CI Signing Process
Relevant source files
The following files were used as context for generating this wiki page:
The CI Signing Process is a critical security mechanism for the Numan Registry, ensuring the integrity and authenticity of the index.json file published to GitHub Pages. The process uses Ed25519 digital signatures to protect the registry against unauthorized modifications and to provide clients with a verifiable trust root.
This system is designed to prevent "unsigned-production fallback" and "silent index corruption" by enforcing strict validation gates before any signature is generated or published. Production signing is isolated within protected GitHub deployment workflows, ensuring that the production private key is never exposed to general build validation or PR environments.
Sources: README.md:12-25, SECURITY.md:52-59, REVIEW.md:28-32
Cryptographic Architecture
The signing process utilizes the Ed25519 algorithm to generate detached signatures over the canonical JSON representation of the registry index.
Signature Envelope
The detached signature is stored in registry/index.json.sig as a JSON envelope containing the key identifier, the algorithm used, and the Base64-encoded signature.
| Field | Description |
|---|---|
key_id | Identifier for the specific signing key (e.g., official-YYYY-MM) |
algorithm | The cryptographic algorithm used (always ed25519) |
signature | The Base64-encoded Ed25519 signature |
Sources: README.md:94-105, scripts/provision-production-key.sh:185-195
Canonicalization and Digesting
Signing is performed on the canonical JSON bytes of index.json. Canonicalization ensures that the signature is stable regardless of non-semantic JSON changes (like whitespace or key order). The SHA-256 hash of these canonical bytes is recorded as the index_sha256 in client lockfiles for subsequent verification.
Sources: README.md:88-92, README.md:107-111
Workflow Environments
The signing process is differentiated across three distinct environments to maintain security and allow for local testing.
Signing Environment Comparison
| Environment | Purpose | Key Type | Access Control |
|---|---|---|---|
| Local/Validation | Exercise sign→verify path | Ephemeral (Temp) | User-controlled; does not overwrite placeholder |
| Staging | Default branch deployment | Ephemeral (CI) | Workflow-generated; no production trust |
| Production | Official catalog publication | Protected Secret | Manual dispatch + Protected GitHub Environment |
Sources: AGENTS.md:38-44, README.md:130-143, REVIEW.md:46-48
Production Workflow Flowchart
This diagram illustrates the separation of concerns between validation and signing in the production environment.
The production workflow explicitly prevents the use of provisional lifecycle evidence and requires all structural lints to pass before the signing key is exposed.
Sources: scripts/test_workflow_safety.py:53-73, README.md:140-143
Tooling and Implementation
The signing logic is primarily implemented in scripts/ci-sign.py, which is invoked by CI workflows.
Key Management Logic
The scripts/provision-production-key.sh script is used by maintainers to generate new production keypairs locally. It enforces safety by never printing the private key to the terminal and setting restrictive (600) file permissions.
Signature Validation Gate
Before publication, CI validates the index using scripts/validate.py. This script performs a triple-check:
- Schema Validation: Ensures
index.jsonmatchesschemas/index-v1.json. - Canonicalization Check: Verifies the JSON is in compact, sorted canonical form.
- Signature Verification: Uses the public key (e.g.,
keys/official.pub) to verify the detached signature.
Sources: [AGENTS. AGENTS.md:27-30, [REVIEW. REVIEW.md:16-25, README.md:148-152
Safety Invariants
To maintain the integrity of the signing process, the following invariants are enforced:
- Placeholder Signature: The
registry/index.json.sigfile committed to the repository is aPLACEHOLDER. Real production signing only occurs during deployment. - No Private Keys in Tree: CI uses
scripts/scan_for_secrets.pyto ensure no private key material is ever committed to git. - Source Building Exclusion: The signing process is restricted to binary artifacts and compliant archives; it rejects
kind: sourceto ensure reproducibility. - Human Review: Production publication requires human approval and cannot be fully automated by scripts.
Sources: REVIEW.md:38-55, AGENTS.md:65-67, SECURITY.md:37-41
The CI Signing Process provides the foundation for the Numan Registry's trust model, ensuring that only reviewed and validated package metadata reaches end-users through a secure, non-interactive signing pipeline.
Sources: SECURITY.md:52-59, README.md:12-25