CLI Operator Decision Signing

Operator decision signing covers high-risk approvals such as exception approval and release promotion. The CLI is a signing client only; the server remains the canonicalization authority.

Signing model

  1. The backend prepares the operator-decision@v1 predicate and returns the exact DSSE pre-authentication encoding (PAE) bytes plus the canonical payload bytes.
  2. The CLI signs those PAE bytes verbatim through ICryptoProviderRegistry.ResolveSigner(CryptoCapability.Signing, algorithmId, keyRef, providerHint).
  3. The CLI wraps the supplied payload bytes and signature into a DSSE envelope and submits that envelope back to the backend decision endpoint.

The CLI must not construct the predicate, reserialize it, or keep a local copy of the server canonicalization routine. Byte identity of the server-provided PAE is the contract.

Provider routing

Software ES256 signing uses the default crypto provider. Regional providers remain selected through the same registry path, including FIPS, GOST, SM, and eIDAS-capable providers when installed and configured for the runtime. No operator-decision command should call platform cryptography APIs directly for signature generation.

Local QES, smartcard, and PKCS#11 flows require hardware/token provisioning. When a token is not available in the operator environment, record the hardware gap in sprint evidence instead of substituting a fake production QES path. Synthetic eIDAS provider profiles may be ingested for deterministic parser and wiring tests only; they are not production qualified-provider pack evidence.

Current command status

stella attest attach --sign --key <pem> is implemented independently of the server decision contract. It signs the existing DSSE envelope payload PAE and appends a signature before online attach or offline bundle storage.

Signed stella release approve --sign, stella release reject --sign, stella release promote --sign, stella release deploy --sign, and stella release rollback --sign now consume the ReleaseOrchestrator prepare endpoint and submit real compact DSSE envelopes on the gated release decision calls. Signed stella exception approve --sign and stella exception reject --sign both consume POST /api/v1/policy/exception/operator-decisions/prepare, sign the returned PAE bytes verbatim, and submit the compact DSSE envelope as operatorDecisionEnvelope on the existing approve/reject calls.

Sprint closeout for the live path still requires enforcement-on runtime proof: unsigned release/exception decisions must be rejected, signed decisions must be accepted and persisted with a verifiable envelope, and non-default regional providers must either pass live verification or carry an explicit hardware or plugin availability gap.