Skip to content

apomesh-pki

The PKI plane — apomesh’s native, org-grade certificate authority. A deployment gains an org-grain trust domain with its own issuing CA that mints short-lived leaf certificates carrying SPIFFE-style identity URIs, and exports/parses trust bundles so two deployments can federate over mutual TLS. It backs three surfaces: the dev-stack’s gRPC mTLS material, the A2A mutual-TLS federation plane, and edge-worker bootstrap enrollment.

Design lineage: SPIFFE/SPIRE, implemented natively — trust domain = org, spiffe://<domain>/node/<id> and .../tenant/<id> SAN URIs = the node and tenant grains, short-lived leaves, trust bundles for cross-domain federation. The existing SubjectAltNameUri mTLS extraction consumes these URIs unchanged.

  • Layer: a leaf crate beside the substrate — it owns cert minting, which the substrate deliberately does not. rcgen is a production dependency of this crate only (“operators bring their own” no longer holds — the platform can mint).
  • Depends on: no apomesh crates (rcgen, x509-parser, rustls, time). A true leaf.
  • Consumed by: apomesh-a2a-client (the outbound peer trust anchors), apomesh-orchestrator (live mutual_tls admission mints per-tenant client identities; worker enrollment mints node certs), the orchestrator binary (loads the org CA, serves the federation listener), and the dev-stack minting bin.
  • Identity vocabulary (identity): TrustDomain (a validated, DNS-name-shaped org identifier) and IdentityUri — build and parse the two grains (IdentityUri::node, IdentityUri::tenant) with typed IdentityError. The rendered URI is exactly what the substrate’s SubjectAltNameUri{prefix} mTLS rule strips to an id.
  • The org CA (ca): CaAuthoritygenerate a self-signed org CA for a trust domain, from_pem to import a BYO CA, persist/load a config-pointed identity directory (the key written 0600), and ca_cert_pem to export the public cert. The signing key never renders in Debug.
  • Leaf issuance (issue): org-CA-signed leaves for the server, node-client, and tenant-client shapes, with a configurable Validity (short-lived by default — Validity::short_lived); IssuedIdentity exposes the public cert PEM and, through the single audited expose_key_pem, the private key.
  • Trust bundles + rotation (bundle, issue): TrustBundlefrom_authority exports the org’s public CA material, from_pem/root_store parses a peer’s bundle into a rustls::RootCertStore fail-closed: any non-certificate section rejects the whole bundle, and a certificate that is not a usable CA is InvalidAnchor — no basic-constraints extension, or cA: false, is refused, because absence is not an assertion and the fail-closed reading of “is this a CA?” is no. Without that check an ordinary end-entity leaf pasted into a peer’s trust anchors is accepted as a root; needs_renewal + reissue (fresh-key rotation, since identity pins to the SAN URI + CA chain, never the key).
  • Dev-stack minting (devstack): mint_dev_stack composes the above into the exact CA + server + worker cert set the local stack’s [auth.tls] config reads — the apomesh-pki mint-dev-stack bin that retired deploy/local/certs/generate.sh.
  • Build: Agent2Agent (A2A) — configuring mutual-TLS peers and the federation listener.
  • Concepts: Agent federation — how mutual-TLS trust composes with the delegation and inbound planes.
  • Reference: apomesh-a2a-client — the outbound client that pins peer trust anchors from a TrustBundle.