feat: Implement console session management with tenant and profile handling
- Add ConsoleSessionStore for managing console session state including tenants, profile, and token information. - Create OperatorContextService to manage operator context for orchestrator actions. - Implement OperatorMetadataInterceptor to enrich HTTP requests with operator context metadata. - Develop ConsoleProfileComponent to display user profile and session details, including tenant information and access tokens. - Add corresponding HTML and SCSS for ConsoleProfileComponent to enhance UI presentation. - Write unit tests for ConsoleProfileComponent to ensure correct rendering and functionality.
This commit is contained in:
		@@ -12,28 +12,61 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
 | 
			
		||||
| Scope | Surface | Purpose | Notes |
 | 
			
		||||
|-------|---------|---------|-------|
 | 
			
		||||
| `advisory:ingest` | Concelier ingestion APIs | Append-only writes to `advisory_raw` collections. | Requires tenant claim; blocked for global clients. |
 | 
			
		||||
| `advisory:read` | `/aoc/verify`, Concelier dashboards, CLI | Read-only access to stored advisories and guard results. | Needed alongside `aoc:verify` for CLI/console verification. |
 | 
			
		||||
| `advisory:read` | `/aoc/verify`, Concelier dashboards, CLI | Read-only access to stored advisories and guard results. | Must be requested with `aoc:verify`; Authority rejects tokens missing the pairing. |
 | 
			
		||||
| `vex:ingest` | Excititor ingestion APIs | Append-only writes to `vex_raw`. | Mirrors `advisory:ingest`; tenant required. |
 | 
			
		||||
| `vex:read` | `/aoc/verify`, Excititor dashboards, CLI | Read-only access to stored VEX material. | Pair with `aoc:verify` for guard checks. |
 | 
			
		||||
| `aoc:verify` | CLI/CI pipelines, Console verification jobs | Execute Aggregation-Only Contract guard runs. | Always issued with tenant; read-only combined with `advisory:read`/`vex:read`. |
 | 
			
		||||
| `vex:read` | `/aoc/verify`, Excititor dashboards, CLI | Read-only access to stored VEX material. | Must be requested with `aoc:verify`; Authority rejects tokens missing the pairing. |
 | 
			
		||||
| `aoc:verify` | CLI/CI pipelines, Console verification jobs | Execute Aggregation-Only Contract guard runs. | Always issued with tenant; required whenever requesting `advisory:read`, `vex:read`, or any `signals:*` scope. |
 | 
			
		||||
| `signals:read` | Signals API, reachability dashboards | Read-only access to stored reachability signals. | Tenant and `aoc:verify` required; missing pairing returns `invalid_scope`. |
 | 
			
		||||
| `signals:write` | Signals ingestion APIs | Append-only writes for reachability signals. | Requires tenant and `aoc:verify`; Authority logs `authority.aoc_scope_violation` on mismatch. |
 | 
			
		||||
| `signals:admin` | Signals administration tooling | Rotate credentials, manage reachability sensors, purge stale data. | Reserved for automation; `aoc:verify` + tenant mandatory; violations are audited. |
 | 
			
		||||
| `graph:write` | Cartographer pipeline | Enqueue graph build/overlay jobs. | Reserved for Cartographer service identity; tenant required. |
 | 
			
		||||
| `graph:read` | Graph API, Scheduler overlays, UI | Read graph projections/overlays. | Tenant required; granted to Cartographer, Graph API, Scheduler. |
 | 
			
		||||
| `graph:export` | Graph export endpoints | Stream GraphML/JSONL artefacts. | UI/gateway automation only; tenant required. |
 | 
			
		||||
| `graph:simulate` | Policy simulation overlays | Trigger what-if overlays on graphs. | Restricted to automation; tenant required. |
 | 
			
		||||
| `effective:write` | Policy Engine | Create/update `effective_finding_*` collections. | **Only** the Policy Engine service client may hold this scope; tenant required. |
 | 
			
		||||
| `findings:read` | Console, CLI, exports | Read derived findings materialised by Policy Engine. | Shared across tenants with RBAC; tenant claim still enforced. |
 | 
			
		||||
| `policy:author` | Policy Studio (Console, CLI) | Author drafts, run lint, execute quick simulations. | Tenant required; typically granted via `role/policy-author`. |
 | 
			
		||||
| `policy:review` | Policy Studio review panes | Review drafts, leave comments, request changes. | Tenant required; pair with `policy:simulate` for diff previews. |
 | 
			
		||||
| `policy:approve` | Policy Studio approvals | Approve or reject policy drafts. | Tenant required; fresh-auth enforced by Console UI. |
 | 
			
		||||
| `policy:operate` | Policy Studio promotion controls | Trigger batch simulations, promotions, and canary runs. | Tenant required; combine with `policy:run`/`policy:activate`. |
 | 
			
		||||
| `policy:audit` | Policy audit exports | Access immutable policy history, comments, and signatures. | Tenant required; read-only access. |
 | 
			
		||||
| `policy:simulate` | Policy Studio / CLI simulations | Run simulations against tenant inventories. | Tenant required; available to authors, reviewers, operators. |
 | 
			
		||||
| `vuln:read` | Vuln Explorer API/UI | Read normalized vulnerability data. | Tenant required. |
 | 
			
		||||
| Existing scopes | (e.g., `policy:*`, `concelier.jobs.trigger`) | Unchanged. | Review `/docs/security/policy-governance.md` for policy-specific scopes. |
 | 
			
		||||
| `export.viewer` | Export Center APIs | List export profiles/runs, fetch manifests and bundles. | Tenant required; read-only access. |
 | 
			
		||||
| `export.operator` | Export Center APIs | Trigger export runs, manage schedules, request verifications. | Tenant required; pair with `export.admin` for retention/encryption changes. |
 | 
			
		||||
| `export.admin` | Export Center administrative APIs | Configure retention policies, encryption keys, and scheduling defaults. | Tenant required; token requests must include `export_reason` + `export_ticket`; Authority audits denials. |
 | 
			
		||||
| `orch:read` | Orchestrator dashboards/API | Read queued jobs, worker state, and rate-limit telemetry. | Tenant required; never grants mutation rights. |
 | 
			
		||||
| `orch:operate` | Orchestrator control actions | Execute pause/resume, retry, sync-now, and backfill operations. Requires tenant assignment **and** `operator_reason`/`operator_ticket` parameters when requesting tokens. |
 | 
			
		||||
| `exceptions:read` | Exception service APIs, Console | Enumerate exception definitions, routing templates, and approval state. | Tenant and approval routing metadata required for audit replay. |
 | 
			
		||||
| `exceptions:write` | Policy Engine → Authority bridge | Persist exception evaluations, lifecycle events, and status changes. | Tenant required; only service principals should hold this scope. |
 | 
			
		||||
| `exceptions:approve` | Console fresh-auth flows, delegated admins | Approve or reject exception requests routed through Authority. | Tenant required; Authority enforces MFA when any bound routing template has `requireMfa=true`. |
 | 
			
		||||
| `ui.read` | Console base APIs | Retrieve tenant catalog, profile metadata, and token introspection results. | Tenant header required; responses are DPoP-bound and audit logged. |
 | 
			
		||||
| `authority:tenants.read` | Console admin workspace | Enumerate configured tenants, default roles, and isolation metadata. | Tenant claim must match header; access audited via `authority.console.tenants.read`. |
 | 
			
		||||
| Existing scopes | (e.g., `policy:*`, `concelier.jobs.trigger`) | Unchanged. | `concelier.merge` is retired — clients must request `advisory:ingest`/`advisory:read`; requests continue to fail with `invalid_client`. Review `/docs/security/policy-governance.md` for policy-specific scopes. |
 | 
			
		||||
 | 
			
		||||
### 1.1 Scope bundles (roles)
 | 
			
		||||
 | 
			
		||||
- **`role/concelier-ingest`** → `advisory:ingest`, `advisory:read`.
 | 
			
		||||
- **`role/excititor-ingest`** → `vex:ingest`, `vex:read`.
 | 
			
		||||
- **`role/signals-uploader`** → `signals:write`, `signals:read`, `aoc:verify`.
 | 
			
		||||
- **`role/aoc-operator`** → `aoc:verify`, `advisory:read`, `vex:read`.
 | 
			
		||||
- **`role/policy-engine`** → `effective:write`, `findings:read`.
 | 
			
		||||
- **`role/cartographer-service`** → `graph:write`, `graph:read`.
 | 
			
		||||
- **`role/graph-gateway`** → `graph:read`, `graph:export`, `graph:simulate`.
 | 
			
		||||
- **`role/console`** → `advisory:read`, `vex:read`, `aoc:verify`, `findings:read`, `vuln:read`.
 | 
			
		||||
- **`role/console`** → `ui.read`, `advisory:read`, `vex:read`, `exceptions:read`, `aoc:verify`, `findings:read`, `orch:read`, `vuln:read`.
 | 
			
		||||
- **`role/ui-console-admin`** → `ui.read`, `authority:tenants.read`, `authority:roles.read`, `authority:tokens.read`, `authority:clients.read` (paired with write scopes where required).  
 | 
			
		||||
- **`role/orch-viewer`** *(Authority role: `Orch.Viewer`)* → `orch:read`.
 | 
			
		||||
- **`role/orch-operator`** *(Authority role: `Orch.Operator`)* → `orch:read`, `orch:operate`.
 | 
			
		||||
- **`role/policy-author`** → `policy:author`, `policy:read`, `policy:simulate`, `findings:read`.
 | 
			
		||||
- **`role/policy-reviewer`** → `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
 | 
			
		||||
- **`role/policy-approver`** → `policy:approve`, `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
 | 
			
		||||
- **`role/policy-operator`** → `policy:operate`, `policy:run`, `policy:activate`, `policy:read`, `policy:simulate`, `findings:read`.
 | 
			
		||||
- **`role/policy-auditor`** → `policy:audit`, `policy:read`, `policy:simulate`, `findings:read`.
 | 
			
		||||
- **`role/export-viewer`** *(Authority role: `Export.Viewer`)* → `export.viewer`.
 | 
			
		||||
- **`role/export-operator`** *(Authority role: `Export.Operator`)* → `export.viewer`, `export.operator`.
 | 
			
		||||
- **`role/export-admin`** *(Authority role: `Export.Admin`)* → `export.viewer`, `export.operator`, `export.admin`.
 | 
			
		||||
- **`role/exceptions-service`** → `exceptions:read`, `exceptions:write`.
 | 
			
		||||
- **`role/exceptions-approver`** → `exceptions:read`, `exceptions:approve`.
 | 
			
		||||
 | 
			
		||||
Roles are declared per tenant in `authority.yaml`:
 | 
			
		||||
 | 
			
		||||
@@ -43,12 +76,34 @@ tenants:
 | 
			
		||||
    roles:
 | 
			
		||||
      concelier-ingest:
 | 
			
		||||
        scopes: [advisory:ingest, advisory:read]
 | 
			
		||||
      signals-uploader:
 | 
			
		||||
        scopes: [signals:write, signals:read, aoc:verify]
 | 
			
		||||
      aoc-operator:
 | 
			
		||||
        scopes: [aoc:verify, advisory:read, vex:read]
 | 
			
		||||
      orch-viewer:
 | 
			
		||||
        scopes: [orch:read]
 | 
			
		||||
      orch-operator:
 | 
			
		||||
        scopes: [orch:read, orch:operate]
 | 
			
		||||
      policy-author:
 | 
			
		||||
        scopes: [policy:author, policy:read, policy:simulate, findings:read]
 | 
			
		||||
      policy-reviewer:
 | 
			
		||||
        scopes: [policy:review, policy:read, policy:simulate, findings:read]
 | 
			
		||||
      policy-approver:
 | 
			
		||||
        scopes: [policy:approve, policy:review, policy:read, policy:simulate, findings:read]
 | 
			
		||||
      policy-operator:
 | 
			
		||||
        scopes: [policy:operate, policy:run, policy:activate, policy:read, policy:simulate, findings:read]
 | 
			
		||||
      policy-auditor:
 | 
			
		||||
        scopes: [policy:audit, policy:read, policy:simulate, findings:read]
 | 
			
		||||
      policy-engine:
 | 
			
		||||
        scopes: [effective:write, findings:read]
 | 
			
		||||
      exceptions-service:
 | 
			
		||||
        scopes: [exceptions:read, exceptions:write]
 | 
			
		||||
      exceptions-approver:
 | 
			
		||||
        scopes: [exceptions:read, exceptions:approve]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> **MFA requirement:** When any `exceptions.routingTemplates` entry sets `requireMfa: true`, Authority refuses to mint tokens containing `exceptions:approve` unless the authenticating identity provider advertises MFA support. Password/OIDC flows produce `authority.password.grant` audit events with `reason="Exception approval scope requires an MFA-capable identity provider."` when the requirement is violated.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 2 · Tenancy enforcement
 | 
			
		||||
@@ -64,15 +119,18 @@ Tokens now include:
 | 
			
		||||
Authority rejects requests when:
 | 
			
		||||
 | 
			
		||||
- `tenant` is missing while requesting `advisory:ingest`, `advisory:read`, `vex:ingest`, `vex:read`, or `aoc:verify` scopes.
 | 
			
		||||
- `aoc:verify` is absent while tokens request `advisory:read`, `vex:read`, or any `signals:*` scope (`invalid_scope` with deterministic message).
 | 
			
		||||
- `service_identity != policy-engine` but `effective:write` is present (`ERR_AOC_006` enforcement).
 | 
			
		||||
- `service_identity != cartographer` but `graph:write` is present (graph pipeline enforcement).
 | 
			
		||||
- Tokens attempt to combine `advisory:ingest` with `effective:write` (separation of duties).
 | 
			
		||||
- `exceptions:approve` is requested by a client without a tenant assignment or via an identity provider lacking MFA when `RequireMfaForApprovals=true`.
 | 
			
		||||
 | 
			
		||||
### 2.2 Propagation
 | 
			
		||||
 | 
			
		||||
- API Gateway forwards `tenant` claim as header (`X-Stella-Tenant`). Services refuse requests lacking the header.
 | 
			
		||||
- Concelier/Excititor stamp tenant into raw documents and structured logs.
 | 
			
		||||
- Policy Engine copies `tenant` from tokens into `effective_finding_*` collections.
 | 
			
		||||
- Exception lifecycle services persist tenant and the selected routing template identifier alongside approval decisions. Authority audit events (`authority.password.grant`, `authority.client_credentials.grant`) surface `audit.scopes` and, on denials, a `scope.invalid` metadata entry so operators can trace exception approval attempts without inspecting downstream services.
 | 
			
		||||
 | 
			
		||||
### 2.3 Cross-tenant scenarios
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,15 +49,35 @@ The console client is registered in Authority as `console-ui` with scopes:
 | 
			
		||||
|--------------|----------------|-------|
 | 
			
		||||
| Base navigation (Dashboard, Findings, SBOM, Runs) | `ui.read`, `findings:read`, `advisory:read`, `vex:read`, `aoc:verify` | `findings:read` enables Policy Engine overlays; `advisory:read`/`vex:read` load ingestion panes; `aoc:verify` allows on-demand guard runs. |
 | 
			
		||||
| Admin workspace | `ui.admin`, `authority:tenants.read`, `authority:tenants.write`, `authority:roles.read`, `authority:roles.write`, `authority:tokens.read`, `authority:tokens.revoke`, `authority:clients.read`, `authority:clients.write`, `authority:audit.read` | Scope combinations are tenant constrained. Role changes require fresh-auth. |
 | 
			
		||||
| Policy approvals | `policy:read`, `policy:review`, `policy:approve`, `policy:activate`, `policy:runs` | `policy:activate` gated behind fresh-auth. |
 | 
			
		||||
| Policy approvals | `policy:read`, `policy:review`, `policy:approve`, `policy:operate`, `policy:simulate` | `policy:operate` (promote/activate/run) requires fresh-auth. |
 | 
			
		||||
| Observability panes (status ticker, telemetry) | `ui.telemetry`, `scheduler:runs.read`, `advisory:read`, `vex:read` | `ui.telemetry` drives OTLP export toggles. |
 | 
			
		||||
| Orchestrator dashboard (queues, workers, rate limits) | `orch:read` | Provision via `Orch.Viewer` role; read-only access to job state and telemetry. |
 | 
			
		||||
| Orchestrator control actions (pause/resume, retry, sync-now, backfill) | `orch:operate` (plus `orch:read`) | CLI/Console must request tokens with `operator_reason` and `operator_ticket`; Authority denies issuance when either value is missing. |
 | 
			
		||||
| Downloads parity (SBOM, attestation) | `downloads:read`, `attestation:verify`, `sbom:export` | Console surfaces digests only; download links require CLI parity for write operations. |
 | 
			
		||||
 | 
			
		||||
Guidance:
 | 
			
		||||
 | 
			
		||||
- **Role mapping**: Provision Authority role `role/ui-console-admin` encapsulating the admin scopes above.  
 | 
			
		||||
- **Orchestrator viewers**: Assign Authority role `role/orch-viewer` (Authority role string `Orch.Viewer`) to consoles that require read-only access to Orchestrator telemetry.  
 | 
			
		||||
- **Orchestrator operators**: Assign Authority role `role/orch-operator` (Authority role string `Orch.Operator`) to identities allowed to pause/resume or backfill. Tokens must include `operator_reason` (≤256 chars) and `operator_ticket` (≤128 chars); Authority records the values in audit logs.
 | 
			
		||||
- **Tenant enforcement**: Gateway injects `X-Stella-Tenant` from token claims. Requests missing the header must be rejected by downstream services (Concelier, Excititor, Policy Engine) and logged.  
 | 
			
		||||
- **Separation of duties**: Never grant `ui.admin` and `policy:approve` to the same human role without SOC sign-off; automation accounts should use least-privilege dedicated clients.
 | 
			
		||||
- **Separation of duties**: Never grant `ui.admin` and `policy:approve`/`policy:operate` to the same human role without SOC sign-off; automation accounts should use least-privilege dedicated clients.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 3.1 Console Authority endpoints
 | 
			
		||||
 | 
			
		||||
Console uses dedicated Authority endpoints scoped under `/console/*`. All requests must include the tenant header injected by the gateway (`X-Stella-Tenant`); calls without the header fail with `tenant_header_missing` and emit a structured audit event. Keep reverse proxies configured to pass the header end-to-end.
 | 
			
		||||
 | 
			
		||||
| Endpoint | Required scopes | Purpose | Notes |
 | 
			
		||||
|----------|-----------------|---------|-------|
 | 
			
		||||
| `GET /console/tenants` | `authority:tenants.read` | Returns the tenant catalogue for the authenticated principal. | Validates `X-Stella-Tenant`; rejects tenants not configured in Authority. |
 | 
			
		||||
| `GET /console/profile` | `ui.read` | Surfaces subject metadata (roles, scopes, session id, fresh-auth state). | Response includes `freshAuth` (bool) based on a 300 s window since `auth_time`. |
 | 
			
		||||
| `POST /console/token/introspect` | `ui.read` | Introspects the access token currently in use and reports expiry + tenant. | Console polls this endpoint to drive session inactivity prompts; intended for SPA usage via fetch POST. |
 | 
			
		||||
 | 
			
		||||
**Fresh-auth & session inactivity:** Authority stamps `auth_time` on issued tokens and considers privileged actions “fresh” for five minutes. When `/console/profile` returns `freshAuth: false`, the UI must require an interactive re-authentication before allowing admin operations (`ui.admin`, `authority:*` mutations, `policy:activate`, `exceptions:approve`). Access tokens remain short-lived (`00:02:00` by default); pair this with Console session timeouts so idle dashboards prompt the user before two minutes of inactivity.
 | 
			
		||||
 | 
			
		||||
**DPoP + tenant binding:** All `/console/*` endpoints require DPoP-bound access tokens. Audit events include `tenant.resolved`, `scope`, `correlationId`, and (when applicable) `token.expires_at`. Staple the same headers into downstream services so cross-component troubleshooting uses the same correlation identifiers.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
@@ -148,15 +168,16 @@ Document gaps and remediation hooks in `SEC5.*` backlog as they are addressed.
 | 
			
		||||
 | 
			
		||||
## 9 · Compliance checklist
 | 
			
		||||
 | 
			
		||||
- [ ] Authority client `console-ui` registered with PKCE, DPoP, tenant claim requirement, and scopes from §3.  
 | 
			
		||||
- [ ] CSP enforced per §4 with overrides documented in deployment manifests.  
 | 
			
		||||
- [ ] Fresh-auth timer (300 s) validated for admin and policy actions; audit events captured.  
 | 
			
		||||
- [ ] DPoP binding tested (replay attempt blocked; logs show `ui_dpop_failure_total` increment).  
 | 
			
		||||
- [ ] Offline mode exercises performed (banner, CLI guidance, manifest verification).  
 | 
			
		||||
- [ ] Evidence download parity verified with CLI scripts; console never caches sensitive artefacts.  
 | 
			
		||||
- [ ] Monitoring dashboards show metrics and alerts outlined in §6; alert runbooks reviewed with Security Guild.  
 | 
			
		||||
- [ ] Security review sign-off recorded in sprint log with links to Authority threat model references.
 | 
			
		||||
- [x] Authority client `console-ui` registered with PKCE, DPoP, tenant claim requirement, and scopes from §3. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#authority-client-validation))  
 | 
			
		||||
- [x] CSP enforced per §4 with overrides documented in deployment manifests. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#csp-enforcement))  
 | 
			
		||||
- [x] Fresh-auth timer (300 s) validated for admin and policy actions; audit events captured. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#fresh-auth-timer))  
 | 
			
		||||
- [x] DPoP binding tested (replay attempt blocked; logs show `ui_dpop_failure_total` increment). (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#dpop-binding-test))  
 | 
			
		||||
- [x] Offline mode exercises performed (banner, CLI guidance, manifest verification). (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#offline-mode-exercise))  
 | 
			
		||||
- [x] Evidence download parity verified with CLI scripts; console never caches sensitive artefacts. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#evidence-parity))  
 | 
			
		||||
- [x] Monitoring dashboards show metrics and alerts outlined in §6; alert runbooks reviewed with Security Guild. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#monitoring--alerts))  
 | 
			
		||||
- [x] Security review sign-off recorded in sprint log with links to Authority threat model references. (see [console security sign-off](../updates/2025-10-27-console-security-signoff.md#sign-off))
 | 
			
		||||
- [x] `/console` Authority endpoints validated for tenant header enforcement, fresh-auth prompts, and introspection flows (Audit IDs `authority.console.tenants.read`, `authority.console.profile.read`, `authority.console.token.introspect`). (see [console security sign-off](../updates/2025-10-31-console-security-refresh.md))
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
*Last updated: 2025-10-28 (Sprint 23).* 
 | 
			
		||||
*Last updated: 2025-10-31 (Sprint 23).* 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										165
									
								
								docs/security/pack-signing-and-rbac.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								docs/security/pack-signing-and-rbac.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
> **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 signing, verification, and authorization requirements for Task Packs across the CLI, Packs Registry, Task Runner, and Offline Kit. It aligns with Authority sprint tasks (`AUTH-PACKS-41-001`, `AUTH-PACKS-43-001`) and security guild expectations.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 1 · Threat Model Highlights
 | 
			
		||||
 | 
			
		||||
| Threat | Mitigation |
 | 
			
		||||
|--------|------------|
 | 
			
		||||
| Unsigned or tampered pack uploaded to registry | Mandatory cosign/DSSE verification before acceptance. |
 | 
			
		||||
| Unauthorized user publishing or promoting packs | Authority scopes (`Packs.Write`) + registry policy checks. |
 | 
			
		||||
| Privilege escalation during approvals | Approval gates require `Packs.Approve` + audit logging; fresh-auth recommended. |
 | 
			
		||||
| Secret exfiltration via pack steps | Secrets injection sandbox with redaction, sealed-mode network guardrails, evidence review. |
 | 
			
		||||
| Replay of old approval tokens | Approval payloads carry plan hash + expiry; Task Runner rejects mismatches. |
 | 
			
		||||
| Malicious pack in Offline Kit | Mirror verification using signed manifest and DSSE provenance. |
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 2 · Signing Requirements
 | 
			
		||||
 | 
			
		||||
- **Cosign** signatures required for all bundles. Keys can be:
 | 
			
		||||
  - Keyless (Fulcio OIDC).
 | 
			
		||||
  - KMS-backed (HSM, cloud KMS).
 | 
			
		||||
  - Offline keys stored in secure vault (air-gapped mode).
 | 
			
		||||
- **DSSE Attestations** recommended to embed:
 | 
			
		||||
  - Manifest digest.
 | 
			
		||||
  - Build metadata (repo, commit, CI run).
 | 
			
		||||
  - CLI version (`stella/pack`).
 | 
			
		||||
- Signatures stored alongside bundle in registry object storage.
 | 
			
		||||
- `stella pack push` refuses to publish without signature (unless `--insecure-publish` used in dev).
 | 
			
		||||
- Registry enforces trust policy:
 | 
			
		||||
 | 
			
		||||
| Policy | Description |
 | 
			
		||||
|--------|-------------|
 | 
			
		||||
| `anyOf` | Accepts any key in configured trust store. |
 | 
			
		||||
| `keyRef` | Accepts specific key ID (`kid`). |
 | 
			
		||||
| `oidcIssuer` | Accepts Fulcio certificates from allowed issuers (e.g., `https://fulcio.sigstore.dev`). |
 | 
			
		||||
| `threshold` | Requires N-of-M signatures (future release). |
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 3 · RBAC & Scopes
 | 
			
		||||
 | 
			
		||||
Authority exposes pack-related scopes:
 | 
			
		||||
 | 
			
		||||
| Scope | Description |
 | 
			
		||||
|-------|-------------|
 | 
			
		||||
| `Packs.Read` | View packs, download manifests/bundles. |
 | 
			
		||||
| `Packs.Write` | Publish, promote, deprecate packs. |
 | 
			
		||||
| `Packs.Run` | Execute packs (Task Runner, CLI). |
 | 
			
		||||
| `Packs.Approve` | Approve pack gates, override tenant visibility. |
 | 
			
		||||
 | 
			
		||||
### 3.1 Role Mapping
 | 
			
		||||
 | 
			
		||||
| Role | Scopes | Use Cases |
 | 
			
		||||
|------|--------|-----------|
 | 
			
		||||
| `pack.viewer` | `Packs.Read` | Inspect packs, plan runs. |
 | 
			
		||||
| `pack.publisher` | `Packs.Read`, `Packs.Write` | Publish new versions, manage channels. |
 | 
			
		||||
| `pack.operator` | `Packs.Read`, `Packs.Run` | Execute packs, monitor runs. |
 | 
			
		||||
| `pack.approver` | `Packs.Read`, `Packs.Approve` | Fulfil approvals, authorize promotions. |
 | 
			
		||||
| `pack.admin` | All | Full lifecycle management (rare). |
 | 
			
		||||
 | 
			
		||||
Roles are tenant-scoped; cross-tenant access requires explicit addition.
 | 
			
		||||
 | 
			
		||||
### 3.2 CLI Enforcement
 | 
			
		||||
 | 
			
		||||
- CLI requests scopes based on command:
 | 
			
		||||
  - `stella pack plan` → `Packs.Read`.
 | 
			
		||||
  - `stella pack run` → `Packs.Run`.
 | 
			
		||||
  - `stella pack push` → `Packs.Write`.
 | 
			
		||||
  - `stella pack approve` → `Packs.Approve`.
 | 
			
		||||
- Offline tokens must include same scopes; CLI warns if missing.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 4 · Approvals & Fresh Auth
 | 
			
		||||
 | 
			
		||||
- Approval commands require recent fresh-auth (< 5 minutes). CLI prompts automatically; Console enforces via Authority.
 | 
			
		||||
- Approval payload includes:
 | 
			
		||||
  - `runId`
 | 
			
		||||
  - `gateId`
 | 
			
		||||
  - `planHash`
 | 
			
		||||
  - `approver`
 | 
			
		||||
  - `timestamp`
 | 
			
		||||
- Task Runner logs approval event and verifies plan hash to prevent rerouting.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 5 · Secret Management
 | 
			
		||||
 | 
			
		||||
- Secrets defined in pack manifest map to Authority secret providers (e.g., HSM, Vault).
 | 
			
		||||
- Task Runner obtains secrets using service account with scoped access; CLI may prompt or read from profile.
 | 
			
		||||
- Secret audit trail:
 | 
			
		||||
  - `secretRequested` event with reason, pack, step.
 | 
			
		||||
  - `secretDelivered` event omitted (only aggregate metrics) to avoid leakage.
 | 
			
		||||
  - Evidence bundle includes hashed secret metadata (no values).
 | 
			
		||||
 | 
			
		||||
Sealed mode requires secrets to originate from sealed vault; external endpoints blocked.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 6 · Audit & Evidence
 | 
			
		||||
 | 
			
		||||
- Registry, Task Runner, and Authority emit audit events to central timeline.
 | 
			
		||||
- Required events:
 | 
			
		||||
  - `pack.version.published`
 | 
			
		||||
  - `pack.version.promoted`
 | 
			
		||||
  - `pack.run.started/completed`
 | 
			
		||||
  - `pack.approval.requested/granted`
 | 
			
		||||
  - `pack.secret.requested`
 | 
			
		||||
- Evidence Locker stores DSSE attestations and run bundles for 90 days (configurable).
 | 
			
		||||
- Auditors can use `stella pack audit --run <id>` to retrieve audit trail.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 7 · Offline / Air-Gap Policies
 | 
			
		||||
 | 
			
		||||
- Offline Kit includes:
 | 
			
		||||
  - Pack bundles + signatures.
 | 
			
		||||
  - Trusted key store (`trust-bundle.pem`).
 | 
			
		||||
  - Approval workflow instructions for manual signing.
 | 
			
		||||
- Air-gapped approvals:
 | 
			
		||||
  - CLI generates approval request file (`.approval-request.json`).
 | 
			
		||||
  - Approver uses offline CLI to sign with offline key.
 | 
			
		||||
  - Response imported to Task Runner.
 | 
			
		||||
- Mirror process verifies signatures prior to import; failure aborts import with `ERR_PACK_SIGNATURE_INVALID`.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 8 · Incident Response
 | 
			
		||||
 | 
			
		||||
- Compromised pack signature:
 | 
			
		||||
  - Revoke key via Authority trust store.
 | 
			
		||||
  - Deprecate affected versions (`registry deprecate`).
 | 
			
		||||
  - Notify consumers via Notifier (`pack.security.alert`).
 | 
			
		||||
  - Forensically review run evidence for impacted tenants.
 | 
			
		||||
- Unauthorized approval:
 | 
			
		||||
  - Review audit log for `Packs.Approve` events.
 | 
			
		||||
  - Trigger `pack.run.freeze` (pauses run pending investigation).
 | 
			
		||||
  - Rotate approver credentials and require fresh-auth.
 | 
			
		||||
- Secret leak suspicion:
 | 
			
		||||
  - Quarantine evidence bundles.
 | 
			
		||||
  - Rotate secrets referenced by pack.
 | 
			
		||||
  - Run sealed-mode audit script to confirm guardrails.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 9 · Compliance Checklist
 | 
			
		||||
 | 
			
		||||
- [ ] Signing requirements (cosign/DSSE, trust policies) documented.  
 | 
			
		||||
- [ ] Authority scope mapping and CLI enforcement captured.  
 | 
			
		||||
- [ ] Approval workflow + fresh-auth expectations defined.  
 | 
			
		||||
- [ ] Secret lifecycle (request, injection, audit) described.  
 | 
			
		||||
- [ ] Audit/evidence integration noted (timeline, Evidence Locker).  
 | 
			
		||||
- [ ] Offline/air-gap controls outlined.  
 | 
			
		||||
- [ ] Incident response playbook provided.  
 | 
			
		||||
- [ ] Imposed rule reminder retained at top.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
*Last updated: 2025-10-27 (Sprint 43).* 
 | 
			
		||||
 | 
			
		||||
@@ -21,16 +21,14 @@
 | 
			
		||||
| Scope | Description | Recommended role |
 | 
			
		||||
|-------|-------------|------------------|
 | 
			
		||||
| `policy:read` | View policies, revisions, runs, findings. | Readers, auditors. |
 | 
			
		||||
| `policy:write` | Create/edit drafts, run lint/compile. | Authors (SecOps engineers). |
 | 
			
		||||
| `policy:submit` | Move draft → submitted, attach simulations. | Authors with submission rights. |
 | 
			
		||||
| `policy:review` | Comment/approve/request changes (non-final). | Reviewers (peer security, product). |
 | 
			
		||||
| `policy:approve` | Final approval; can archive. | Approval board/security lead. |
 | 
			
		||||
| `policy:activate` | Promote approved version, schedule activation. | Runtime operators / release managers. |
 | 
			
		||||
| `policy:run` | Trigger runs, inspect live status. | Operators, automation bots. |
 | 
			
		||||
| `policy:runs` | Read run history, replay bundles. | Operators, auditors. |
 | 
			
		||||
| `policy:archive` | Retire versions, perform rollbacks. | Approvers, operators. |
 | 
			
		||||
| `policy:author` | Create/edit drafts, lint/compile, quick simulate. | `role/policy-author`. |
 | 
			
		||||
| `policy:review` | Comment, request changes, approve in-progress drafts. | `role/policy-reviewer`. |
 | 
			
		||||
| `policy:approve` | Final approval; archive decisions. | `role/policy-approver`. |
 | 
			
		||||
| `policy:operate` | Promote revisions, trigger runs, manage rollouts. | `role/policy-operator`, automation bots. |
 | 
			
		||||
| `policy:audit` | Access immutable history and evidence bundles. | `role/policy-auditor`, compliance teams. |
 | 
			
		||||
| `policy:simulate` | Execute simulations via API/CLI. | Authors, reviewers, CI. |
 | 
			
		||||
| `policy:operate` | Activate incident mode, toggle sampling. | SRE/on-call. |
 | 
			
		||||
| `policy:run` | Trigger runs, inspect live status. | Operators, automation bots. |
 | 
			
		||||
| `policy:activate` | Promote approved version, schedule activation. | Runtime operators / release managers. |
 | 
			
		||||
| `findings:read` | View effective findings/explain. | Analysts, auditors, CLI. |
 | 
			
		||||
| `effective:write` | **Service only** – materialise findings. | Policy Engine service principal. |
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user