Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterize PKI certs location #667

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from
34 changes: 34 additions & 0 deletions .github/workflows/pki-certs-location.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Test PKI certs location

on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]

permissions:
contents: read

jobs:
build:
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .
- name: Test PKI certs location
run: |
python -m tests.github.test_pki_cert_location --agg-cert-path ~/.openfl/agg --agg-key-path ~/.openfl/agg --col1-cert-path ~/.openfl/col1/ --col1-key-path ~/.openfl/col1 --col2-cert-path ~/.openfl/col2 --col2-key-path ~/.openfl/col2/
3 changes: 2 additions & 1 deletion .github/workflows/pki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ jobs:
pip install .
- name: Test PKI
run: |
python tests/github/pki_wrong_cn.py
python tests/github/pki_wrong_cn.py

116 changes: 97 additions & 19 deletions docs/running_the_federation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ However, continue with the following procedure for details in creating a federat

- Ensures each node in the federation has a valid public key infrastructure (PKI) certificate.
- Distributes the workspace from the aggregator node to the other collaborator nodes.
- Optionally, select a subset of registered/certified collaborators to participate in the federation. By default, all certified collaborators will be added.


`STEP 3: Start the Federation`_
Expand Down Expand Up @@ -952,12 +953,27 @@ Setting Up the Certificate Authority

fx workspace certify

By default, all certificates are stored under :code:`WORKSPACE_PATH/cert` folder inside workspace. To store certificates elsewhere:

.. code-block:: console

fx workspace certify -c CERT_PATH -k KEY_PATH -cdir CERT_DIR

where :code:`CERT_PATH` is the path where the CA signing certificate and the certificate chain will be stored for this node,
:code:`KEY_PATH` is where the CA signing key path will be stored and :code:`CERT_DIR` is the directory where rest of CA certificates (e.g. root CA cert and key) will reside.

3. Run the aggregator certificate creation command, replacing :code:`AFQDN` with the actual `fully qualified domain name (FQDN) <https://en.wikipedia.org/wiki/Fully_qualified_domain_name>`_ for the aggregator node.

.. code-block:: console

fx aggregator generate-cert-request --fqdn AFQDN

To store certificate under :code:`CERT_PATH` and key under :code:`KEY_PATH`:

.. code-block:: console

fx aggregator generate-cert-request --fqdn AFQDN -c CERT_PATH -k KEY_PATH

.. note::

On Linux\*\, you can discover the FQDN with this command:
Expand Down Expand Up @@ -986,6 +1002,11 @@ Setting Up the Certificate Authority

fx aggregator certify --fqdn AFQDN

If :code:`CERT_PATH` and :code:`KEY_PATH` was used to store CA signing certificate and signing key respectively, specify the same path here:

.. code-block:: console

fx aggregator certify --fqdn AFQDN -c CERT_PATH -k KEY_PATH

.. note::

Expand All @@ -997,15 +1018,15 @@ Setting Up the Certificate Authority

5. This node now has a signed security certificate as the aggregator for this new federation. You should have the following files.

+---------------------------+--------------------------------------------------+
| File Type | Filename |
+===========================+==================================================+
| Certificate chain | WORKSPACE.PATH/cert/cert_chain.crt |
+---------------------------+--------------------------------------------------+
| Aggregator certificate | WORKSPACE.PATH/cert/server/agg_{AFQDN}.crt |
+---------------------------+--------------------------------------------------+
| Aggregator key | WORKSPACE.PATH/cert/server/agg_{AFQDN}.key |
+---------------------------+--------------------------------------------------+
+---------------------------+-----------------------------------------------------------------------------+
| File Type | Filename |
+===========================+=============================================================================+
| Certificate chain | WORKSPACE.PATH/cert/cert_chain.crt or CERT.PATH/cert_chain.crt |
+---------------------------+-----------------------------------------------------------------------------+
| Aggregator certificate | WORKSPACE.PATH/cert/server/agg_{AFQDN}.crt or CERT.PATH/agg_{AFQDN}.crt |
+---------------------------+-----------------------------------------------------------------------------+
| Aggregator key | WORKSPACE.PATH/cert/server/agg_{AFQDN}.key or KEY.PATH/agg_{AFQDN}.key |
+---------------------------+-----------------------------------------------------------------------------+

where **AFQDN** is the fully-qualified domain name of the aggregator node.

Expand Down Expand Up @@ -1049,21 +1070,27 @@ Importing the Workspace

fx collaborator generate-cert-request -n {COL_LABEL}

To store certs under :code:`CERT_PATH_COL/` and key under :code:`KEY_PATH_COL/` other than :code:`WORKSPACE_PATH/cert`:

.. code-block:: console

fx collaborator generate-cert-request -n {COL_LABEL} -c {CERT_PATH_COL} -k {KEY_PATH_COL}

where **CERT_PATH_COL** is the path where collaborator certificates (client) will be stored and **KEY_PATH_COL** is where the collaborator key is stored.

The creation script will also ask you to specify the path to the data. For this example, enter the integer that represents which MNIST shard to use on this collaborator node. For the first collaborator node enter **1**. For the second collaborator node enter **2**.

This will create the following files:

+-----------------------------+--------------------------------------------------------+
| File Type | Filename |
+=============================+========================================================+
| Collaborator CSR | WORKSPACE.PATH/cert/client/col_{COL_LABEL}.csr |
+-----------------------------+--------------------------------------------------------+
| Collaborator key | WORKSPACE.PATH/cert/client/col_{COL_LABEL}.key |
+-----------------------------+--------------------------------------------------------+
| Collaborator CSR Package | WORKSPACE.PATH/col_{COL_LABEL}_to_agg_cert_request.zip |
+-----------------------------+--------------------------------------------------------+

+-----------------------------+-------------------------------------------------------------------------------------+
| File Type | Filename |
+=============================+=====================================================================================+
| Collaborator CSR | WORKSPACE.PATH/cert/client/col_{COL_LABEL}.csr or CERT.PATH.COL/col_{COL_LABEL}.csr |
+-----------------------------+-------------------------------------------------------------------------------------+
| Collaborator key | WORKSPACE.PATH/cert/client/col_{COL_LABEL}.key or KEY.PATH.COL/col_{COL_LABEL}.key |
+-----------------------------+-------------------------------------------------------------------------------------+
| Collaborator CSR Package | WORKSPACE.PATH/col_{COL_LABEL}_to_agg_cert_request.zip |
+-----------------------------+-------------------------------------------------------------------------------------+

4. On the aggregator node (i.e., the certificate authority in this example), sign the Collaborator CSR Package from the collaborator nodes.

Expand All @@ -1073,6 +1100,12 @@ Importing the Workspace

where :code:`/PATH/TO/col_{COL_LABEL}_to_agg_cert_request.zip` is the path to the Collaborator CSR Package containing the :code:`.csr` file from the collaborator node. The certificate authority will sign this certificate for use in the federation.

If :code:`CERT_PATH` and :code:`KEY_PATH` was used at the aggregator node to store CA signing certificate and signing key, specify the same path here:

.. code-block:: console

fx collaborator certify --request-pkg /PATH/TO/col_{COL_LABEL}_to_agg_cert_request.zip -n collaborator_name -c CERT_PATH -k KEY_PATH

The command packages the signed collaborator certificate, along with the **cert_chain.crt** file needed to verify certificate signatures, for transport back to the collaborator node:

+---------------------------------+------------------------------------------------------------+
Expand All @@ -1087,7 +1120,33 @@ Importing the Workspace

fx collaborator certify --import /PATH/TO/agg_to_col_{COL_LABEL}_signed_cert.zip

If :code:`CERT_PATH_COL` and :code:`KEY_PATH_COL` was used to store collaborator certificate and key for this node, specify the paths here:

.. code-block:: console

fx collaborator certify --import /PATH/TO/agg_to_col_{COL_LABEL}_signed_cert.zip -c CERT_PATH_COL -k KEY_PATH_COL

.. _select_participants:

**On the Aggregator Node:**

OPTIONAL STEP: Users can select participants to take part in a federation. By default, all the participants (Collaborators) certified by the CA are added to the plan :code:`plan/cols.yaml` file. To select only a subset of participants out of the displayed names of all certified collaborators for the current federation:

.. code-block:: console

fx workspace participants

If :code:`CERT_PATH` was used at the aggregator node to store CA signing certificate, specify the same path here:

.. code-block:: console

fx workspace participants -c CERT_PATH

If users want to add uncertified participants, or manually want to edit the collaborator names for the experiment:

.. code-block:: console

fx workspace participants --no_cert

.. _running_the_federation.start_nodes:

Expand All @@ -1103,6 +1162,12 @@ STEP 3: Start the Federation

fx aggregator start

If :code:`CERT_PATH` and :code:`KEY_PATH` was used to store certificates for this node, specify the same path here:

.. code-block:: console

fx aggregator start -c ${CERT_PATH} -k ${KEY_PATH}

Now, the Aggregator is running and waiting for Collaborators to connect.

.. _running_collaborators:
Expand All @@ -1119,6 +1184,12 @@ STEP 3: Start the Federation

where :code:`COLLABORATOR_LABEL` is the label for this Collaborator.

If :code:`CERT_PATH_COL` and :code:`KEY_PATH_COL` was used to store certificates for this node, specify the same path here:

.. code-block:: console

fx collaborator start -n {COLLABORATOR_LABEL} -c ${CERT_PATH_COL} -k ${KEY_PATH_COL}

.. note::

Each workspace may have multiple FL plans and multiple collaborator lists associated with it.
Expand Down Expand Up @@ -1160,6 +1231,13 @@ Another way to access the trained model is by calling the API command directly f

In fact, the :code:`get_model()` method returns a **TaskRunner** object loaded with the chosen model snapshot. Users may utilize the linked model as a regular Python object.

If :code:`CERT_PATH` was used to store certificates for any node, uninstall them:

.. code-block:: console

fx workspace uninstall-cert -c ${CERT_PATH} -k ${KEY_PATH}
fx aggregator uninstall-cert -c ${CERT_PATH} -k ${KEY_PATH}
fx collaborator uninstall-cert -c ${CERT_PATH_COL} -k ${KEY_PATH_COL}

.. _running_the_federation_docker:

Expand Down
16 changes: 10 additions & 6 deletions openfl/federated/plan/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,11 +498,13 @@ def get_collaborator(self, collaborator_name, root_certificate=None, private_key
def get_client(self, collaborator_name, aggregator_uuid, federation_uuid,
root_certificate=None, private_key=None, certificate=None):
"""Get gRPC client for the specified collaborator."""
from openfl.interface.cli_helper import CERT_DIR

common_name = collaborator_name
if not root_certificate or not private_key or not certificate:
root_certificate = 'cert/cert_chain.crt'
certificate = f'cert/client/col_{common_name}.crt'
private_key = f'cert/client/col_{common_name}.key'
root_certificate = f'{CERT_DIR}/cert_chain.crt'
certificate = f'{CERT_DIR}/client/col_{common_name}.crt'
private_key = f'{CERT_DIR}/client/col_{common_name}.key'

client_args = self.config['network'][SETTINGS]

Expand All @@ -522,12 +524,14 @@ def get_client(self, collaborator_name, aggregator_uuid, federation_uuid,

def get_server(self, root_certificate=None, private_key=None, certificate=None, **kwargs):
"""Get gRPC server of the aggregator instance."""
from openfl.interface.cli_helper import CERT_DIR

common_name = self.config['network'][SETTINGS]['agg_addr'].lower()

if not root_certificate or not private_key or not certificate:
root_certificate = 'cert/cert_chain.crt'
certificate = f'cert/server/agg_{common_name}.crt'
private_key = f'cert/server/agg_{common_name}.key'
root_certificate = f'{CERT_DIR}/cert_chain.crt'
certificate = f'{CERT_DIR}/server/agg_{common_name}.crt'
private_key = f'{CERT_DIR}/server/agg_{common_name}.key'

server_args = self.config['network'][SETTINGS]

Expand Down
Loading