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:
2025-10-28 09:58:55 +02:00
parent 4d932cc1ba
commit 4e3e575db5
501 changed files with 51904 additions and 6663 deletions

View File

@@ -6,7 +6,7 @@ schemaVersion: 1
issuer: "https://authority.localtest.me"
accessTokenLifetime: "00:15:00"
accessTokenLifetime: "00:02:00"
refreshTokenLifetime: "30.00:00:00"
identityTokenLifetime: "00:05:00"
authorizationCodeLifetime: "00:05:00"
@@ -61,6 +61,17 @@ clients:
type: "client_secret"
secretFile: "../secrets/policy-engine.secret"
- clientId: "policy-cli"
displayName: "Policy Automation CLI"
grantTypes: [ "client_credentials" ]
audiences: [ "api://policy-engine" ]
scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/policy-cli.secret"
- clientId: "cartographer-service"
displayName: "Cartographer Service"
grantTypes: [ "client_credentials" ]
@@ -84,6 +95,26 @@ clients:
auth:
type: "client_secret"
secretFile: "../secrets/graph-api.secret"
- clientId: "export-center-operator"
displayName: "Export Center Operator"
grantTypes: [ "client_credentials" ]
audiences: [ "api://export-center" ]
scopes: [ "export.viewer", "export.operator" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/export-center-operator.secret"
- clientId: "export-center-admin"
displayName: "Export Center Admin"
grantTypes: [ "client_credentials" ]
audiences: [ "api://export-center" ]
scopes: [ "export.viewer", "export.operator", "export.admin" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/export-center-admin.secret"
- clientId: "concelier-ingest"
displayName: "Concelier Ingestion"
@@ -118,6 +149,30 @@ clients:
type: "client_secret"
secretFile: "../secrets/graph-api-cli.secret"
tenants:
- name: "tenant-default"
roles:
orch-viewer:
scopes: [ "orch:read" ]
orch-operator:
scopes: [ "orch:read", "orch:operate" ]
export-viewer:
scopes: [ "export.viewer" ]
export-operator:
scopes: [ "export.viewer", "export.operator" ]
export-admin:
scopes: [ "export.viewer", "export.operator", "export.admin" ]
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" ]
security:
rateLimiting:
token:

View File

@@ -11,7 +11,7 @@ schemaVersion: 1
issuer: "https://authority.stella-ops.local"
# Token lifetimes expressed as HH:MM:SS or DD.HH:MM:SS.
accessTokenLifetime: "00:15:00"
accessTokenLifetime: "00:02:00"
refreshTokenLifetime: "30.00:00:00"
identityTokenLifetime: "00:05:00"
authorizationCodeLifetime: "00:05:00"
@@ -151,12 +151,39 @@ clients:
displayName: "Policy Automation CLI"
grantTypes: [ "client_credentials" ]
audiences: [ "api://policy-engine" ]
scopes: [ "policy:write", "policy:submit", "policy:run", "findings:read" ]
scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/policy-cli.secret"
- clientId: "exceptions-service"
displayName: "Policy Engine Exceptions Worker"
grantTypes: [ "client_credentials" ]
audiences: [ "api://policy-engine" ]
scopes: [ "exceptions:read", "exceptions:write" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/exceptions-service.secret"
- clientId: "console-web"
displayName: "StellaOps Console"
grantTypes: [ "authorization_code", "refresh_token" ]
audiences: [ "console" ]
scopes: [ "openid", "profile", "email", "ui.read", "authority:tenants.read", "advisory:read", "vex:read", "exceptions:read", "exceptions:approve", "aoc:verify", "findings:read", "orch:read", "vuln:read" ]
# exceptions:approve is elevated via fresh-auth and requires an MFA-capable identity provider.
tenant: "tenant-default"
senderConstraint: "dpop"
redirectUris:
- "https://console.stella-ops.local/oidc/callback"
postLogoutRedirectUris:
- "https://console.stella-ops.local/"
# Gateway must forward X-Stella-Tenant for /console endpoints; fresh-auth window (300s)
# returned by /console/profile governs admin actions in the Console UI.
auth:
type: "client_secret"
secretFile: "../secrets/console-web.secret"
- clientId: "cartographer-service"
displayName: "Cartographer Service"
grantTypes: [ "client_credentials" ]
@@ -179,6 +206,26 @@ clients:
auth:
type: "client_secret"
secretFile: "../secrets/graph-api.secret"
- clientId: "export-center-operator"
displayName: "Export Center Operator"
grantTypes: [ "client_credentials" ]
audiences: [ "api://export-center" ]
scopes: [ "export.viewer", "export.operator" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/export-center-operator.secret"
- clientId: "export-center-admin"
displayName: "Export Center Admin"
grantTypes: [ "client_credentials" ]
audiences: [ "api://export-center" ]
scopes: [ "export.viewer", "export.operator", "export.admin" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/export-center-admin.secret"
- clientId: "vuln-explorer-ui"
displayName: "Vuln Explorer UI"
grantTypes: [ "client_credentials" ]
@@ -189,6 +236,53 @@ clients:
auth:
type: "client_secret"
secretFile: "../secrets/vuln-explorer-ui.secret"
# Signals sensors must request aoc:verify alongside write scope.
- clientId: "signals-uploader"
displayName: "Signals Sensor"
grantTypes: [ "client_credentials" ]
audiences: [ "api://signals" ]
scopes: [ "signals:write", "signals:read", "aoc:verify" ]
tenant: "tenant-default"
senderConstraint: "dpop"
auth:
type: "client_secret"
secretFile: "../secrets/signals-uploader.secret"
tenants:
- name: "tenant-default"
roles:
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" ]
export-viewer:
scopes: [ "export.viewer" ]
export-operator:
scopes: [ "export.viewer", "export.operator" ]
export-admin:
scopes: [ "export.viewer", "export.operator", "export.admin" ]
# Exception approval routing templates used by Policy Engine and Console.
exceptions:
routingTemplates:
- id: "secops"
authorityRouteId: "approvals/secops"
requireMfa: true
description: "Security Operations approval chain"
- id: "governance"
authorityRouteId: "approvals/governance"
requireMfa: false
description: "Governance review (non-production)"
# CIDR ranges that bypass network-sensitive policies (e.g. on-host cron jobs).
# Keep the list tight: localhost is sufficient for most air-gapped installs.

View File

@@ -0,0 +1,39 @@
# StellaOps Policy Gateway configuration template.
# Copy to ../etc/policy-gateway.yaml (relative to the gateway content root)
# and adjust values to fit your environment. Environment variables prefixed with
# STELLAOPS_POLICY_GATEWAY_ override these values at runtime.
schemaVersion: 1
telemetry:
minimumLogLevel: Information
resourceServer:
authority: "https://authority.stella-ops.local"
metadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
audiences: [ "api://policy-gateway" ]
requiredScopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ]
requiredTenants: [ ]
bypassNetworks:
- "127.0.0.1/32"
- "::1/128"
requireHttpsMetadata: true
backchannelTimeoutSeconds: 30
tokenClockSkewSeconds: 60
policyEngine:
baseAddress: "https://policy-engine.stella-ops.local"
audience: "api://policy-engine"
clientCredentials:
enabled: true
clientId: "policy-gateway"
clientSecret: "change-me"
scopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ]
backchannelTimeoutSeconds: 30
dpop:
enabled: false
keyPath: "../etc/policy-gateway-dpop.pem"
keyPassphrase: ""
algorithm: "ES256"
proofLifetime: "00:02:00"
clockSkew: "00:00:30"

View File

@@ -0,0 +1,2 @@
# replace with a strong shared secret for the console-web client
console-web-secret-change-me

View File

@@ -0,0 +1,2 @@
# generated 2025-10-27T21:55:11Z via scripts/rotate-policy-cli-secret.sh
policy-cli-iOHhrE+K1sx+iyWQOd9pqYh0LwbXRauO/zdv0AeFUvLKAtZsc1wTIB5qZ8YIfKEo

28
etc/signals.yaml.sample Normal file
View File

@@ -0,0 +1,28 @@
# Signals service configuration template.
# Copy to ../etc/signals.yaml (relative to the Signals content root)
# and adjust values to fit your environment.
schemaVersion: 1
Signals:
Authority:
Enabled: true
Issuer: "https://authority.stella-ops.local"
AllowAnonymousFallback: false
Audiences:
- "api://signals"
RequiredTenants:
- "tenant-default"
RequiredScopes:
- "signals:read"
- "signals:write"
- "signals:admin"
BypassNetworks:
- "127.0.0.1/32"
- "::1/128"
Mongo:
ConnectionString: "mongodb://localhost:27017/signals"
Database: "signals"
CallgraphsCollection: "callgraphs"
Storage:
RootPath: "../data/signals-artifacts"