Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Story: Developer trusts the dev CA locally

Story ID: STORY-003 Status: Revision 1 Created: 2026-10-13

Statement

As a developer, I want Xianyun to generate a name-constrained dev CA and install it in my trust stores, so that browsers and tools accept the local cluster’s certificates without warnings and the CA can’t vouch for domains I don’t use.

Trigger

The developer runs xianyun ca trust, or runs xianyun up with the builtin:dev-ca deployer.

Acceptance Criteria

Scenario: First trust generates and installs the CA

Given no CA exists for profile "dev" and the config hostname is "gitlab.dev"
When the developer runs "xianyun ca trust" and approves the sudo prompt
Then a CA certificate MUST exist under the profile's pki "current" directory
And its permitted DNS subtrees MUST be ".local", ".test", ".svc", and "gitlab.dev"
And the system trust store MUST contain the certificate

Scenario: Untrust removes current and legacy entries

Given the CA is trusted under both the Xianyun name and the legacy Caproni name
When the developer runs "xianyun ca untrust"
Then neither entry MUST remain in the system trust store
And neither entry MUST remain in any NSS database where certutil is available

Scenario: The CA key isn’t exposed during a build

Given a profile with a generated CA and the "builtin:dev-ca" deployer
When "kustomize build" runs against the staged overlay
Then every staged file containing the CA key MUST have mode 0600
And the staging directory MUST have mode 0700

Scenario: Missing NSS tooling doesn’t fail the trust

Given certutil isn't on PATH
When the developer runs "xianyun ca trust"
Then the exit code MUST be 0
And the output MUST note that NSS databases weren't updated

EARS Constraints

  • The system shall create ca.key with mode 0600 and shall never overwrite an existing key file.
  • If the CA’s constraints change, then the system shall re-sign with the same key.
  • If the CA has expired, then the system shall generate a new one.
  • When loading a CA, the system shall verify the certificate matches the private key.
  • If sudo is unavailable and the user isn’t root, then the system shall report that the trust store wasn’t changed. (Not met: apply_sudo logs a warning and runs the command without privileges, so the user sees the tool’s own permission error.)

Autonomy Limits

Not applicable for a human actor. Through MCP, ca trust and ca untrust are gated tools; ca inspect isn’t, and can generate a CA on first run.

Security Mapping

ConcernAddressed By
Information disclosure (key in staging)Third scenario; SR-010 (not yet met; measured 755 directory, 644 key)
Elevation of privilege (CA outside intended domains)First scenario subtrees; SR-011 (partial)
Tampering (swapped key or certificate)EARS constraint on loading; FR-008.6 (not yet met)
Spoofing (hostile cluster-reported zone)SR-011 (not yet met, unproven exploit)
Repudiation (who installed or removed a trust anchor, and when)No durable record today; SR-014 (not yet met)
Denial of serviceNot applicable beyond the single-user local case; the 10-year lifetime and the expiry regeneration are the relevant limits

Standards Mapping

  • SLSA Level: N/A
  • SSDF Practices: N/A
  • SCVS Controls: N/A

Dependencies

Notes

  • The Keychain path on macOS was read, not run, in this review. A macOS variant of the first two scenarios needs the macOS build host.
  • The third scenario fails today (see the threat model, TM-PKI-001).
  • Whether every client enforces Name Constraints (TM-PKI-006) is unproven; the first scenario checks the certificate’s content, not client behaviour.