PKI Release Testing
Required human and automated qualification for PKI releases.
PKI Release Testing: Human and AI Runbook
This runbook is the release gate for merging the certificates branch into
main. It converts the PKI test plan into commands that a human operator or an
AI coding agent can execute and report consistently.
The tests use disposable PostgreSQL databases, generated test keys, OpenSSL, the independent GlobalSign EST client, and (for the full gate) a disposable SoftHSM token. They must never use production CA keys, HSM credentials, tenant data, or reusable private-key fixtures.
Required release gates
| Gate | Purpose | Required result |
|---|---|---|
| PKI smoke | Prove the critical issue-to-revoke path with real DB and crypto implementations | Every selected test binary passes against its own fresh database |
| Rust CI | Format, lint, compile, and execute the complete repository test matrix | All steps pass with the committed Cargo.lock |
| PKI full integration | Exercise all PKI specifications, EST interoperability, and PKCS#11 behavior | Every PKI test binary passes; the HSM recovery proof passes in CI |
| API docs | Prove generated GraphQL/gRPC documentation is current | Workflow passes with no generated diff |
| Merge-state check | Test the commit GitHub will merge, including current main | Required checks are green on the release PR, not only on an older branch PR |
Do not merge when a gate is skipped, cancelled, stale, or green only on a different commit.
Test levels
Smoke test
scripts/pki-test.sh smoke runs a deliberately small but end-to-end set:
- tenant CA provisioning;
- CSR issuance and independent OpenSSL chain verification;
- immediate revocation;
- per-issuer CRL generation and verification;
- per-issuer OCSP good/revoked/unknown responses and verification;
- issuer-plus-serial/fingerprint runtime resolution and tenant isolation;
- RFC 7030 EST enrollment through the independent GlobalSign client.
This is a real integration smoke test. It does not replace the full gate.
Full PKI integration test
scripts/pki-test.sh full discovers and runs every tests/m<digits>_pki*.rs
integration binary, including the legacy-certificate migration and purge-after-
revocation regressions. It requires a pre-provisioned disposable SoftHSM token
and the independent EST client. The repository Rust workflow is the
authoritative full run because it also provisions the token, proves non-
exportable PKCS#11 behavior, and performs the populated-token backup/restore
signing exercise.
Local prerequisites
- Rust stable with
rustfmtandclippy; - PostgreSQL 16 (server and
psqlclient); - OpenSSL;
protoc;- Go and
github.com/globalsign/est/cmd/estclient@v1.0.7; - SoftHSM 2 for the full mode.
Create only a disposable database. The runner refuses a database name that
does not start with atom_pki_test.
The two example URLs are local development credentials only. Do not copy production connection strings into a shell history, CI log, issue, or PR.
Human test procedure
-
Check out the exact release PR head and record
git rev-parse HEAD. -
Confirm the diff is
certificates → mainand contains no production key, PIN, connection string, certificate private key, or generated test secret. -
Start a disposable PostgreSQL instance and install the prerequisites above.
-
Run the quality and compile gates:
-
Run the smoke gate:
-
Inspect the output. All seven selected binaries must pass; a compile-only result is not a smoke-test pass.
-
In GitHub, confirm
RustandAPI Docsare green on the current release-PR commit. Open the Rust job and confirm itsRun real PKI smoke teststep executed; do not rely only on the green summary icon. -
For a production-like pre-release drill, use a disposable SoftHSM token and run the full mode, then follow
PKCS11-RUNBOOK.mdfor the backup/restore proof. Never substitute the production root or a production HSM partition. -
Record the commit SHA, workflow run links, date, tester, and any environment deviation in the PR description or a PR comment.
Human acceptance checklist
- A tenant A certificate chains to tenant A's active issuer and the offline test root.
- Tenant B cannot issue, resolve, renew, or revoke tenant A's credential.
- Default leaves are not CAs and do not receive server authentication unless an explicit combined profile allows it.
- Revocation denies runtime resolution immediately.
- The issuer CRL contains the revoked serial and verifies independently.
- OCSP returns signed
good,revoked, andunknownresults correctly. - EST first enrollment and re-enrollment use the same policy/issuer pipeline as native enrollment.
- Existing encrypted-database authorities and PKCS#11-backed authorities retain their own provider; no fallback silently changes the signer.
- No private key, PIN, opaque provider reference, CSR body, or credential secret appears in logs, audit details, GraphQL output, or artifacts.
AI-agent test procedure
An AI agent follows the same commands and acceptance criteria as a human. It must additionally:
- Read
AGENTS.md,AI-GUIDELINES.md,TEST-PLAN.md, this runbook, and the changed PKI specifications before acting. - Resolve and report the exact base SHA, head SHA, and GitHub merge SHA being
tested. A head-only pass is insufficient when
mainhas advanced. - Use only disposable local/CI secrets. Never request, reveal, copy, or rotate production PKI credentials for a test.
- Run the commands rather than infer success from code inspection or an older workflow. Capture the failing test name and first actionable error when a command fails.
- Fix the implementation or test environment; never weaken an assertion,
skip a mandatory binary, remove
--locked, or replace independent crypto verification with an Atom-internal check merely to obtain green CI. - Re-run every affected gate after a fix and ensure all required checks belong to the newest commit.
- Produce the completion report required by
AGENTS.md: files changed, acceptance criteria, commands/results, migrations, compatibility impact, security assumptions, and unresolved risks.
Use this evidence format:
Failure handling
- Stop the release on the first reproducible failure.
- Preserve logs that do not contain secrets and link them from the PR.
- Treat cross-tenant access, signer fallback, key export, incorrect chain constraints, stale revocation, or unverifiable CRL/OCSP/EST output as release blockers.
- If external infrastructure prevents a full local run, use the GitHub-hosted gate. Do not mark the missing local execution as passed.
- After any code change, re-run both the focused failing test and the complete required workflow on the new commit.