← Diligence index  ·  View raw .md

Title: Signing-Key Publishing, Pinning, and Rotation Policy Version: 0.1.0 Status: Phase 1 — example/demo key in repo; production KMS key pending KmsEd25519Signer (ADR-0002, skeleton today) Owner: Security Lead Last Reviewed: 2026-05-07 Next Review: 2026-08-07 Supersedes: none


Why this document exists

The customer-facing offline verifier (genomics-verify, see ../customer/LOI_ONEPAGER.md) re-canonicalizes a provenance manifest under JCS and verifies the detached Ed25519 signature against a public verification key that the lab fetches out of band.

For that flow to be defensible inside a lab's QMS, three things must be unambiguous:

  1. Where the lab obtains the canonical public key.
  2. How the lab confirms the key it pulled is the one we published (fingerprint pinning).
  3. When the key rotates and how old manifests stay verifiable after rotation.

This file is the single source of truth for all three.


1. Trust model

              published                  out-of-band                       in-pipeline
public key ─────────────► fingerprint ──────────► pinned in pilot agreement ──► verifies
(PEM file)               (sha256 hex)            and shipped to lab                signature

The public key file alone is not the trust anchor. The trust anchor is the fingerprintSHA-256(PEM-bytes) — which we deliver to the lab through a separate, signed channel (the executed pilot agreement, plus a confirmation email from the security lead sent from the company's primary corporate domain).

A lab that only has the PEM file but no out-of-band fingerprint is performing TOFU (trust-on-first-use) and must not rely on the result for clinical sign-off. Ask for the pinned fingerprint.


2. Where to fetch the current public key

Channel URL pattern Use when
Repo (canonical) https://github.com/NVIDIA-AI-Blueprints/genomics-analysis/raw/main/keys/genomics-public.pem Default; commit-pinned; verify the commit SHA matches the one cited in the pilot agreement.
Customer doc bundle customer-bundle-<pilot_id>.zip → keys/genomics-public.pem When the lab took delivery of a pilot bundle; the bundle's manifest pins the fingerprint.
In-pipeline The signature.json for any signed manifest carries public_key_fingerprint — the lab reconciles that against its pinned fingerprint, never against a key the same payload claims to use. Always, as a defense-in-depth check.

Canonical filename: genomics-public.pem. PEM-encoded Ed25519, SubjectPublicKeyInfo wrapper, PKCS#8 — the format cryptography.hazmat.primitives.serialization.load_pem_public_key parses by default.

Phase 1 note. As of v0.1.0 of this policy, the example key shipped at ../../../keys/genomics-public.pem.example is the only key in the repo. The example fingerprint is documented in §3 below. The production KMS-rooted key lands when KmsEd25519Signer (ADR-0002) flips from skeleton to GA, at which point this file is updated and a new section added documenting the retirement of the example key.


3. Current keys

3.1 Active: example/demo key (Phase 1)

Field Value
Key ID example-2026-05-07
Algorithm Ed25519
PEM path (in repo) keys/genomics-public.pem.example
Fingerprint (SHA-256 of PEM bytes) c45fed5f205aea057efa7314515ec3688109aa4f072aa71bd4a7fd4c48db102d
First used (signing) 2026-05-07 (earliest)
Status Active for demos only. Real pilot signatures must be produced by the production KMS key once KmsEd25519Signer is implemented.

This key is example material. It is checked into the repo so the demo script in customer/DEMO_SCRIPT.md runs end-to-end without network access. Any signature the lab receives that verifies under this key is by definition a demo signature, not a clinical-pilot signature.

3.2 Pending: production key (Phase 1 → Phase 2)

Field Value
Key ID (assigned at provisioning time, e.g. prod-2026-Q3)
Algorithm Ed25519
Storage Google Cloud KMS, asymmetric key, EC_SIGN_ED25519, HSM-backed
Resource path projects/<gcp_project>/locations/<region>/keyRings/<ring>/cryptoKeys/<key>/cryptoKeyVersions/<v>
Public key URL https://github.com/NVIDIA-AI-Blueprints/genomics-analysis/raw/<release_tag>/keys/genomics-public.pem
Fingerprint populated at first GA release; communicated by signed email + pilot agreement appendix
First used TBD (gated on KmsEd25519Signer landing)
Status Pending — substrate is ready, KMS hookup is tracked in genomics/CLAUDE.md §"Substrate-hook reality" item 3.

4. Lab-side verification checklist

A lab that just received manifest.json + signature.json does this on every signed sample, in order:

  1. Pin the fingerprint in advance, from the executed pilot agreement (Appendix A: Signing-Key Fingerprints), as a hex string. Treat the pilot agreement as the trust anchor.
  2. Pull the PEM from the canonical URL in §2 (or read it from the delivery bundle).
  3. Compute sha256(<the-PEM-bytes-as-stored-on-disk>) and confirm it equals the pinned fingerprint. Reject otherwise. bash sha256sum genomics-public.pem # expect: c45fed5f205aea057efa7314515ec3688109aa4f072aa71bd4a7fd4c48db102d (example key)
  4. Confirm the signature block has a public_key_fingerprint field equal to the pinned fingerprint. Reject otherwise. bash jq -r .public_key_fingerprint signature.json
  5. Run the verifier (genomics-verify): bash genomics-verify manifest.json signature.json --public-key genomics-public.pem
  6. Record the verifier's exit code (0 / 1) plus the manifest_sha256 and the run timestamp into the lab's QMS records alongside the run.

Steps 1, 3, and 4 are non-optional. Steps 5 and 6 are the action; steps 1, 3, and 4 are what makes the action mean something.


5. Rotation policy

5.1 Triggers

A signing key rotates on any of:

5.2 Process

  1. T-7 days — Notice posted to all active customers via the primary contact in the executed pilot agreement, by signed email from the company's corporate domain. Notice includes:
  2. Reason for rotation (scheduled / incident / personnel — minimum truthful disclosure consistent with any open security review).
  3. New key ID, fingerprint, canonical PEM URL.
  4. Cutover date.
  5. Whether the prior key is being deprecated (still verifiable for old manifests) or revoked (no manifest signed by it should be trusted any more — only used in confirmed-exposure rotation).
  6. T-0 — New key activates. Both keys remain valid for signature verification on prior manifests for the deprecation window (default 18 months) so historical artifacts stay re-verifiable.
  7. T+18 months — Deprecated key moved to the archive section of this document (§6). Manifests signed by the deprecated key remain verifiable for the lab's local records, but the platform stops issuing new signatures under that key on T-0 day one.

In a confirmed-exposure rotation, step 2's overlap is omitted and the prior key is moved straight to revoked status.

5.3 What labs should do on a rotation notice

  1. Read the notice; capture new key ID + fingerprint into local QMS records.
  2. Update the pinned fingerprint(s) in the lab's verification pipeline (e.g. config secret in their LIMS or CI).
  3. Re-pull the PEM from the canonical URL; confirm fingerprint match per §4.
  4. Continue verifying old manifests under the old fingerprint(s) until they age out of retention; verify new signatures under the new fingerprint.
  5. If the rotation is a revoke (not a deprecate), flag for the QMS owner: any manifest signed under the revoked fingerprint inside the exposure window may need re-signing or remediation.

6. Key archive (rotation history)

Past keys we have signed under, ordered most recent first.

Key ID Algorithm Fingerprint Status Active range Reason for rotation
example-2026-05-07 Ed25519 c45fed5f205aea057efa7314515ec3688109aa4f072aa71bd4a7fd4c48db102d Active (demo only; not for pilots) 2026-05-07 — present n/a — first key in repo, example use

Add new rows on rotation. Never delete rows; deprecation and revoke are status changes, not deletions.


7. References