[PKI] Release Atom-native multi-tenant certificates - #79
Conversation
* Add multi-tenant PKI authority schema * Add typed PKI authority domain model * Add PKI authority read repository * Expose PKI authority module * Test tenant PKI authority isolation and rotation * Document Atom-native multi-tenant PKI direction * Keep dynamic authority queries alive across await * Temporarily format PKI foundation in CI * Format PKI foundation * Remove temporary formatting workflow * Harden PKI foundation compatibility and tenant isolation * Add PKI implementation roadmap and delivery contracts * Align PKI tests with resolver-v2 serial cutover * Update PKI plan (#45) Signed-off-by: dusan <borovcanindusan1@gmail.com> * Align authority model with platform leaf issuer plan * Add scope-aware active leaf issuer selector * Enforce PKI hierarchy, scope, and retention invariants * Cover platform leaf issuer and PKI retention invariants * Add temporary PKI formatting helper * Format PKI corrections * Remove temporary PKI formatting helper * Harden PKI authority foundation * Harden PKI authority foundation * Harden PKI authority foundation * Harden PKI authority foundation * Harden PKI authority foundation * Format PKI authority tests --------- Signed-off-by: dusan <borovcanindusan1@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Dušan Borovčanin <dusan.borovcanin@absmach.eu>
Allow Rust and API documentation workflows to validate pull requests targeting the certificates staging branch.
Implements PKI PR-002 with encrypted CA key handling, dedicated KEK validation, secure plaintext zeroization, startup validation, metrics, and regression coverage.
Implements the PR-003 CA provisioning specification with validated offline-root import, tenant/platform issuer lifecycle management, protected key-provider operations, audit/outbox coverage, and dynamic trust-bundle publication.
Implements the complete PR-004 stored profile and PKI core specification with mandatory database and OpenSSL coverage.
* feat(pki): add tenant-aware CSR issuance * test(pki): cover managed CSR issuance * test(pki): query transactional outbox payload * test(pki): enable schema introspection in harness
Implements one-time managed generated-key bootstrap with profile-driven keys, tenant issuer enforcement, zeroizing secret handling, production-off gating, operational documentation, and complete PR-006 coverage.
Implements exact-credential issuer-aware renewal, profile-derived renewal windows, rotation migration, controlled overlap/revocation, idempotency, and the complete PR-007 test matrix.
Implements PR-008 exact issuer-aware revocation, immutable evidence, lifecycle propagation, issuer-only artifact invalidation, and mandatory integration coverage.
Publish issuer-scoped CRLs with monotonic state migration, exact revocation reasons, retained-authority signing, validator caching, and complete interoperability coverage.
* feat(pki): implement per-issuer OCSP * fix(pki): make OCSP nonce encoding explicit * test(pki): encode unsupported OCSP parameters explicitly * test(pki): pass OCSP serial to OpenSSL as hexadecimal * test(pki): verify operational OCSP key policies * test(pki): cover accepted issuer key families
Adds the versioned issuer-aware runtime resolver, lifecycle validation, scoped serial uniqueness, legacy isolation, migration coverage, and resolver contract documentation.
Implements subject-driven first enrollment and certificate-only re-enrollment through a dedicated in-process TLS listener, with durable abuse controls, audit/outbox events, renewal guidance, deployment configuration, documentation, and mandatory integration coverage.
Implement replica-safe expiry events, authorization-filtered fleet queries, resumable bulk revocation, authority expiry visibility, and bounded lifecycle metrics with complete PR-015 mandatory coverage.
* [PKI PR-014b] Implement RFC 7030 EST adapter * ci: re-run checks on final PR-014b tree * fix(pki): audit EST failures and enforce CSR wire limits * fix(pki): audit EST failures and enforce CSR wire limits * fix(pki): audit EST failures and enforce CSR wire limits * style(pki): preserve EST formatting * style(pki): match rustfmt EST spacing * fix(pki): return leaf-only EST enrollment responses * test(pki): compare EST challenge case-insensitively
Add a production PKCS#11 signing backend for managed authorities while retaining encrypted-database compatibility, fail-closed startup validation, bounded provider operations, SoftHSM contract coverage, and tested backup recovery.
* fix(pki): observe authority mutation failures * fix(pki): make authority lifecycle replays explicit * test(pki): cover PR-003 review corrections * style(pki): apply rustfmt to provisioning follow-up * style(pki): apply rustfmt to PR-003 coverage
Validate and land the remaining corrective work for PR-003 through PR-015 as one dependency-ordered, fully green certificates tree.
Document the human and AI release procedure, add a guarded real-integration runner, and make the seven-binary PKI smoke gate execute in the trusted Rust workflow.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
atom-docs | 5347f9d | Commit Preview URL Branch Preview URL |
Aug 12 2026, 09:07 AM |
Preserve main ancestry, resolve the configuration integration, and carry the validated PKI release gates into certificates.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5347f9d390
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| SET status = 'active', issuance_enabled = $2, subject = $3, | ||
| serial_number = $4, fingerprint_sha256 = $5, | ||
| subject_key_id = $6, authority_key_id = $7, | ||
| certificate_pem = $8, chain_pem = $9, not_before = $10, | ||
| not_after = $11, failure_reason = NULL, activated_at = now(), |
There was a problem hiding this comment.
Populate discovery URLs before activating issuers
Every authority activated through the provisioning API leaves ocsp_url, ca_issuers_url, and crl_distribution_point_url null, while PkiIssuer::from_managed_authority rejects an issuer unless all three are present. Consequently, a successfully provisioned tenant or platform issuer cannot issue any managed certificate until an operator performs an undocumented direct SQL update—the test fixtures currently mask this by setting the columns manually. Populate these routes during activation or expose a supported configuration step before setting issuance_enabled.
Useful? React with 👍 / 👎.
| ALTER TABLE certificate_revocations | ||
| ALTER COLUMN expires_at SET NOT NULL, | ||
| DROP CONSTRAINT certificate_revocations_credential_id_fkey; |
There was a problem hiding this comment.
Detach revocation evidence from purged issuers
This migration removes only the credential FK, leaving certificate_revocations.issuer_id with its ON DELETE RESTRICT reference to pki_authorities. After the normal tenant soft-delete path revokes a managed certificate and creates an immutable ledger row, both explicit and background tenant purge attempt to delete that tenant's authority and fail on this retained FK, rolling back the purge. Either retain authorities independently of tenant purges or remove/detach the issuer FK while preserving the fingerprint evidence.
AGENTS.md reference: AGENTS.md:L134-L134
Useful? React with 👍 / 👎.
| ATOM_PKI_LIFECYCLE_BATCH_SIZE: ${ATOM_PKI_LIFECYCLE_BATCH_SIZE:-250} | ||
| ATOM_PKI_EXPIRY_WARNING_SECS: ${ATOM_PKI_EXPIRY_WARNING_SECS:-86400} | ||
| ATOM_PKI_AUTHORITY_WARNING_SECS: ${ATOM_PKI_AUTHORITY_WARNING_SECS:-2592000} | ||
| ATOM_PKI_GENERATED_KEY_ISSUANCE_ENABLED: ${ATOM_PKI_GENERATED_KEY_ISSUANCE_ENABLED:-false} |
There was a problem hiding this comment.
Forward managed-CA provider settings into containers
When either Compose service is used, its explicit environment allowlist forwards the new lifecycle and enrollment settings but omits ATOM_PKI_CA_KEY_ENCRYPTION_KEY, its key ID, the backend selector, and all PKCS#11 settings. Thus values configured in .env per the new PKI documentation never reach Atom: encrypted-database provisioning reports an unconfigured provider, and a restart with an existing managed authority can fail startup validation. Forward the CA provider variables in both atom and atom-dev.
Useful? React with 👍 / 👎.
Three release-blocking issues found while reviewing the PKI release PR: - Managed leaf issuers activated through the provisioning API were left with NULL ocsp_url, ca_issuers_url, and crl_distribution_point_url, so PkiIssuer::from_managed_authority rejected every subsequent leaf issuance. Test fixtures masked this by patching the columns via direct SQL. Populate the three columns at activation from a new optional PkiCaKeyConfig.artifact_base_url, sourced from ATOM_PUBLIC_BASE_URL so no new operator env var is required. Only leaf-issuing authority kinds (TenantIntermediate, PlatformLeafIssuer) get URLs, matching where the issuer loader is actually called. activate_authority uses COALESCE so an operator's manual SQL update survives a re-activation. - Migration 010 left certificate_revocations.issuer_id with an ON DELETE RESTRICT reference to pki_authorities, so tenant purge (explicit and background) rolled back for any tenant that had ever revoked a managed certificate. Add migration 017: switch the FK to ON DELETE SET NULL and extend the immutability trigger to allow exactly the FK-cascade transition (issuer_id: UUID -> NULL, every other column unchanged) while continuing to reject any other UPDATE and every DELETE. Publication continuity is preserved through issuer_fingerprint_sha256. - docker-compose forwarded the new PKI enrollment and lifecycle env vars but omitted ATOM_PKI_CA_KEY_BACKEND, ATOM_PKI_CA_KEY_ENCRYPTION_ KEY(_ID), and all ATOM_PKI_PKCS11_* settings for both atom and atom-dev services, so values documented in the release runbook never reached the container. Add the missing 12 variables to both services. Verified with cargo check --tests --locked and cargo fmt --check. The full integration matrix (./scripts/pki-test.sh smoke) still needs a live Postgres and GlobalSign EST client and should be re-run before merge. Signed-off-by: Arvindh <arvindh91@gmail.com>
Activation writes ocsp_url, ca_issuers_url, and crl_distribution_point_url from PkiCaKeyConfig.artifact_base_url as of the previous commit, and Config::for_tests() populates that field. The three UPDATE pki_authorities statements in the shared provisioning fixtures were left behind as a safety net and are now dead code — they overwrite the derived URLs with identical-scheme test constants. Drop them; keep the OCSP_URL / CA_ISSUERS_URL / CRL_URL constants because tests/m41_pki_est.rs still uses them for its own scenario-specific patch of a separately-provisioned issuer. Signed-off-by: Arvindh <arvindh91@gmail.com>
Release summary
Merge the completed Atom-native, multi-tenant PKI program from
certificatesintomain.The release provides one offline root trust anchor, an Atom-managed platform intermediate, one active intermediate per tenant, an optional platform leaf issuer for global entities, policy-backed certificate profiles, CSR/generated-key issuance, renewal, revocation, CRL, OCSP, runtime resolution v2, native enrollment, RFC 7030 EST, lifecycle automation, and PKCS#11 authority-key support.
This PR does not put the production root key in Atom. Root signing remains an offline/operator ceremony.
Included specification set
mainintegration and lifecycle-boundary stabilization — [PKI release] Sync current main into certificates #80PR-012's relying-party implementation is maintained in FluxMQ and was merged separately as absmach/fluxmq#558 into its
certificatesbranch.Human and AI testing
The exact procedure and evidence format are committed at:
./scripts/pki-test.sh smoke./scripts/pki-test.sh fullThe Rust workflow ends with an explicit seven-binary real PKI smoke run after the complete fresh-database test matrix and populated SoftHSM recovery proof. The smoke gate covers CA provisioning, independent OpenSSL CSR issuance, revocation, CRL, OCSP, runtime tenant isolation, and an independent GlobalSign EST client.
Final release validation
Validated head:
5347f9d39047a647a1492b839413e07e22933937GitHub merge preview:
97abe8f64623d5b77ac0902dd3634fe36d1755ccValidated tree:
af15c05d0a2889fc84e90b906d18b7ddb8b31381The head and GitHub merge preview have the same tree, because current
mainis an ancestor ofcertificates.cargo fmt --check;Baseline frontend-audit blocker
Frontend run 31581415297 passed install, UI lint, UI tests, and both production builds, but its dependency-audit step failed for both matrix projects.
This is a current-
mainbaseline failure, not a PKI diff:app/package.json,app/pnpm-lock.yaml,docs/package.json,docs/pnpm-lock.yaml, or.github/workflows/frontend.yml;mainfails at the same audit step for both projects;nanoidissues plusimage-sizeadvisories for which no patched package version is currently published.The PR remains draft until that baseline is remediated separately or a maintainer explicitly accepts its documented exception. Certificate validation itself is complete and green.
Database and compatibility
005through016; migrations are forward-only and applied automatically at startup.issuer_id = NULLretain the legacy resolver path.mainbroker-auth configuration and vendored-proto enforcement are preserved.Security assumptions
ATOM_PKI_CA_KEY_BACKENDand PKCS#11 configuration are operator-controlled deployment inputs;Merge gate
mainmainand head ascertificatesRollback
Do not roll back database migrations destructively. If release validation fails after deployment, stop new issuance/enrollment at the edge, restore the prior application image while retaining the migrated database and all issuer/key-provider configuration, keep CRL/OCSP publication available, and follow the authority/provider runbooks for any affected signer.