Add the Pi credential registry contract #13

Merged
vnprc merged 2 commits from agent/pi-credential-registry into master 2026-08-22 04:16:14 +01:00
Member

This adds the empty public contract that a private deployment will use to map Pi credentials to providers and libvirt dev VMs. A running machine stays unchanged because the public registry is empty and no ciphertext is added. When populated in a private fork, the contract derives ciphertext paths, Age recipients, credential inventory, and per-VM projections; malformed or incomplete data fails closed. The focused registry and existing credential-inventory checks prove the empty state, derived synthetic shapes, and sabotage paths. If the contract is wrong, leave this PR unmerged or revert it before private adoption.

Refs allod/strategy#34

Boundary

secrets owns credential IDs, targets, provider references, rotation strategy, ciphertext existence, and recipient derivation. It deliberately does not import profiles: lib.validatePiProviderReferences lets the archetypes join force unknown-provider rejection against the separately pinned profiles catalog without adding a fifth source edge.

No bearer value, real endpoint, provider/model metadata, private target, private recipient, or ciphertext is present in this change.

Exported contract

  • lib.piCredentials
  • lib.piCredentialCiphertextPaths
  • lib.piProviderCredentials
  • lib.piCredentialInventory
  • lib.piCredentialRecipients
  • lib.piCredentialProjections
  • lib.validatePiProviderReferences
  • lib.mkPiCredentialContract
  • lib.consumedInventorySource
  • per-dev-identity piCredentials and piProviders

Risk

R3: private adoption will change Age recipients and credential delivery. This public change is inert while the registry remains empty. Residual integration risk is the exact profiles/secrets join and downstream agenix projection, owned by later archetypes and deploy PRs.

Validation

  • nix build .#checks.x86_64-linux.pi-credential-registry .#checks.x86_64-linux.credential-inventory
  • nix flake check --no-build
  • direct evaluation of the empty registry, per-VM projection, ciphertext-path map, and consumed inventory source
  • git diff --check
This adds the empty public contract that a private deployment will use to map Pi credentials to providers and libvirt dev VMs. A running machine stays unchanged because the public registry is empty and no ciphertext is added. When populated in a private fork, the contract derives ciphertext paths, Age recipients, credential inventory, and per-VM projections; malformed or incomplete data fails closed. The focused registry and existing credential-inventory checks prove the empty state, derived synthetic shapes, and sabotage paths. If the contract is wrong, leave this PR unmerged or revert it before private adoption. Refs allod/strategy#34 ## Boundary `secrets` owns credential IDs, targets, provider references, rotation strategy, ciphertext existence, and recipient derivation. It deliberately does not import profiles: `lib.validatePiProviderReferences` lets the archetypes join force unknown-provider rejection against the separately pinned profiles catalog without adding a fifth source edge. No bearer value, real endpoint, provider/model metadata, private target, private recipient, or ciphertext is present in this change. ## Exported contract - `lib.piCredentials` - `lib.piCredentialCiphertextPaths` - `lib.piProviderCredentials` - `lib.piCredentialInventory` - `lib.piCredentialRecipients` - `lib.piCredentialProjections` - `lib.validatePiProviderReferences` - `lib.mkPiCredentialContract` - `lib.consumedInventorySource` - per-dev-identity `piCredentials` and `piProviders` ## Risk R3: private adoption will change Age recipients and credential delivery. This public change is inert while the registry remains empty. Residual integration risk is the exact profiles/secrets join and downstream agenix projection, owned by later archetypes and deploy PRs. ## Validation - `nix build .#checks.x86_64-linux.pi-credential-registry .#checks.x86_64-linux.credential-inventory` - `nix flake check --no-build` - direct evaluation of the empty registry, per-VM projection, ciphertext-path map, and consumed inventory source - `git diff --check`
Author
Member

The independent read-only review found two defects in cfd52d4:

  • High: the standalone secrets.nix/agenix recipient helper validates only target/key shape. A malformed registry ID such as ../escape, invalid rotation strategy, empty providers, or unknown fields can still produce a recipient entry. The standalone surface must force the full registry schema, global provider uniqueness, and recipient-key uniqueness while leaving ciphertext existence to the flake contract so agenix can create a new file.
  • Low: one combined reference sabotage cannot prove duplicate-provider, unsupported-target, and missing-ciphertext validators independently because the missing-ciphertext failure masks the other two. Split them into three controlled fixtures.

I will fix both in a follow-up commit and rerun the focused checks.

The independent read-only review found two defects in `cfd52d4`: - **High:** the standalone `secrets.nix`/agenix recipient helper validates only target/key shape. A malformed registry ID such as `../escape`, invalid rotation strategy, empty providers, or unknown fields can still produce a recipient entry. The standalone surface must force the full registry schema, global provider uniqueness, and recipient-key uniqueness while leaving ciphertext existence to the flake contract so agenix can create a new file. - **Low:** one combined reference sabotage cannot prove duplicate-provider, unsupported-target, and missing-ciphertext validators independently because the missing-ciphertext failure masks the other two. Split them into three controlled fixtures. I will fix both in a follow-up commit and rerun the focused checks.
Author
Member

Both review findings are addressed in 2692bef:

  • lib/pi-credential-schema.nix is now the single strict schema used by both the flake contract and standalone secrets.nix recipient generation. The agenix surface rejects invalid IDs/fields/lists/rotation strategy, duplicate provider ownership, malformed recipient key records, and duplicate recipient keys before producing any path.
  • The reference witness now isolates duplicate-provider, unsupported-target, unknown-target, and missing-ciphertext sabotage. Separate fixtures cover standalone path traversal/schema rejection, declared-recipient drift, and duplicate recipient keys.

Revalidated:

  • nix build .#checks.x86_64-linux.pi-credential-registry .#checks.x86_64-linux.credential-inventory
  • nix flake check --no-build
  • standalone valid secrets.nix evaluation
  • standalone malformed ../escape registry rejection
  • git diff --check
Both review findings are addressed in `2692bef`: - `lib/pi-credential-schema.nix` is now the single strict schema used by both the flake contract and standalone `secrets.nix` recipient generation. The agenix surface rejects invalid IDs/fields/lists/rotation strategy, duplicate provider ownership, malformed recipient key records, and duplicate recipient keys before producing any path. - The reference witness now isolates duplicate-provider, unsupported-target, unknown-target, and missing-ciphertext sabotage. Separate fixtures cover standalone path traversal/schema rejection, declared-recipient drift, and duplicate recipient keys. Revalidated: - `nix build .#checks.x86_64-linux.pi-credential-registry .#checks.x86_64-linux.credential-inventory` - `nix flake check --no-build` - standalone valid `secrets.nix` evaluation - standalone malformed `../escape` registry rejection - `git diff --check`
vnprc approved these changes 2026-08-22 04:16:08 +01:00
vnprc merged commit 2692bef371 into master 2026-08-22 04:16:14 +01:00
vnprc deleted branch agent/pi-credential-registry 2026-08-22 04:16:14 +01:00
Sign in to join this conversation.
No description provided.