StellaOps Console Security Posture

Audience: Security Guild, Console & Authority teams, deployment engineers. Scope: OIDC/DPoP flows, scope model, session controls, CSP and transport headers, evidence handling, offline posture, and monitoring expectations for the StellaOps Console.

Related: Authority scopes (canonical scope catalogue) · Authority threat model (§8 maps console controls to its threats) · Authority rate limits.

The console is an Angular SPA fronted by the StellaOps Web gateway. It consumes Authority for identity, Concelier/Excititor for aggregation data, Policy Engine for findings, and Attestor for evidence bundles. This guide captures the security guarantees and required hardening so that the console can ship alongside the Aggregation-Only Contract (AOC) without introducing new attack surface.


1 · Identity & Authentication

1.1 Authorization sequence

  1. Browser→Authority uses OAuth 2.1 Authorization Code + PKCE (S256).
  2. Upon code exchange the console requests a DPoP-bound access token (aud=console, tenant=<id>) with 120 s TTL and optional rotating refresh token (rotate=true).
  3. Authority includes cnf.jkt for the ephemeral WebCrypto keypair; console stores the private key in IndexedDB (non-exportable) and keeps the public JWK in memory.
  4. All API calls attach Authorization: Bearer <token> + DPoP proof header. Nonces from the gateway are replay-protected (dpopt-nonce header).
  5. Tenanted API calls flow through the Web gateway which forwards X-StellaOps-TenantId and enforces tenancy headers. Missing or mismatched tenants trigger 403 with ERR_TENANT_MISMATCH.

1.2 Fresh-auth gating

1.3 Offline & sealed mode


2 · Session & Device Binding


3 · Authorization & Scope Model

The console client is registered in Authority as console-ui with scopes:

Feature areaRequired scopesNotes
Base navigation (Dashboard, Findings, SBOM, Runs)ui.read, findings:read, advisory:read, vex:read, aoc:verifyfindings:read enables Policy Engine overlays; advisory:read/vex:read load ingestion panes; aoc:verify allows on-demand guard runs.
Admin workspaceui.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.readScope combinations are tenant constrained. Role changes require fresh-auth.
Policy approvalspolicy:read, policy:review, policy:approve, policy:operate, policy:simulatepolicy:operate (promote/activate/run) requires fresh-auth.
Observability panes (status ticker, telemetry)ui.telemetry, scheduler:runs.read, advisory:read, vex:readui.telemetry drives OTLP export toggles.
Orchestrator dashboard (queues, workers, rate limits)orch:readProvision via Orch.Viewer role; read-only access to job state and telemetry.
Orchestrator control actions (pause/resume, retry, sync-now)orch:operate (plus orch:read)CLI/Console must request tokens with operator_reason and operator_ticket; Authority denies issuance when either value is missing.
Orchestrator backfill runsorch:backfill (plus orch:read, orch:operate)Backfill tokens require backfill_reason (≤256 chars) and backfill_ticket (≤128 chars); Authority stores both alongside operator metadata in audit events.
Orchestrator quota & burst controlsorch:quota (plus orch:read, orch:operate)Tokens must include quota_reason (≤256 chars); optional quota_ticket (≤128 chars) is captured for audit.
Downloads parity (SBOM, attestation)downloads:read, attestation:verify, sbom:exportConsole surfaces digests only; download links require CLI parity for write operations.

Guidance:


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-StellaOps-TenantId); 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.

EndpointRequired scopesPurposeNotes
GET /console/tenantsauthority:tenants.readReturns the tenant catalogue for the authenticated principal.Validates X-StellaOps-TenantId; rejects tenants not configured in Authority.
GET /console/profileui.readSurfaces 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/introspectui.readIntrospects 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.


4 · Transport, CSP & Browser Hardening

4.1 Gateway requirements

4.2 Content Security Policy

Default CSP served by the console container:

default-src 'self';
connect-src 'self' https://*.stella-ops.local http://*.stella-ops.local;
img-src 'self' data:;
script-src 'self';
style-src 'self' 'unsafe-inline';
font-src 'self';
frame-ancestors 'self';

Recommendations:

4.3 SSE & WebSocket hygiene


5 · Evidence & Data Handling


6 · Logging, Monitoring & Alerts


7 · Offline & Air-Gapped Posture


8 · Threat Model Alignment

Threat (Authority TM §5)Console control
Spoofed revocation bundleConsole verifies manifest signatures before showing revocation status; links to stella auth revoke verify.
Parameter tampering on /tokenPKCE + DPoP enforced; console propagates correlation IDs so Authority logs can link anomalies.
Bootstrap invite replayAdmin UI surfaces invite status with expiry; fresh-auth required before issuing new invites.
Token replay by stolen agentDPoP binding prevents reuse; console surfaces revocation latency warnings sourced from Zastava metrics.
Offline bundle tamperingConsole refuses unsigned Offline Kit assets; prompts operators to re-import verified bundles.
Privilege escalation via plug-in overridesPlug-in manifest viewer warns when a plug-in downgrades password policy; UI restricts plug-in activation to fresh-auth + ui.admin scoped users.

Document gaps and remediation hooks in SEC5.* backlog as they are addressed.


9 · Compliance checklist


Last updated: 2025-10-31 (Sprint 23).