.. _cert_command: ############ Cert Command ############ The ``nvflare cert`` command family manages certificate material for distributed provisioning. It is used by both requesters and the Project Admin. The public subcommands are: .. code-block:: none usage: nvflare cert [-h] {init,request,approve} ... positional arguments: {init,request,approve} init Initialize root CA for a distributed provisioning federation (Project Admin only). request Create a distributed provisioning request zip. approve Approve a distributed provisioning request zip. ********************** Initialize the Root CA ********************** The Project Admin first creates a **project profile** file. This file can be stored anywhere on the Project Admin's machine — there is no required location. The path is passed explicitly to every ``cert init`` and ``cert approve`` command; NVFlare never searches for it automatically. .. code-block:: yaml name: hospital_federation scheme: grpc connection_security: tls server: host: server1.hospital-central.org fed_learn_port: 8002 admin_port: 8003 # optional; defaults to fed_learn_port if omitted The profile captures three things the Project Admin owns: - **name**: the project name; every participant definition must use this exact string. - **scheme** and **connection_security**: transport settings (``grpc`` / ``tls`` are the defaults). - **server**: the server endpoint that clients and users will connect to. ``cert approve`` reads this and embeds it in every signed zip so requesters do not have to supply it themselves. The Project Admin then runs ``cert init`` once per federation: .. code-block:: shell nvflare cert init --profile project_profile.yaml -o ./ca --deploy-version 00 This creates: - ``./ca/rootCA.pem``: root CA certificate - ``./ca/rootCA.key``: root CA private key; keep this secret - ``./ca/ca.json``: internal CA metadata generated by ``nvflare cert init``; stores the project name, deploy version, and root CA fingerprint used by ``nvflare cert approve``. Do not edit manually. Common ``init`` options: - ``--profile``: path to the project profile yaml file. Required. The file is read directly from this path — no automatic file discovery occurs. ``cert init`` reads only the ``name`` field; ``cert approve`` uses the full profile later. - ``--deploy-version``: deployment generation recorded in ``ca.json`` and signed into approved zips. Default: ``00``. Normally ignore this option. ``00`` maps to ``prod_00``; use ``01``, ``02``, etc. only when intentionally creating a new deployment CA/generation. - ``--org``: optional organization name for the root CA certificate's O field. - ``-o, --output-dir``: CA output directory. Required. - ``--valid-days``: root CA validity in days. Default: ``3650``. - ``--force``: replace existing CA files after backing them up only when using a new deploy version. Reusing an existing deploy version with a new root CA is rejected so startup kits from different CAs are not mixed in the same ``prod_`` directory, for example ``00`` maps to ``prod_00``. - ``--schema``: print JSON schema for this command. ******************** Create a Request Zip ******************** The requester runs ``cert request`` on the machine that should own the private key. The command reads one participant definition file, creates a private key, CSR, metadata, and request zip. Client site request: .. code-block:: shell nvflare cert request --participant hospital-a.yaml Server request: .. code-block:: shell nvflare cert request --participant server.yaml User request: .. code-block:: shell nvflare cert request --participant alice.yaml A participant definition uses the same top-level shape as a centralized ``project.yaml``: a ``name`` field for the project and a ``participants`` list. For distributed provisioning the ``participants`` list must contain **exactly one entry** — one file, one identity, one request. The key is plural to stay consistent with the centralized format, but ``cert request`` will reject the file if the list has zero or more than one entry. **Participant definition formats:** *Server* — includes the server's own listen ports: .. code-block:: yaml name: hospital_federation participants: - name: server.example.com type: server org: nvidia fed_learn_port: 8002 admin_port: 8003 # optional; defaults to fed_learn_port if omitted .. note:: ``fed_learn_port`` and ``admin_port`` are the ports this server *listens on* locally. ``admin_port`` is optional and defaults to ``fed_learn_port`` when omitted. ``nvflare cert approve`` verifies that the ``name`` field in the request zip matches the project name in ``ca.json`` and ``project_profile.yaml``. Requests with a mismatched project name are rejected. *Client* — only name, type, and org are required: .. code-block:: yaml name: hospital_federation participants: - name: hospital-a type: client org: hospital_alpha *User (FL admin)* — ``type: admin`` identifies an FL admin user (org_admin, lead, or member), not the Project Admin who manages the CA. Add ``role``: .. code-block:: yaml name: hospital_federation participants: - name: alice@hospital.org type: admin org: hospital_alpha role: lead To request a second participant such as ``hospital-b``, create a separate ``hospital-b.yaml`` file with its own single entry and run ``cert request`` again. Each participant has its own private key and request zip. .. note:: **What the requester needs from the Project Admin (out-of-band):** - **Project name** (``name:``): every participant definition must use the exact project name from the Project Admin's ``project_profile.yaml``. Client and user definitions do not include a server endpoint. The Project Admin embeds the approved server host, ports, scheme, and connection security from ``project_profile.yaml`` into every signed zip during ``cert approve``. Requesters receive this information inside the signed zip, not by writing it into their own participant definition file. By default, ``cert request`` writes to ``.//``. For ``hospital-a``: .. code-block:: text hospital-a/ hospital-a.key hospital-a.csr site.yaml request.json hospital-a.request.zip All files in this directory are generated automatically by ``cert request``. Do not edit them manually. ``request.json`` records request metadata that ``nvflare package`` uses later to validate the signed zip. Send only ``hospital-a.request.zip`` to the Project Admin. The private key remains local and is not included in the zip. Common ``request`` options: - ``-p, --participant``: participant definition file. Required. - ``--out``: request folder. Default: ``./``. - ``--force``: overwrite existing request files. - ``--schema``: print JSON schema for this command. ********************* Approve a Request Zip ********************* The Project Admin runs ``cert approve`` with the project CA and project profile: .. code-block:: shell nvflare cert approve hospital-a/hospital-a.request.zip --ca-dir ./ca --profile project_profile.yaml This validates the request zip, verifies that the request project matches the CA and project profile, signs the CSR, injects the Project Admin-approved server endpoint from ``project_profile.yaml``, signs CA metadata into ``signed.json``, and creates: .. code-block:: text hospital-a/hospital-a.signed.zip signed.json signed.json.sig site.yaml hospital-a.crt rootCA.pem Return the signed zip to the requester. ``signed.json.sig`` is a Project Admin CA signature over ``signed.json``. ``nvflare package`` verifies this signature before trusting the approved server endpoint, scheme, connection security fields, and ``ca_info``. ``ca_info`` contains signed CA metadata used by ``nvflare package``. The signed zip already includes ``rootCA.pem``. The requester does not need to receive or place a separate ``rootCA.pem`` file before running ``nvflare package``. The command output includes ``rootca_fingerprint_sha256``. Share only that fingerprint value with the requester through a trusted out-of-band channel so they can verify the signed zip root CA during ``nvflare package``. Use ``--out`` to choose the signed zip location: .. code-block:: shell nvflare cert approve hospital-a/hospital-a.request.zip \ --ca-dir ./ca \ --profile project_profile.yaml \ --out ./signed/hospital-a.signed.zip Common ``approve`` options: - ``request_zip``: request zip produced by ``nvflare cert request``. Required. - ``-c, --ca-dir``: directory containing ``rootCA.pem``, ``rootCA.key``, and ``ca.json``. Required. - ``--profile``: Project Admin's ``project_profile.yaml`` containing ``name``, ``scheme``, ``connection_security``, and the ``server`` endpoint. Required. - ``--out``: signed zip output path. Default: ``.signed.zip`` next to the request zip. - ``--valid-days``: participant certificate validity in days. Default: ``1095``. - ``--force``: overwrite existing signed zip. - ``--schema``: print JSON schema for this command. **************** End-to-End Flow **************** Requester: .. code-block:: shell nvflare cert request --participant hospital-a.yaml Project Admin: .. code-block:: shell nvflare cert init --profile project_profile.yaml -o ./ca --deploy-version 00 nvflare cert approve hospital-a/hospital-a.request.zip --ca-dir ./ca --profile project_profile.yaml Requester: .. code-block:: shell nvflare package hospital-a/hospital-a.signed.zip --fingerprint For the full workflow, including participant definition examples and artifact layout, see :ref:`distributed_provisioning`. .. note:: **Compatibility:** Request zips produced before this release do not contain a ``site_yaml_sha256`` integrity field and will be rejected by ``nvflare cert approve``. Regenerate the request zip with ``nvflare cert request`` before running approve.