Imposed rule: Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.

Pack Signing & RBAC Controls

This document defines the signing, verification, and authorization requirements for Stella Ops Task Packs across the CLI, Packs Registry, Task Runner, and Offline Kit. It is written for operators who publish and approve packs and for engineers building pack tooling. It aligns with Authority sprint tasks (AUTH-PACKS-41-001, AUTH-PACKS-43-001) and security-guild expectations. For the canonical scope catalogue and role model, see authority-scopes.md and scopes-and-roles.md.

Implementation status (reconciled 2026-05-30). Several controls in this document are the target posture; the shipped implementation is narrower. Where they diverge, an explicit Status note is given. Ground truth: StellaOpsScopes.cs (scope catalog), StellaOps.PacksRegistry.* (registry service), PasswordGrantHandlers.cs / StellaOpsScopeAuthorizationHandler.cs (Authority approval-token enforcement), and StellaOps.Cli (PackClient.cs, CommandFactory.cs).

Key gaps to be aware of before relying on this page:

  • The Packs Registry service signature verifier is SimpleSignatureVerifier (SHA-256 digest match, accepts unsigned) or RsaSignatureVerifier (RSA-PKCS1 over the digest string). Cosign/Fulcio/KMS and DSSE verification are not implemented in the registry service — those rows are roadmap.
  • The Packs Registry WebService authorizes with a single static X-API-Key (PacksRegistry:Auth:ApiKey); when no key is configured, auth is disabled. It does not enforce the packs.* OAuth scopes — scope enforcement lives in the CLI token requests and the shared Authority resource-server policies (StellaOpsResourceServerPolicies), applied when the registry is fronted by the gateway/router.

1 · Threat Model Highlights

ThreatMitigation
Unsigned or tampered pack uploaded to registryDigest is recomputed (SHA-256) and the supplied signature is verified on upload (PackService.UploadAsync). Status: today the verifier is SimpleSignatureVerifier (digest match; unsigned accepted unless Policy.RequireSignature=true) or RsaSignatureVerifier. Mandatory cosign/DSSE verification is roadmap (not implemented).
Unauthorized user publishing or promoting packsAuthority scope packs.write is requested by the CLI and enforced by the shared resource-server policy when the registry is gateway-fronted. Status: the standalone Packs Registry WebService gates on a static X-API-Key, not on the packs.* scopes.
Privilege escalation during approvalsApproval tokens require packs.approve and the pack_run_id / pack_gate_id / pack_plan_hash parameters at the token endpoint, plus fresh-auth (≤ 5 minutes); enforced in PasswordGrantHandlers (issuance) and StellaOpsScopeAuthorizationHandler (resource layer). All three are recorded as sensitive audit properties (pack.run_id, pack.gate_id, pack.plan_hash).
Secret exfiltration via pack stepsSecrets injection with redaction, sealed-mode network guardrails, evidence review. Status: the CLI exposes secret injection (PackClient.InjectSecretAsync); the broader sandbox/redaction guarantees are roadmap.
Replay of old approval tokensApproval tokens bind pack_plan_hash (validated as a 32–128 char hex digest) and require fresh authentication; stale auth_time is rejected at the resource layer.
Malicious pack in Offline KitMirror/offline-seed export carries provenance and digests. Status: signed-manifest + DSSE provenance verification on import is roadmap.

2 · Signing Requirements

2.1 Implemented today

2.2 Roadmap (NOT IMPLEMENTED in the registry service)

The following describe the intended target posture and are not present in StellaOps.PacksRegistry:

PolicyDescriptionStatus
anyOfAccepts any key in configured trust store.Roadmap
keyRefAccepts specific key ID (kid).Roadmap
oidcIssuerAccepts Fulcio certificates from allowed issuers (e.g., https://fulcio.sigstore.dev).Roadmap
thresholdRequires N-of-M signatures.Roadmap

3 · RBAC & Scopes

Authority exposes exactly four pack-related scopes (canonical source: StellaOpsScopes.cs):

ScopeConstDescription
packs.readStellaOpsScopes.PacksReadRead-only access to Task Packs catalogues and manifests.
packs.writeStellaOpsScopes.PacksWritePublish or update Task Packs in the registry.
packs.runStellaOpsScopes.PacksRunExecute Task Packs via CLI or Task Runner.
packs.approveStellaOpsScopes.PacksApproveFulfil Task Pack approval gates.

All four are exposed as resource-server policies in StellaOpsResourceServerPolicies and seeded into the authority.permissions catalog by S002_seed_full_scope_permissions.sql. Tenant assignment is mandatory for any pack scope under the client-credentials grant (ClientCredentialsHandlers rejects with "Pack scopes require a tenant assignment.").

Note. The CLI PackClient additionally requests two scopes — packs.secrets (secret injection) and packs.cache (cache management) — that are not registered in StellaOpsScopes.cs. They are therefore unknown scopes and will not be issued in an OpTok; treat the corresponding CLI surfaces (InjectSecretAsync, ManageCacheAsync) as not yet scope-backed.

3.1 Role Mapping (illustrative)

These role bundles are guidance only — they are not defined as named roles in the codebase. Operators assemble custom roles from the four scopes above via the Console Admin role editor.

Role (suggested)ScopesUse Cases
pack.viewerpacks.readInspect packs, plan runs.
pack.publisherpacks.read, packs.writePublish new versions, manage channels.
pack.operatorpacks.read, packs.runExecute packs, monitor runs.
pack.approverpacks.read, packs.approveFulfil approvals, authorize promotions.
pack.adminall fourFull lifecycle management (rare).

Roles are tenant-scoped; cross-tenant access requires explicit addition.

3.2 CLI Enforcement


4 · Approvals & Fresh Auth


5 · Secret Management

Status: largely roadmap / partially wired. The CLI exposes a secret-injection call (PackClient.InjectSecretAsyncPOST /api/v1/packs/runs/{runId}/secrets, requesting the unregistered packs.secrets scope), but the documented secret audit events below (secretRequested / secretDelivered) are not emitted by the Packs Registry service. Treat this section as the intended design.

Sealed mode is intended to require secrets to originate from a sealed vault, with external endpoints blocked.


6 · Audit & Evidence


7 · Offline / Air-Gap Policies

Status: partly roadmap. Offline-seed export is implemented (POST /api/v1/export/offline-seedoffline.seed.exported); the manual offline-signing approval workflow (.approval-request.json, trust-bundle.pem) is a target design and is not wired in the registry/CLI today.


8 · Incident Response


9 · Compliance Checklist


Last updated: 2025-10-27 (Sprint 43). Reconciled against implementation 2026-05-30 — see the “Implementation status” note at the top; sections 2, 5, 6, 7, and 8 distinguish shipped behavior from roadmap.