Skip to navigation

Signing Keys and Trust Roots

View as Markdown

An APF deployment uses several keys, each with one job. Confusing them is the most common configuration mistake, so this page lists every one.

Key Inventory

KeyPurposePrivate half held byPublic half or verifierFormat
Bundle signing keySigns bundle manifests.The signing authority, offline.Trust roots in each policy service’s --trust-root-dir.Ed25519 seed for apf-compile, or a P-256 key in a signing service. Public keys as .pub, .pem, or .p256.
Document signing keySigns a provenance token on every document the policy service serves over gRPC.The policy service, from --document-signing-key.The policy service’s /.well-known/jwks.json, read by the gateway.Ed25519 seed. Its key ID is --document-key-id.
OpenShell extension signing keySigns the JWTs OpenShell sends to APF’s listeners.The OpenShell gateway.The public_key_pem in each APF trust profile.Ed25519.
Listener TLS keysIdentify APF’s interceptor and middleware listeners to OpenShell.The policy gateway, from the TLS key files.The CA in OpenShell’s tls_ca_cert_path.PEM certificate chain and private key.
HTTP bearer tokenGates the policy service’s document and refresh routes.The policy service and authorized callers.Compared in constant time.Opaque string.
Bundle source tokenAuthenticates the policy service to the artifact store.The policy service.The artifact store.Opaque string.

The repository’s examples/dev-keys/apf-dev.seed is a committed private key. Development setups use it as both the bundle signing key and the document signing key. It has no security value. Do not install apf-dev.pub as a trust root on any host that governs real agents.

Custody

  • Bundle signing keys never touch an APF host. A host that holds a bundle signing key can sign policy for every host that trusts it.
  • Host secrets are root-owned and delivered as systemd credentials. The shipped units load the document signing key, the TLS keys, and optionally the HTTP token with LoadCredential, so the apf account reads per-service copies under $CREDENTIALS_DIRECTORY and has no path to the originals in /etc/apf.
  • Generated key files are not locked down for you. apf-policy-service keygen and apf-compile genfixture --generate-key write key files with the process umask. Run chmod 0600 on each seed as soon as it is written.
  • Each key has one job. Do not reuse the bundle signing key as the document signing key, or one trust profile for both listeners.

Separation of Duties

PartyCanCannot
Policy authorsPropose policy changes for review.Sign bundles, unless they also hold the signing authority’s key.
Signing authoritySign bundles.Change what a host trusts.
Host administratorsInstall trust roots and configuration.Produce a bundle a host accepts without a trusted key.
APF servicesVerify, serve, and enforce.Author or modify a bundle.

Whoever both holds a bundle signing key and can merge policy changes is, in effect, the policy authority. Keep those roles apart where you can, and enforce review in your source control.

Rotation

KeyProcedure
Bundle signing keyInstall the new public key next to the old one on every host and restart. Sign the next bundle with the new key and a higher revision. Remove the old public key and restart once every host runs the new bundle.
Document signing keyReplace the seed and restart the policy service. The gateway re-fetches the JWKS every 60 seconds by default, and provenance verification fails until it has the new key. The JWKS publishes only the current key, so sandboxes admitted earlier keep tokens that only the old public key verifies. Keep the old public key for investigations.
OpenShell extension signing keyFollow OpenShell’s rotation procedure, update kid and public_key_pem in both APF trust profiles, and restart the gateway.
Listener TLS keysReplace the certificate and key files and restart the gateway. Update OpenShell’s CA if the issuer changed.
TokensReplace the token file and restart the service. Update every caller.

If a Key Is Compromised

KeyResponse
Bundle signing keySign a replacement bundle with a new key at a higher revision. On each host, put the replacement where the policy service loads it at startup, install the new key’s trust root, and remove the compromised one, then restart the policy service. Do not remove the trust root while the bundle the service loads at startup is still signed by that key: the service would refuse it and not start. APF has no revocation list, so until a host restarts with the compromised trust root removed, it still accepts bundles signed by that key.
Document signing keyReplace it and restart the policy service. An attacker with it could mint provenance tokens the interceptor accepts.
OpenShell extension signing keyRotate it in OpenShell and update the trust profiles. An attacker with it could call APF’s listeners as OpenShell.
Listener TLS keyReplace the key and certificate, and revoke the certificate with its issuer.

Next Steps