Skip to content

Commit 83d860f

Browse files
docs: add section on mtls (#2849)
Co-authored-by: PProfizi <[email protected]> Co-authored-by: Paul Profizi <[email protected]>
1 parent e2a20e3 commit 83d860f

File tree

5 files changed

+192
-51
lines changed

5 files changed

+192
-51
lines changed

doc/source/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@
217217
html_theme = "ansys_sphinx_theme"
218218
html_favicon = ansys_favicon
219219
html_theme_options = {
220+
"announcement": """Starting with PyDPF-Core 0.15.0, gRPC communication with the DPF server defaults to requiring authentication.
221+
Refer to <a href='https://dpf.docs.pyansys.com/version/dev/getting_started/dpf_server.html#run-dpf-server-in-secure-mode-with-mtls'>this page</a> for more information.""",
220222
"logo": {
221223
"image_dark": pyansys_logo_dark_mode,
222224
"image_light": pyansys_logo_light_mode,

doc/source/getting_started/dpf_server.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,39 @@ DPF Server can be run in a Docker container.
120120
docker build . -t dpf-core:v2025.1.pre0 --build-arg DPF_VERSION=251
121121
122122
5. To run the DPF Docker container, license it. For more information, see :ref:`DPF Preview License Agreement<target_to_license_terms>`.
123+
124+
.. _ref_dpf_server_secure_mode:
125+
126+
Run DPF Server in Secure mode wih mTLS
127+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128+
129+
.. warning::
130+
131+
Starting with Ansys 2026 R1 (DPF 2026.1.0, kernel version 11.0) and PyDPF-Core 0.15.0,
132+
DPF Server gRPC connections default to using `authenticated mTLS Transport<https://tools.docs.pyansys.com/version/stable/user_guide/secure_grpc.html>`.
133+
134+
This change is also brought by service packs for the following older Ansys versions:
135+
136+
- `Ansys 2025 R2 SP03`
137+
- `Ansys 2025 R1 SP04`
138+
- `Ansys 2024 R2 SP05`
139+
140+
141+
.. note::
142+
143+
The default client-server communication mode being InProcess,
144+
this change only impacts users connecting to a remote DPF Server over gRPC.
145+
146+
147+
Both client and server now require mTLS certificates to establish a gRPC connection.
148+
149+
The location to the mTLS certificates can be set using an environment variable ``ANSYS_GRPC_CERTIFICATES``.
150+
151+
More information on the generation of certificates can be read on `Generating certificates for mtls<https://tools.docs.pyansys.com/version/stable/user_guide/secure_grpc.html#generating-certificates-for-mtls>`.
152+
153+
This environment variable must be set both on the server machine and on the client machine when working remotely.
154+
155+
The mTLS Transport mode can be disabled by setting ``DPF_DEFAULT_GRPC_MODE`` to ``insecure`` both client-side and server-side.
156+
157+
This allows to fall back to the previous behavior when using gRPC communication.
158+

src/ansys/dpf/core/server.py

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import functools
3333
import inspect
3434
import os
35+
from pathlib import Path
3536
import platform
3637
import socket
3738
import sys
@@ -43,8 +44,10 @@
4344
from ansys import dpf
4445
from ansys.dpf.core import errors, server_context
4546
from ansys.dpf.core.misc import get_ansys_path, is_ubuntu
47+
from ansys.dpf.core.server_context import ServerContext
4648
from ansys.dpf.core.server_factory import (
4749
CommunicationProtocols,
50+
DockerConfig,
4851
GrpcMode,
4952
ServerConfig,
5053
ServerFactory,
@@ -158,63 +161,76 @@ def shutdown_all_session_servers():
158161

159162

160163
def start_local_server(
161-
ip=LOCALHOST,
162-
port=DPF_DEFAULT_PORT,
163-
ansys_path=None,
164-
as_global=True,
165-
load_operators=True,
166-
use_docker_by_default=True,
167-
docker_config=RUNNING_DOCKER,
168-
timeout=20.0,
169-
config=None,
170-
use_pypim_by_default=True,
171-
context=None,
164+
ip: str = LOCALHOST,
165+
port: int = DPF_DEFAULT_PORT,
166+
ansys_path: Path | str = None,
167+
as_global: bool = True,
168+
load_operators: bool = True,
169+
use_docker_by_default: bool = True,
170+
docker_config: DockerConfig = RUNNING_DOCKER,
171+
timeout: float = 20.0,
172+
config: ServerConfig = None,
173+
use_pypim_by_default: bool = True,
174+
context: ServerContext = None,
172175
) -> AnyServerType:
173176
"""Start a new local DPF server at a given port and IP address.
174177
175178
This method requires Windows and ANSYS 2021 R1 or later. If ``as_global=True``, which is
176179
the default) the server is stored globally, replacing the one stored previously.
177180
Otherwise, a user must keep a handle on their server.
178181
182+
.. warning::
183+
Starting with DPF 2026 R1 and PyDPF 0.15.0, the default gRPC server uses mTLS authentication.
184+
Please refer to :ref:`ref_dpf_server_secure_mode` for more information on how to set up the
185+
certificates and configure the server and client accordingly.
186+
See the ``config`` parameter for more details.
187+
179188
Parameters
180189
----------
181-
ip : str, optional
190+
ip:
182191
IP address of the remote or local instance to connect to. The
183192
default is ``"LOCALHOST"``.
184-
port : int, optional
193+
port:
185194
Port to connect to the remote instance on. The default is
186195
``"DPF_DEFAULT_PORT"``, which is 50054.
187-
ansys_path : str or os.PathLike, optional
196+
ansys_path:
188197
Root path for the Ansys installation directory. For example, ``"/ansys_inc/v212/"``.
189198
The default is the latest Ansys installation.
190-
as_global : bool, optional
199+
as_global:
191200
Global variable that stores the IP address and port for the DPF
192201
module. All DPF objects created in this Python session will
193202
use this IP and port. The default is ``True``.
194-
load_operators : bool, optional
203+
load_operators:
195204
Whether to automatically load the math operators. The default is ``True``.
196-
use_docker_by_default : bool, optional
205+
use_docker_by_default:
197206
If the environment variable DPF_DOCKER is set to a docker name and use_docker_by_default
198207
is True, the server is ran as a docker (default is True).
199-
docker_config : server_factory.DockerConfig, optional
208+
docker_config:
200209
To start DPF server as a docker, specify the docker configuration options here.
201-
timeout : float, optional
210+
timeout:
202211
Maximum number of seconds for the initialization attempt.
203212
The default is ``10``. Once the specified number of seconds
204213
passes, the connection fails.
205-
config: ServerConfig, optional
206-
Manages the type of server connection to use.
207-
use_pypim_by_default: bool, optional
214+
config:
215+
Manages the type of server connection to use. Forced to LegacyGrpc on macOS.
216+
Defaults to mTLS authenticated gRPC connection.
217+
Define the path to the mTLS authentication certificates here if needed.
218+
Define the default server authentication configuration with environment variables:
219+
- ANSYS_GRPC_CERTIFICATES: path to the certificates directory
220+
- DPF_GRPC_MODE: gRPC authentication mode, options are 'mtls' and 'insecure'.
221+
More information available at :ref:`ref_dpf_server_secure_mode`.
222+
use_pypim_by_default:
208223
Whether to use PyPIM functionalities by default when a PyPIM environment is detected.
209224
Defaults to True.
210-
context: ServerContext, optional
225+
context:
211226
Defines the settings that will be used to load DPF's plugins.
212227
A DPF xml file can be used to list the plugins and set up variables. Default is
213228
`server_context.SERVER_CONTEXT`.
214229
215230
Returns
216231
-------
217-
server : server.ServerBase
232+
server:
233+
The newly created server.
218234
"""
219235
from ansys.dpf.core.misc import is_pypim_configured
220236

@@ -266,6 +282,8 @@ def start_local_server(
266282
if config is not None:
267283
grpc_mode = config.grpc_mode
268284
certs_dir = config.certificates_dir
285+
else:
286+
config = ServerConfig()
269287
server = server_type(
270288
ansys_path,
271289
ip,
@@ -315,37 +333,49 @@ def start_local_server(
315333

316334

317335
def connect_to_server(
318-
ip=LOCALHOST,
319-
port=DPF_DEFAULT_PORT,
320-
as_global=True,
321-
timeout=10.0,
322-
config=None,
323-
context=None,
336+
ip: str = LOCALHOST,
337+
port: int = DPF_DEFAULT_PORT,
338+
as_global: bool = True,
339+
timeout: float = 10.0,
340+
config: ServerConfig = None,
341+
context: ServerContext = None,
324342
):
325343
"""Connect to an existing DPF server.
326344
327345
This method sets the global default channel that is then used for the
328346
duration of the DPF session.
329347
348+
.. warning::
349+
Starting with DPF 2026 R1 and PyDPF 0.15.0, the default gRPC server uses mTLS authentication.
350+
Please refer to :ref:`ref_dpf_server_secure_mode` for more information on how to set up the
351+
certificates and configure the server and client accordingly.
352+
See the ``config`` parameter for more details.
353+
330354
Parameters
331355
----------
332-
ip : str
356+
ip:
333357
IP address of the remote or local instance to connect to. The
334358
default is ``"LOCALHOST"``.
335-
port : int
359+
port:
336360
Port to connect to the remote instance on. The default is
337361
``"DPF_DEFAULT_PORT"``, which is 50054.
338-
as_global : bool, optional
362+
as_global:
339363
Global variable that stores the IP address and port for the DPF
340364
module. All DPF objects created in this Python session will
341365
use this IP and port. The default is ``True``.
342-
timeout : float, optional
366+
timeout:
343367
Maximum number of seconds for the initialization attempt.
344368
The default is ``10``. Once the specified number of seconds
345369
passes, the connection fails.
346-
config: ServerConfig, optional
370+
config:
347371
Manages the type of server connection to use. Forced to LegacyGrpc on macOS.
348-
context: ServerContext, optional
372+
Defaults to mTLS authenticated gRPC connection.
373+
Define the path to the mTLS authentication certificates here if needed.
374+
Define the default server authentication configuration with environment variables:
375+
- ANSYS_GRPC_CERTIFICATES: path to the certificates directory
376+
- DPF_GRPC_MODE: gRPC authentication mode, options are 'mtls' and 'insecure'.
377+
More information available at :ref:`ref_dpf_server_secure_mode`.
378+
context:
349379
Defines the settings that will be used to load DPF's plugins.
350380
A DPF xml file can be used to list the plugins and set up variables. Default is
351381
`server_context.SERVER_CONTEXT`.

src/ansys/dpf/core/server_factory.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class GrpcMode:
6666
DEFAULT_COMMUNICATION_PROTOCOL = CommunicationProtocols.InProcess
6767
DEFAULT_LEGACY = False
6868
DEFAULT_GRPC_MODE = GrpcMode.mTLS
69+
DEFAULT_CERTIFICATES_DIR = None
6970

7071

7172
class DockerConfig:
@@ -265,18 +266,33 @@ def find_port_available_for_docker_bind(port: int) -> int:
265266
class ServerConfig:
266267
"""Provides an instance of ServerConfig object to manage the server type used.
267268
269+
.. warning::
270+
Starting with DPF 2026 R1 and PyDPF 0.15.0, the default gRPC server uses mTLS authentication.
271+
Please refer to :ref:`ref_dpf_server_secure_mode` for more information on how to set up the
272+
certificates and configure the server and client accordingly.
273+
See the ``config`` parameter for more details.
274+
268275
The default parameters can be overwritten using the DPF_SERVER_TYPE environment
269276
variable. DPF_SERVER_TYPE=INPROCESS, DPF_SERVER_TYPE=GRPC,
270277
DPF_SERVER_TYPE=LEGACYGRPC can be used.
271278
272279
Parameters
273280
----------
274-
protocol : CommunicationProtocols, optional
281+
protocol:
275282
Communication protocol for DPF server (e.g. InProcess, gRPC)
276-
legacy : bool, optional
283+
legacy:
277284
If legacy is set to True, the server will be using ansys-grpc-dpf
278285
Python module. If not, it will communicate with DPF binaries using ctypes
279286
and DPF CLayer calls.
287+
grpc_mode:
288+
Grpc mode to use when launching DPF server.
289+
Can be one of the members of :class:`ansys.dpf.core.server_factory.GrpcMode`.
290+
Defaults to mTLS authenticated mode.
291+
More information available at :ref:`ref_dpf_server_secure_mode`.
292+
certificates_dir:
293+
Path to a directory containing the certificates to use for mTLS authentication.
294+
More information available at :ref:`ref_dpf_server_secure_mode`.
295+
280296
281297
Examples
282298
--------
@@ -307,7 +323,7 @@ def __init__(
307323
protocol: str = DEFAULT_COMMUNICATION_PROTOCOL,
308324
legacy: bool = DEFAULT_LEGACY,
309325
grpc_mode: str = DEFAULT_GRPC_MODE,
310-
certificates_dir: Path = None,
326+
certificates_dir: Path = DEFAULT_CERTIFICATES_DIR,
311327
):
312328
self.legacy = legacy
313329
if not protocol:
@@ -319,7 +335,11 @@ def __init__(
319335
self.grpc_mode = DEFAULT_GRPC_MODE
320336
else:
321337
self.grpc_mode = grpc_mode
322-
self.certificates_dir = certificates_dir
338+
self.certificates_dir = (
339+
certificates_dir
340+
if certificates_dir
341+
else os.environ.get("ANSYS_GRPC_CERTIFICATES", None)
342+
)
323343

324344
def __str__(self):
325345
"""Return a string representation of the ServerConfig instance.

0 commit comments

Comments
 (0)