Skip to content

[PKI] Release Atom-native multi-tenant certificates - #79

Open
arvindh123 wants to merge 25 commits into
mainfrom
certificates
Open

[PKI] Release Atom-native multi-tenant certificates#79
arvindh123 wants to merge 25 commits into
mainfrom
certificates

Conversation

@arvindh123

@arvindh123 arvindh123 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Release summary

Merge the completed Atom-native, multi-tenant PKI program from certificates into main.

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

PR-012's relying-party implementation is maintained in FluxMQ and was merged separately as absmach/fluxmq#558 into its certificates branch.

Human and AI testing

The exact procedure and evidence format are committed at:

The 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: 5347f9d39047a647a1492b839413e07e22933937
GitHub merge preview: 97abe8f64623d5b77ac0902dd3634fe36d1755cc
Validated tree: af15c05d0a2889fc84e90b906d18b7ddb8b31381

The head and GitHub merge preview have the same tree, because current main is an ancestor of certificates.

  • Rust run 31581415233: passed
    • vendored broker proto matches upstream;
    • cargo fmt --check;
    • locked Clippy with warnings denied;
    • locked test compilation;
    • every test binary against a fresh PostgreSQL database;
    • independent OpenSSL and GlobalSign EST interoperability exercised;
    • SoftHSM PKCS#11 integration;
    • populated-token backup/restore followed by signing;
    • explicit seven-binary real PKI smoke rerun.
  • API Docs run 31581415303: passed
    • OpenAPI validation;
    • proto lint and generated-doc verification.
  • Cloudflare docs preview build passed.
  • No unresolved review threads or submitted reviews.

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-main baseline failure, not a PKI diff:

  • this PR has no changes to app/package.json, app/pnpm-lock.yaml, docs/package.json, docs/pnpm-lock.yaml, or .github/workflows/frontend.yml;
  • the latest scheduled Frontend run on main fails at the same audit step for both projects;
  • the high findings are newly disclosed transitive nanoid issues plus image-size advisories 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

  • Adds migrations 005 through 016; migrations are forward-only and applied automatically at startup.
  • Existing v1 certificate credentials with issuer_id = NULL retain the legacy resolver path.
  • Managed credentials use issuer-aware identity and can safely reuse serials across different issuers.
  • Legacy artifact routes remain available during the cutover.
  • Existing encrypted-database CA keys remain supported alongside PKCS#11-backed authorities.
  • Current main broker-auth configuration and vendored-proto enforcement are preserved.
  • No caller may select tenant, issuer, CA path, key backend, or opaque provider reference.

Security assumptions

  • the production root key stays offline and outside Atom configuration, database, container, and runtime memory;
  • ATOM_PKI_CA_KEY_BACKEND and PKCS#11 configuration are operator-controlled deployment inputs;
  • HSM PINs and KEKs are supplied through deployment secret mechanisms and never logged;
  • public CRL/OCSP/AIA routes are deployed at the URLs encoded in issued certificates;
  • relying parties use issuer-aware resolution and enforce the expected tenant before authorization;
  • rollout preserves old issuer providers while any retained certificate or artifact still depends on them;
  • all documented tests use disposable databases, development certificates, and disposable SoftHSM tokens—not production key material.

Merge gate

  • branch is mergeable against current main
  • API Docs passes
  • format, locked Clippy, and locked compile pass
  • complete fresh-PostgreSQL test matrix passes
  • SoftHSM PKCS#11 integration passes
  • populated-token recovery proof passes
  • named real PKI smoke step passes
  • review threads are resolved
  • base is re-verified as main and head as certificates
  • inherited frontend dependency-audit failure is remediated or explicitly accepted

Rollback

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.

arvindh123 and others added 19 commits August 5, 2026 23:51
* 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.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 12, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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.
@arvindh123
arvindh123 marked this pull request as ready for review August 12, 2026 14:10

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +486 to +490
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(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +20 to +22
ALTER TABLE certificate_revocations
ALTER COLUMN expires_at SET NOT NULL,
DROP CONSTRAINT certificate_revocations_credential_id_fkey;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment thread docker-compose.yml
Comment on lines +82 to +85
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}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant