Files
git.stella-ops.org/devops/compose/docker-compose.stella-ops.yml
master da76d6e93e Add topology auth policies + journey findings notes
Concelier:
- Register Topology.Read, Topology.Manage, Topology.Admin authorization
  policies mapped to OrchRead/OrchOperate/PlatformContextRead/IntegrationWrite
  scopes. Previously these policies were referenced by endpoints but never
  registered, causing System.InvalidOperationException on every topology
  API call.

Gateway routes:
- Simplified targets/environments routes (removed specific sub-path routes,
  use catch-all patterns instead)
- Changed environments base route to JobEngine (where CRUD lives)
- Changed to ReverseProxy type for all topology routes

KNOWN ISSUE (not yet fixed):
- ReverseProxy routes don't forward the gateway's identity envelope to
  Concelier. The regions/targets/bindings endpoints return 401 because
  hasPrincipal=False — the gateway authenticates the user but doesn't
  pass the identity to the backend via ReverseProxy. Microservice routes
  use Valkey transport which includes envelope headers. Topology endpoints
  need either: (a) Valkey transport registration in Concelier, or
  (b) Concelier configured to accept raw bearer tokens on ReverseProxy paths.
  This is an architecture-level fix.

Journey findings collected so far:
- Integration wizard (Harbor + GitHub App): works end-to-end
- Advisory Check All: fixed (parallel individual checks)
- Mirror domain creation: works, generate-immediately fails silently
- Topology wizard Step 1 (Region): blocked by auth passthrough issue
- Topology wizard Step 2 (Environment): POST to JobEngine needs verify
- User ID resolution: raw hashes shown everywhere

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 08:12:39 +02:00

2425 lines
98 KiB
YAML

# =============================================================================
# STELLA OPS - MAIN STACK
# =============================================================================
# Consolidated Docker Compose for the complete StellaOps platform.
# Infrastructure: PostgreSQL 18.1, Valkey 9.0.1, SeaweedFS (S3), Rekor v2, Zot (OCI)
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml up -d
#
# With Sigstore tools:
# docker compose -f devops/compose/docker-compose.stella-ops.yml --profile sigstore up -d
#
# With Telemetry:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.telemetry.yml up -d
#
# With Compliance overlay (e.g., China):
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-china.yml up -d
#
# =============================================================================
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0"
com.stellaops.release.channel: "stable"
com.stellaops.profile: "default"
x-postgres-connection: &postgres-connection
"Host=db.stella-ops.local;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
x-kestrel-cert: &kestrel-cert
Kestrel__Certificates__Default__Path: "/app/etc/certs/kestrel-dev.pfx"
Kestrel__Certificates__Default__Password: "devpass"
x-cert-volume: &cert-volume
"../../etc/authority/keys:/app/etc/certs:ro"
x-ca-bundle: &ca-bundle
"./combined-ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt:ro"
x-plugin-tmpfs: &plugin-tmpfs
/app/plugins:
mode: "1777"
x-router-microservice-defaults: &router-microservice-defaults
Router__Region: "local"
Router__Gateways__0__Host: "router.stella-ops.local"
Router__Gateways__0__Port: "9100"
Router__Gateways__0__TransportType: "Messaging"
Router__OnMissingAuthorization: "${ROUTER_ON_MISSING_AUTHORIZATION:-WarnAndAllow}"
Router__TransportPlugins__Directory: "/app/plugins/router/transports"
Router__TransportPlugins__SearchPattern: "StellaOps.Router.Transport.*.dll"
Router__Messaging__Transport: "valkey"
Router__Messaging__PluginDirectory: "/app/plugins/messaging"
Router__Messaging__SearchPattern: "StellaOps.Messaging.Transport.*.dll"
Router__Messaging__RequestQueueTemplate: "router:requests:{service}"
Router__Messaging__ResponseQueueName: "router:responses"
Router__Messaging__RequestTimeout: "30s"
Router__Messaging__LeaseDuration: "5m"
Router__Messaging__BatchSize: "10"
Router__Messaging__HeartbeatInterval: "10s"
Router__Messaging__valkey__ConnectionString: "cache.stella-ops.local:6379"
Router__Messaging__valkey__Database: "0"
Router__Messaging__valkey__QueueWaitTimeoutSeconds: "${VALKEY_QUEUE_WAIT_TIMEOUT:-0}"
# Identity envelope verification (signed by gateway, verified by services)
Router__IdentityEnvelopeSigningKey: "${STELLAOPS_IDENTITY_ENVELOPE_SIGNING_KEY}"
# ---------------------------------------------------------------------------
# Common anchors for the 60-service stack
# ---------------------------------------------------------------------------
x-depends-infra: &depends-infra
postgres:
condition: service_healthy
valkey:
condition: service_healthy
x-healthcheck-tcp: &healthcheck-tcp
interval: ${HEALTHCHECK_INTERVAL:-60s}
timeout: 5s
retries: 3
start_period: 15s
x-healthcheck-worker: &healthcheck-worker
test: ["CMD", "/usr/local/bin/healthcheck.sh"]
interval: ${HEALTHCHECK_INTERVAL:-60s}
timeout: 5s
start_period: 30s
retries: 3
# ---------------------------------------------------------------------------
# Resource limit tiers (Workstream 1: CPU optimization)
# ---------------------------------------------------------------------------
x-resources-heavy: &resources-heavy
deploy:
resources:
limits:
cpus: "1.0"
memory: 2G
x-resources-medium: &resources-medium
deploy:
resources:
limits:
cpus: "0.50"
memory: 1G
x-resources-light: &resources-light
deploy:
resources:
limits:
cpus: "0.25"
memory: 512M
# ---------------------------------------------------------------------------
# .NET GC tuning tiers (Workstream 6: GC configuration)
# ---------------------------------------------------------------------------
x-gc-heavy: &gc-heavy
DOTNET_gcServer: "1"
DOTNET_GCConserveMemory: "5"
DOTNET_GCDynamicAdaptationMode: "1"
x-gc-medium: &gc-medium
DOTNET_gcServer: "1"
DOTNET_GCConserveMemory: "7"
DOTNET_GCDynamicAdaptationMode: "1"
x-gc-light: &gc-light
DOTNET_gcServer: "0"
DOTNET_GCConserveMemory: "9"
DOTNET_GCDynamicAdaptationMode: "1"
networks:
stellaops:
driver: bridge
name: stellaops
frontdoor:
external: true
name: ${FRONTDOOR_NETWORK:-stellaops_frontdoor}
volumes:
postgres-data:
valkey-data:
rustfs-data:
rekor-tiles-data:
registry-data:
concelier-jobs:
scanner-surface-cache:
scanner-cache-data:
console-dist:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
evidence-data:
taskrunner-artifacts-data:
services:
# ===========================================================================
# INFRASTRUCTURE SERVICES
# ===========================================================================
postgres:
image: docker.io/library/postgres:18.1
container_name: stellaops-postgres
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d:ro
ports:
- "127.1.1.1:${POSTGRES_PORT:-5432}:5432"
networks:
stellaops:
aliases:
- db.stella-ops.local
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-stellaops} -d ${POSTGRES_DB:-stellaops_platform}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
container_name: stellaops-valkey
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "127.1.1.2:${VALKEY_PORT:-6379}:6379"
networks:
stellaops:
aliases:
- cache.stella-ops.local
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
rustfs:
image: chrislusf/seaweedfs:latest
container_name: stellaops-rustfs
command: ["server", "-s3", "-s3.port=8333", "-volume.port=8080", "-dir=/data"]
restart: unless-stopped
volumes:
- rustfs-data:/data
ports:
- "127.1.1.3:${RUSTFS_HTTP_PORT:-8333}:8333"
networks:
stellaops:
aliases:
- s3.stella-ops.local
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8333/status || exit 1"]
interval: 30s
timeout: 10s
retries: 3
labels: *release-labels
registry:
image: ghcr.io/project-zot/zot-linux-amd64:v2.1.3
container_name: stellaops-registry
restart: unless-stopped
volumes:
- registry-data:/var/lib/registry
- ./zot-config.json:/etc/zot/config.json:ro
ports:
- "127.1.1.5:80:5000"
networks:
stellaops:
aliases:
- registry.stella-ops.local
healthcheck:
disable: true
labels: *release-labels
rekor-v2:
image: ${REKOR_TILES_IMAGE:-ghcr.io/sigstore/rekor-tiles:latest}
container_name: stellaops-rekor
restart: on-failure:5
command:
- rekor-server
- serve
- --http-address
- 0.0.0.0
- --http-port
- "3322"
- --grpc-address
- 0.0.0.0
- --grpc-port
- "3323"
- --signer-filepath
- /etc/rekor/signer.pem
- --gcp-bucket
- ${REKOR_GCP_BUCKET:-stellaops-rekor-dev}
- --gcp-spanner
- ${REKOR_GCP_SPANNER:-projects/stellaops-dev/instances/rekor/databases/rekor}
volumes:
- rekor-tiles-data:/var/lib/rekor-tiles
- ../../etc/authority/keys/signing-dev.pem:/etc/rekor/signer.pem:ro
ports:
- "127.1.1.4:${REKOR_PORT:-3322}:3322"
networks:
stellaops:
aliases:
- rekor.stella-ops.local
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3322/api/v1/log"]
interval: 30s
timeout: 10s
retries: 3
profiles: ["sigstore-local"]
labels:
<<: *release-labels
com.stellaops.component: "rekor-v2"
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks: [stellaops]
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks: [stellaops]
labels: *release-labels
# ===========================================================================
# APPLICATION SERVICES (ordered by port-registry slot)
# ===========================================================================
# --- Console builder (init container) ---------------------------------------
console-builder:
image: stellaops/console:dev
container_name: stellaops-console-builder
user: "0:0"
entrypoint: ["sh", "-c"]
command: ["cp -r /usr/share/nginx/html/browser/* /output/ 2>/dev/null || cp -r /usr/share/nginx/html/* /output/"]
volumes:
- console-dist:/output
restart: "no"
networks:
- stellaops
# --- Slot 0: Router Gateway (Front Door) -----------------------------------
router-gateway:
<<: *resources-heavy
image: stellaops/router-gateway:dev
container_name: stellaops-router-gateway
restart: unless-stopped
depends_on:
<<: *depends-infra
console-builder:
condition: service_completed_successfully
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080;https://0.0.0.0:443"
<<: [*kestrel-cert, *gc-heavy]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Gateway__Auth__DpopEnabled: "false"
Gateway__Auth__Authority__Issuer: "https://authority.stella-ops.local/"
Gateway__Auth__Authority__RequireHttpsMetadata: "false"
Gateway__Auth__Authority__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Gateway__Auth__Authority__ClaimsOverridesUrl: "${ROUTER_AUTHORITY_CLAIMS_OVERRIDES_URL:-http://authority.stella-ops.local}"
Gateway__Transports__Messaging__Enabled: "${ROUTER_GATEWAY_MESSAGING_ENABLED:-true}"
Gateway__Transports__Messaging__transport: "valkey"
Gateway__Transports__Messaging__ConnectionString: "cache.stella-ops.local:6379"
Gateway__Transports__Messaging__Database: "0"
Gateway__Transports__Messaging__valkey__ConnectionString: "cache.stella-ops.local:6379"
Gateway__Transports__Messaging__valkey__Database: "0"
Gateway__Transports__Messaging__valkey__QueueWaitTimeoutSeconds: "${VALKEY_QUEUE_WAIT_TIMEOUT:-0}"
Gateway__Transports__Messaging__RequestQueueTemplate: "router:requests:{service}"
Gateway__Transports__Messaging__ResponseQueueName: "router:responses"
Gateway__Transports__Messaging__ConsumerGroup: "router-gateway"
Gateway__Transports__Messaging__RequestTimeout: "30s"
Gateway__Transports__Messaging__LeaseDuration: "5m"
Gateway__Transports__Messaging__BatchSize: "10"
Gateway__Transports__Messaging__HeartbeatInterval: "10s"
# Identity envelope signing (gateway -> microservice auth)
Gateway__Auth__IdentityEnvelopeSigningKey: "${STELLAOPS_IDENTITY_ENVELOPE_SIGNING_KEY}"
# Audience validation disabled until authority includes aud in access tokens
# Gateway__Auth__Authority__Audiences__0: "stella-ops-api"
# Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Information"
# Logging__LogLevel__Microsoft.IdentityModel: "Debug"
Logging__LogLevel__Microsoft.IdentityModel: "Information"
# Logging__LogLevel__StellaOps: "Debug"
Logging__LogLevel__StellaOps: "Information"
volumes:
- *cert-volume
- console-dist:/app/wwwroot:ro
- ${ROUTER_GATEWAY_CONFIG:-./router-gateway-local.json}:/app/appsettings.local.json:ro
- ./envsettings-override.json:/app/envsettings-override.json:ro
- ./gateway-ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt:ro
ports:
- "127.1.0.1:80:8080"
- "127.1.0.1:443:443"
networks:
stellaops:
aliases:
- router.stella-ops.local
- stella-ops.local
healthcheck:
test: ["CMD-SHELL", "bash -lc 'exec 3<>/dev/tcp/127.0.0.1/8080 && printf \"GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n\" >&3 && head -n 1 <&3 | grep -q \"200\"'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 1: Platform ------------------------------------------------------
platform:
<<: *resources-heavy
image: stellaops/platform:dev
container_name: stellaops-platform
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-heavy]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Platform__Authority__Issuer: "https://authority.stella-ops.local/"
Platform__Authority__RequireHttpsMetadata: "false"
Platform__Authority__BypassNetworks__0: "172.0.0.0/8"
Platform__Authority__BypassNetworks__1: "127.0.0.0/8"
Platform__Authority__BypassNetworks__2: "::1/128"
# Logging__LogLevel__StellaOps.Auth: "Debug"
Logging__LogLevel__StellaOps.Auth: "Information"
# Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Information"
# Logging__LogLevel__Microsoft.AspNetCore.Authorization: "Debug"
Logging__LogLevel__Microsoft.AspNetCore.Authorization: "Information"
Platform__Storage__Driver: "postgres"
Platform__Storage__PostgresConnectionString: *postgres-connection
Platform__EnvironmentSettings__AuthorizeEndpoint: "https://stella-ops.local/connect/authorize"
Platform__EnvironmentSettings__TokenEndpoint: "https://stella-ops.local/connect/token"
Platform__EnvironmentSettings__RedirectUri: "https://stella-ops.local/auth/callback"
Platform__EnvironmentSettings__PostLogoutRedirectUri: "https://stella-ops.local/"
Platform__EnvironmentSettings__Scope: "openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin"
STELLAOPS_ROUTER_URL: "http://router.stella-ops.local"
STELLAOPS_PLATFORM_URL: "http://platform.stella-ops.local"
STELLAOPS_AUTHORITY_URL: "http://authority.stella-ops.local"
STELLAOPS_GATEWAY_URL: "http://router.stella-ops.local"
STELLAOPS_ATTESTOR_URL: "http://attestor.stella-ops.local"
STELLAOPS_EVIDENCELOCKER_URL: "http://evidencelocker.stella-ops.local"
STELLAOPS_SCANNER_URL: "http://scanner.stella-ops.local"
STELLAOPS_CONCELIER_URL: "http://concelier.stella-ops.local"
STELLAOPS_EXCITITOR_URL: "http://excititor.stella-ops.local"
STELLAOPS_VEXHUB_URL: "http://vexhub.stella-ops.local"
STELLAOPS_VEXLENS_URL: "http://vexlens.stella-ops.local"
STELLAOPS_VULNEXPLORER_URL: "http://vulnexplorer.stella-ops.local"
STELLAOPS_POLICY_ENGINE_URL: "http://policy-engine.stella-ops.local"
STELLAOPS_POLICY_GATEWAY_URL: "http://policy-gateway.stella-ops.local"
STELLAOPS_RISKENGINE_URL: "http://riskengine.stella-ops.local"
STELLAOPS_JOBENGINE_URL: "http://jobengine.stella-ops.local"
STELLAOPS_TASKRUNNER_URL: "http://taskrunner.stella-ops.local"
STELLAOPS_SCHEDULER_URL: "http://scheduler.stella-ops.local"
STELLAOPS_GRAPH_URL: "http://graph.stella-ops.local"
STELLAOPS_CARTOGRAPHER_URL: "http://cartographer.stella-ops.local"
STELLAOPS_REACHGRAPH_URL: "http://reachgraph.stella-ops.local"
STELLAOPS_TIMELINEINDEXER_URL: "http://timelineindexer.stella-ops.local"
STELLAOPS_TIMELINE_URL: "http://timeline.stella-ops.local"
STELLAOPS_FINDINGS_LEDGER_URL: "http://findings.stella-ops.local"
STELLAOPS_DOCTOR_URL: "http://doctor.stella-ops.local"
STELLAOPS_OPSMEMORY_URL: "http://opsmemory.stella-ops.local"
STELLAOPS_NOTIFIER_URL: "http://notifier.stella-ops.local"
STELLAOPS_NOTIFY_URL: "http://notify.stella-ops.local"
STELLAOPS_SIGNER_URL: "http://signer.stella-ops.local"
STELLAOPS_SMREMOTE_URL: "http://smremote.stella-ops.local"
STELLAOPS_AIRGAP_CONTROLLER_URL: "http://airgap-controller.stella-ops.local"
STELLAOPS_AIRGAP_TIME_URL: "http://airgap-time.stella-ops.local"
STELLAOPS_PACKSREGISTRY_URL: "http://packsregistry.stella-ops.local"
STELLAOPS_REGISTRY_TOKENSERVICE_URL: "http://registry-token.stella-ops.local"
STELLAOPS_BINARYINDEX_URL: "http://binaryindex.stella-ops.local"
STELLAOPS_ISSUERDIRECTORY_URL: "http://issuerdirectory.stella-ops.local"
STELLAOPS_SYMBOLS_URL: "http://symbols.stella-ops.local"
STELLAOPS_SBOMSERVICE_URL: "http://sbomservice.stella-ops.local"
STELLAOPS_EXPORTCENTER_URL: "http://exportcenter.stella-ops.local"
STELLAOPS_REPLAY_URL: "http://replay.stella-ops.local"
STELLAOPS_INTEGRATIONS_URL: "http://integrations.stella-ops.local"
STELLAOPS_SIGNALS_URL: "http://signals.stella-ops.local"
STELLAOPS_ADVISORYAI_URL: "http://advisoryai.stella-ops.local"
STELLAOPS_UNKNOWNS_URL: "http://unknowns.stella-ops.local"
Router__Enabled: "${PLATFORM_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "platform"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.3:80:80"
networks:
stellaops:
aliases:
- platform.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 2: Authority -----------------------------------------------------
authority:
<<: *resources-heavy
image: stellaops/authority:dev
container_name: stellaops-authority
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
environment:
ASPNETCORE_URLS: "http://+:8440"
Kestrel__Certificates__Default__Path: "/app/etc/authority/keys/kestrel-dev.pfx"
Kestrel__Certificates__Default__Password: "devpass"
STELLAOPS_DISABLE_TRANSPORT_SECURITY: "true"
STELLAOPS_AUTHORITY_AUTHORITY__ACCESSTOKENLIFETIME: "00:30:00"
STELLAOPS_AUTHORITY_AUTHORITY__SCHEMAVERSION: "1"
STELLAOPS_AUTHORITY_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER:-http://authority.stella-ops.local}"
STELLAOPS_AUTHORITY_AUTHORITY__STORAGE__CONNECTIONSTRING: *postgres-connection
STELLAOPS_AUTHORITY_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "cache.stella-ops.local:6379"
STELLAOPS_AUTHORITY_AUTHORITY__SIGNING__ACTIVEKEYID: "dev-signing-key-1"
STELLAOPS_AUTHORITY_AUTHORITY__SIGNING__KEYPATH: "/app/etc/authority/keys/signing-dev.pem"
STELLAOPS_AUTHORITY_AUTHORITY__NOTIFICATIONS__ACKTOKENS__ACTIVEKEYID: "dev-ack-key-1"
STELLAOPS_AUTHORITY_AUTHORITY__NOTIFICATIONS__ACKTOKENS__KEYPATH: "/app/etc/authority/keys/ack-token-dev.pem"
STELLAOPS_AUTHORITY_AUTHORITY__NOTIFICATIONS__WEBHOOKS__ALLOWEDHOSTS__0: "notify.stella-ops.local"
STELLAOPS_AUTHORITY_AUTHORITY__NOTIFICATIONS__ESCALATION__SCOPE: "notify.escalate"
STELLAOPS_AUTHORITY_AUTHORITY__BOOTSTRAP__ENABLED: "${AUTHORITY_BOOTSTRAP_ENABLED:-true}"
STELLAOPS_AUTHORITY_AUTHORITY__BOOTSTRAP__APIKEY: "${AUTHORITY_BOOTSTRAP_APIKEY:-stellaops-dev-bootstrap-key}"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINDIRECTORIES__0: "/app"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority/plugins"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__Type: "standard"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__AssemblyName: "StellaOps.Authority.Plugin.Standard"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__Enabled: "true"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__TenantId: "demo-prod"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapUser__Username: "admin"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapUser__Password: "Admin@Stella2026!"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapUser__Roles__0: "admin"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__ClientId: "stella-ops-ui"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__DisplayName: "Stella Ops Console"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__AllowedGrantTypes: "authorization_code refresh_token"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__AllowedScopes: "openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__RedirectUris: "https://stella-ops.local/auth/callback https://stella-ops.local/auth/silent-refresh https://127.1.0.1/auth/callback https://127.1.0.1/auth/silent-refresh"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__PostLogoutRedirectUris: "https://stella-ops.local/ https://127.1.0.1/"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__RequirePkce: "true"
STELLAOPS_AUTHORITY_AUTHORITY__PLUGINS__DESCRIPTORS__standard__BootstrapClients__0__AllowPlainTextPkce: "false"
STELLAOPS_AUTHORITY_AUTHORITY__TENANTS__0__ID: "demo-prod"
STELLAOPS_AUTHORITY_AUTHORITY__TENANTS__0__DISPLAYNAME: "Demo Production"
STELLAOPS_AUTHORITY_AUTHORITY__TENANTS__0__STATUS: "active"
<<: [*router-microservice-defaults, *gc-heavy]
Router__Enabled: "${AUTHORITY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "authority"
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
ports:
- "127.1.0.4:80:80"
networks:
stellaops:
aliases:
- authority.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 3: (removed — Gateway consolidated into Router Gateway, slot 0) ---
# --- Slot 4: Attestor ------------------------------------------------------
attestor:
<<: *resources-light
image: stellaops/attestor:dev
container_name: stellaops-attestor
restart: unless-stopped
depends_on:
- signer
environment:
ASPNETCORE_URLS: "http://+:8442"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ATTESTOR_ATTESTOR__SIGNER__BASEURL: "http://signer.stella-ops.local"
ATTESTOR_ATTESTOR__POSTGRES__CONNECTIONSTRING: *postgres-connection
ConnectionStrings__Default: *postgres-connection
Router__Enabled: "${ATTESTOR_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "attestor"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.6:80:80"
networks:
stellaops:
aliases:
- attestor.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 5: Attestor TileProxy --------------------------------------------
attestor-tileproxy:
<<: *resources-light
image: stellaops/attestor-tileproxy:dev
container_name: stellaops-attestor-tileproxy
restart: unless-stopped
depends_on:
- attestor
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *gc-light]
TILE_PROXY__tile_proxy__UpstreamUrl: "https://rekor.sigstore.dev"
TILE_PROXY__tile_proxy__Origin: "stellaops-tileproxy"
TILE_PROXY__tile_proxy__Cache__BasePath: "/var/cache/stellaops/tiles"
TILE_PROXY__tile_proxy__Cache__MaxSizeGb: "1"
volumes:
- *cert-volume
tmpfs:
- /var/cache/stellaops/tiles:mode=1777
networks:
stellaops:
aliases:
- attestor-tileproxy.stella-ops.local
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/8080'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 6: Evidence Locker ------------------------------------------------
evidence-locker-web:
<<: *resources-light
image: stellaops/evidence-locker-web:dev
container_name: stellaops-evidence-locker-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
EvidenceLocker__Database__ConnectionString: *postgres-connection
EvidenceLocker__Database__ApplyMigrationsAtStartup: "true"
EvidenceLocker__ObjectStore__Kind: "FileSystem"
EvidenceLocker__ObjectStore__FileSystem__RootPath: "/data/evidence"
EvidenceLocker__ObjectStore__EnforceWriteOnce: "false"
EvidenceLocker__Signing__Enabled: "false"
EvidenceLocker__Signing__Algorithm: "ES256"
EvidenceLocker__Signing__KeyId: "dev-evidence-key"
EvidenceLocker__Quotas__MaxMaterialCount: "128"
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
EvidenceLocker__Authority__BaseUrl: "https://authority.stella-ops.local"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${EVIDENCELOCKER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "evidencelocker"
volumes:
- *cert-volume
- *ca-bundle
- evidence-data:/data/evidence
ports:
- "127.1.0.7:80:80"
networks:
stellaops:
aliases:
- evidencelocker.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
evidence-locker-worker:
<<: *resources-light
image: stellaops/evidence-locker-worker:dev
container_name: stellaops-evidence-locker-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
EvidenceLocker__Database__ConnectionString: *postgres-connection
EvidenceLocker__Database__ApplyMigrationsAtStartup: "true"
EvidenceLocker__ObjectStore__Kind: "FileSystem"
EvidenceLocker__ObjectStore__FileSystem__RootPath: "/data/evidence"
EvidenceLocker__ObjectStore__EnforceWriteOnce: "false"
EvidenceLocker__Signing__Enabled: "false"
EvidenceLocker__Signing__Algorithm: "ES256"
EvidenceLocker__Signing__KeyId: "dev-evidence-key"
EvidenceLocker__Quotas__MaxMaterialCount: "128"
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
volumes:
- *cert-volume
- evidence-data:/data/evidence
networks:
stellaops:
aliases:
- evidence-locker-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 8: Scanner -------------------------------------------------------
scanner-cache-init:
image: stellaops/scanner-worker:dev
container_name: stellaops-scanner-cache-init
restart: "no"
user: "0:0"
entrypoint:
- /bin/sh
- -lc
- |
mkdir -p /var/lib/stellaops/cache/scanner/layers /var/lib/stellaops/cache/scanner/cas &&
chown -R 10001:10001 /var/lib/stellaops/cache/scanner &&
chmod -R u+rwX,go-rwx /var/lib/stellaops/cache/scanner
volumes:
- scanner-cache-data:/var/lib/stellaops/cache/scanner
networks:
stellaops: {}
labels: *release-labels
scanner-web:
<<: *resources-heavy
image: stellaops/scanner-web:dev
container_name: stellaops-scanner-web
restart: unless-stopped
depends_on:
scanner-cache-init:
condition: service_completed_successfully
postgres:
condition: service_healthy
valkey:
condition: service_healthy
rustfs:
condition: service_healthy
environment:
ASPNETCORE_URLS: "http://+:8444"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-heavy]
SCANNER_SCANNER__PLUGINS__BASEDIRECTORY: "/tmp/stellaops"
SCANNER_SCANNER__STORAGE__DRIVER: "postgres"
SCANNER_SCANNER__STORAGE__DSN: *postgres-connection
SCANNER_SCANNER__STORAGE__COMMANDTIMEOUTSECONDS: "30"
SCANNER_SCANNER__STORAGE__HEALTHCHECKTIMEOUTSECONDS: "5"
SCANNER_SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER_SCANNER__ARTIFACTSTORE__ENDPOINT: "http://s3.stella-ops.local:8333"
SCANNER_SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER_SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER_SCANNER__QUEUE__DRIVER: "redis"
SCANNER_SCANNER__QUEUE__DSN: "cache.stella-ops.local:6379"
SCANNER_SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER_SCANNER__EVENTS__DRIVER: "redis"
SCANNER_SCANNER__EVENTS__DSN: "cache.stella-ops.local:6379"
SCANNER_SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER_SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER_SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER_SCANNER__CACHE__ROOTPATH: "/var/lib/stellaops/cache/scanner"
SCANNER_SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://s3.stella-ops.local:8333}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
SCANNER_SURFACE_CACHE_QUOTA_MB: "${SCANNER_SURFACE_CACHE_QUOTA_MB:-4096}"
SCANNER_SURFACE_PREFETCH_ENABLED: "${SCANNER_SURFACE_PREFETCH_ENABLED:-false}"
SCANNER_SURFACE_TENANT: "${SCANNER_SURFACE_TENANT:-default}"
SCANNER_SURFACE_FEATURES: "${SCANNER_SURFACE_FEATURES:-}"
SCANNER_SURFACE_SECRETS_PROVIDER: "${SCANNER_SURFACE_SECRETS_PROVIDER:-file}"
SCANNER_SURFACE_SECRETS_NAMESPACE: "${SCANNER_SURFACE_SECRETS_NAMESPACE:-}"
SCANNER_SURFACE_SECRETS_ROOT: "${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}"
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
Router__Enabled: "${SCANNER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "scanner"
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
- *cert-volume
- scanner-cache-data:/var/lib/stellaops/cache/scanner
tmpfs:
- /var/lib/stellaops/surface:mode=1777
ports:
- "127.1.0.8:80:80"
networks:
stellaops:
aliases:
- scanner.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
scanner-worker:
<<: *resources-heavy
image: stellaops/scanner-worker:dev
container_name: stellaops-scanner-worker
restart: unless-stopped
depends_on:
scanner-cache-init:
condition: service_completed_successfully
postgres:
condition: service_healthy
valkey:
condition: service_healthy
rustfs:
condition: service_healthy
environment:
<<: [*kestrel-cert, *gc-heavy]
# Scanner worker options
Scanner__Worker__Authority__Enabled: "false"
BinaryIndex__Enabled: "false"
# Scanner storage (Postgres + S3/RustFS object store)
ScannerStorage__Postgres__ConnectionString: *postgres-connection
ScannerStorage__Postgres__SchemaName: "scanner"
ScannerStorage__ObjectStore__Driver: "rustfs"
ScannerStorage__ObjectStore__BucketName: "scanner-artifacts"
ScannerStorage__ObjectStore__RustFs__BaseUrl: "http://s3.stella-ops.local:8333"
# Surface environment (read via Environment.GetEnvironmentVariable)
SCANNER_SURFACE_FS_ENDPOINT: "http://s3.stella-ops.local:8333"
SURFACE_FS_ENDPOINT: "http://s3.stella-ops.local:8333"
SCANNER_SURFACE_SECRETS_NAMESPACE: "stellaops"
SCANNER_SURFACE_SECRETS_PROVIDER: "file"
SCANNER_SURFACE_SECRETS_ROOT: "/var/lib/stellaops/surface"
SCANNER_SURFACE_VALIDATION_DISABLED: "true"
SCANNER_SCANNER__CACHE__ROOTPATH: "/var/lib/stellaops/cache/scanner"
# EPSS bundle source path (EpssBundleSource constructor)
EPSS_BUNDLE_PATH: "/app/epss"
volumes:
- *cert-volume
- scanner-cache-data:/var/lib/stellaops/cache/scanner
tmpfs:
- /var/lib/stellaops/surface:mode=1777
- /app/epss:mode=1777
networks:
stellaops:
aliases:
- scanner-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 9: Concelier -----------------------------------------------------
concelier:
<<: *resources-medium
image: stellaops/concelier:dev
container_name: stellaops-concelier
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
rustfs:
condition: service_healthy
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
CONCELIER_PLUGINS__BASEDIRECTORY: "/tmp/stellaops"
CONCELIER_POSTGRESSTORAGE__CONNECTIONSTRING: *postgres-connection
CONCELIER_POSTGRESSTORAGE__ENABLED: "true"
CONCELIER_MIRROR__ENABLED: "true"
CONCELIER_MIRROR__EXPORTROOT: "/var/lib/concelier/jobs/mirror-exports"
CONCELIER_MIRROR__ACTIVEEXPORTID: "latest"
CONCELIER_S3__ENDPOINT: "http://s3.stella-ops.local:8333"
CONCELIER_AUTHORITY__ENABLED: "true"
CONCELIER_AUTHORITY__ISSUER: "https://authority.stella-ops.local/"
CONCELIER_AUTHORITY__REQUIREHTTPSMETADATA: "false"
CONCELIER_AUTHORITY__METADATAADDRESS: "https://authority.stella-ops.local/.well-known/openid-configuration"
CONCELIER_AUTHORITY__BYPASSNETWORKS__0: "172.19.0.0/16"
CONCELIER_AUTHORITY__BYPASSNETWORKS__1: "172.20.0.0/16"
CONCELIER_AUTHORITY__BYPASSNETWORKS__2: "0.0.0.0/0"
CONCELIER_AUTHORITY__AUDIENCES__0: "stellaops"
CONCELIER_AUTHORITY__BASEURL: "https://authority.stella-ops.local"
CONCELIER_AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER_AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
Router__Enabled: "${CONCELIER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "concelier"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.9:80:80"
networks:
stellaops:
aliases:
- concelier.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 10: Excititor ----------------------------------------------------
excititor:
<<: *resources-medium
image: stellaops/excititor:dev
container_name: stellaops-excititor
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
# Postgres options (section: Postgres:Excititor)
Postgres__Excititor__ConnectionString: *postgres-connection
Postgres__Excititor__SchemaName: "vex"
Excititor__Concelier__BaseUrl: "http://concelier.stella-ops.local"
Excititor__Storage__Driver: "postgres"
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
# TenantAuthorityOptionsValidator requires BaseUrls dict with at least one entry
Excititor__Authority__BaseUrls__default: "https://authority.stella-ops.local"
# IssuerDirectoryClientOptions.Validate() requires BaseAddress
IssuerDirectory__Client__BaseAddress: "http://issuerdirectory.stella-ops.local"
Router__Enabled: "${EXCITITOR_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "excititor"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.10:80:80"
networks:
stellaops:
aliases:
- excititor.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
excititor-worker:
<<: *resources-medium
image: stellaops/excititor-worker:dev
container_name: stellaops-excititor-worker
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
environment:
<<: [*kestrel-cert, *gc-medium]
# Postgres options (section: Postgres:Excititor)
Postgres__Excititor__ConnectionString: *postgres-connection
Postgres__Excititor__SchemaName: "vex"
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Excititor__Concelier__BaseUrl: "http://concelier.stella-ops.local"
Excititor__Storage__Driver: "postgres"
Excititor__Worker__DisableConsensus: "true"
# TenantAuthorityOptionsValidator requires BaseUrls dict with at least one entry
Excititor__Authority__BaseUrls__default: "https://authority.stella-ops.local"
# IssuerDirectoryClientOptions.Validate() requires BaseAddress
IssuerDirectory__Client__BaseAddress: "http://issuerdirectory.stella-ops.local"
volumes:
- *cert-volume
- *ca-bundle
networks:
stellaops:
aliases:
- excititor-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 11: VexHub -------------------------------------------------------
vexhub-web:
<<: *resources-light
image: stellaops/vexhub-web:dev
container_name: stellaops-vexhub-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Postgres__ConnectionString: *postgres-connection
Postgres__SchemaName: "vexhub"
Router__Enabled: "${VEXHUB_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "vexhub"
volumes:
- *cert-volume
ports:
- "127.1.0.11:80:80"
networks:
stellaops:
aliases:
- vexhub.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 12: VexLens ------------------------------------------------------
vexlens-web:
<<: *resources-light
image: stellaops/vexlens-web:dev
container_name: stellaops-vexlens-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${VEXLENS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "vexlens"
volumes:
- *cert-volume
ports:
- "127.1.0.12:80:80"
networks:
stellaops:
aliases:
- vexlens.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 13: VulnExplorer (api) [src/Findings/StellaOps.VulnExplorer.Api] ---
api:
<<: *resources-light
image: stellaops/api:dev
container_name: stellaops-api
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${VULNEXPLORER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "vulnexplorer"
volumes:
- *cert-volume
ports:
- "127.1.0.13:80:80"
networks:
stellaops:
aliases:
- vulnexplorer.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 14: Policy Engine ------------------------------------------------
policy-engine:
<<: *resources-medium
image: stellaops/policy-engine:dev
container_name: stellaops-policy-engine
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
STELLAOPS_POLICY_ENGINE_Postgres__Policy__ConnectionString: *postgres-connection
STELLAOPS_POLICY_ENGINE_ConnectionStrings__Redis: "cache.stella-ops.local:6379"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__Authority: "https://authority.stella-ops.local/"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__RequireHttpsMetadata: "false"
# UI tokens in local compose currently carry scopes but no aud claim.
# Keep this empty and let Program.cs explicitly clear default audience lists.
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__Audiences__0: ""
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__RequiredScopes__0: "policy:read"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
STELLAOPS_POLICY_ENGINE_PolicyEngine__ResourceServer__BypassNetworks__2: "::1/128"
PolicyEngine__ResourceServer__Authority: "https://authority.stella-ops.local/"
PolicyEngine__ResourceServer__RequireHttpsMetadata: "false"
PolicyEngine__ResourceServer__Audiences__0: ""
PolicyEngine__ResourceServer__RequiredScopes__0: "policy:read"
PolicyEngine__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
PolicyEngine__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
PolicyEngine__ResourceServer__BypassNetworks__2: "::1/128"
# Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Information"
# Logging__LogLevel__Microsoft.IdentityModel: "Debug"
Logging__LogLevel__Microsoft.IdentityModel: "Information"
Router__Enabled: "${POLICY_ENGINE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "policy-engine"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.14:80:80"
networks:
stellaops:
aliases:
- policy-engine.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 15: Policy Gateway -----------------------------------------------
policy:
<<: *resources-medium
image: stellaops/policy:dev
container_name: stellaops-policy
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8084"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Postgres__Policy__ConnectionString: *postgres-connection
PolicyGateway__ResourceServer__Authority: "https://authority.stella-ops.local/"
PolicyGateway__ResourceServer__RequireHttpsMetadata: "false"
PolicyGateway__ResourceServer__Audiences__0: ""
PolicyGateway__ResourceServer__RequiredScopes__0: "policy:read"
PolicyGateway__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
# In local compose, callers should forward their own token. Disable fallback
# client-credentials to avoid 500s on invalid_scope when no Authorization header is present.
PolicyGateway__PolicyEngine__ClientCredentials__Enabled: "false"
# Bootstrap-prefixed vars (read by StellaOpsConfigurationBootstrapper before DI)
STELLAOPS_POLICY_GATEWAY_PolicyGateway__ResourceServer__Authority: "https://authority.stella-ops.local/"
STELLAOPS_POLICY_GATEWAY_PolicyGateway__ResourceServer__RequireHttpsMetadata: "false"
STELLAOPS_POLICY_GATEWAY_PolicyGateway__ResourceServer__Audiences__0: ""
STELLAOPS_POLICY_GATEWAY_PolicyGateway__ResourceServer__RequiredScopes__0: "policy:read"
STELLAOPS_POLICY_GATEWAY_PolicyGateway__PolicyEngine__ClientCredentials__Enabled: "false"
STELLAOPS_POLICY_GATEWAY_Postgres__Policy__ConnectionString: *postgres-connection
Router__Enabled: "${POLICY_GATEWAY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "policy-gateway"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.15:80:80"
networks:
stellaops:
aliases:
- policy-gateway.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 16: RiskEngine [src/Findings/StellaOps.RiskEngine.*] ---------------
riskengine-web:
<<: *resources-medium
image: stellaops/riskengine-web:dev
container_name: stellaops-riskengine-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
RISKENGINE__STORAGE__DRIVER: "postgres"
RISKENGINE__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
Router__Enabled: "${RISKENGINE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "riskengine"
volumes:
- *cert-volume
ports:
- "127.1.0.16:80:80"
networks:
stellaops:
aliases:
- riskengine.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
riskengine-worker:
<<: *resources-medium
image: stellaops/riskengine-worker:dev
container_name: stellaops-riskengine-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
volumes:
- *cert-volume
healthcheck:
<<: *healthcheck-worker
networks:
stellaops:
aliases:
- riskengine-worker.stella-ops.local
labels: *release-labels
# --- Slot 17: Orchestrator -------------------------------------------------
jobengine:
<<: *resources-heavy
image: stellaops/orchestrator:dev
container_name: stellaops-jobengine
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-heavy]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${ORCHESTRATOR_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "jobengine"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.17:80:80"
networks:
stellaops:
aliases:
- jobengine.stella-ops.local
- orchestrator.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
jobengine-worker:
<<: *resources-medium
image: stellaops/orchestrator-worker:dev
container_name: stellaops-jobengine-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
volumes:
- *cert-volume
healthcheck:
<<: *healthcheck-worker
networks:
stellaops:
aliases:
- jobengine-worker.stella-ops.local
labels: *release-labels
# --- Slot 18: TaskRunner ---------------------------------------------------
taskrunner-web:
<<: *resources-light
image: stellaops/taskrunner-web:dev
container_name: stellaops-taskrunner-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
TASKRUNNER__STORAGE__DRIVER: "postgres"
TASKRUNNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
TASKRUNNER__STORAGE__OBJECTSTORE__DRIVER: "seed-fs"
TASKRUNNER__STORAGE__OBJECTSTORE__SEEDFS__ROOTPATH: "/app/artifacts"
Router__Enabled: "${TASKRUNNER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "taskrunner"
volumes:
- *cert-volume
- taskrunner-artifacts-data:/app/artifacts
ports:
- "127.1.0.18:80:80"
networks:
stellaops:
aliases:
- taskrunner.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
taskrunner-worker:
<<: *resources-light
image: stellaops/taskrunner-worker:dev
container_name: stellaops-taskrunner-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
TASKRUNNER__STORAGE__DRIVER: "postgres"
TASKRUNNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
TASKRUNNER__STORAGE__OBJECTSTORE__DRIVER: "seed-fs"
TASKRUNNER__STORAGE__OBJECTSTORE__SEEDFS__ROOTPATH: "/app/artifacts"
# AirGap egress policy (disable for dev)
AirGap__Egress__Enabled: "false"
volumes:
- *cert-volume
tmpfs:
- /app/artifacts:mode=1777
- /app/queue:mode=1777
- /app/state:mode=1777
- /app/approvals:mode=1777
- /app/logs:mode=1777
networks:
stellaops:
aliases:
- taskrunner-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 19: Scheduler ----------------------------------------------------
scheduler-web:
<<: *resources-medium
image: stellaops/scheduler-web:dev
container_name: stellaops-scheduler-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Scheduler__Authority__Enabled: "false"
# Worker options are validated even in web mode
scheduler__queue__Kind: "Redis"
scheduler__queue__Redis__ConnectionString: "cache.stella-ops.local:6379"
Scheduler__Storage__Postgres__Scheduler__ConnectionString: *postgres-connection
Scheduler__Storage__Postgres__Scheduler__SchemaName: "scheduler"
Scheduler__Worker__Runner__Scanner__BaseAddress: "http://scanner.stella-ops.local"
Scheduler__Worker__Graph__Cartographer__BaseAddress: "http://cartographer.stella-ops.local"
Scheduler__Worker__Graph__SchedulerApi__BaseAddress: "http://scheduler.stella-ops.local"
Scheduler__Worker__Policy__Api__BaseAddress: "http://policy.stella-ops.local"
Router__Enabled: "${SCHEDULER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "scheduler"
volumes:
- *cert-volume
tmpfs:
- /plugins:mode=1777
ports:
- "127.1.0.19:80:80"
networks:
stellaops:
aliases:
- scheduler.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
scheduler-worker:
<<: *resources-medium
image: stellaops/scheduler-worker:dev
container_name: stellaops-scheduler-worker
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
environment:
<<: [*kestrel-cert, *gc-medium]
# Queue config (Redis transport)
scheduler__queue__Kind: "Redis"
scheduler__queue__Redis__ConnectionString: "cache.stella-ops.local:6379"
# Persistence config (section: Scheduler:Storage, subsection: Postgres:Scheduler)
Scheduler__Storage__Postgres__Scheduler__ConnectionString: *postgres-connection
Scheduler__Storage__Postgres__Scheduler__SchemaName: "scheduler"
# Worker config
Scheduler__Worker__Runner__Scanner__BaseAddress: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner.stella-ops.local}"
Scheduler__Worker__Graph__Cartographer__BaseAddress: "http://cartographer.stella-ops.local"
Scheduler__Worker__Graph__SchedulerApi__BaseAddress: "http://scheduler.stella-ops.local"
Scheduler__Worker__Policy__Api__BaseAddress: "http://policy.stella-ops.local"
# Surface environment
SURFACE_FS_ENDPOINT: "http://s3.stella-ops.local:8333"
volumes:
- *cert-volume
tmpfs:
- /var/lib/stellaops/surface:mode=1777
networks:
stellaops:
aliases:
- scheduler-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 20: Graph API ----------------------------------------------------
graph-api:
<<: *resources-medium
image: stellaops/graph-api:dev
container_name: stellaops-graph-api
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${GRAPH_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "graph"
volumes:
- *cert-volume
ports:
- "127.1.0.20:80:80"
networks:
stellaops:
aliases:
- graph.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 21: Cartographer -------------------------------------------------
cartographer:
<<: *resources-light
image: stellaops/cartographer:dev
container_name: stellaops-cartographer
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${CARTOGRAPHER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "cartographer"
volumes:
- *cert-volume
ports:
- "127.1.0.21:80:80"
networks:
stellaops:
aliases:
- cartographer.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 22: ReachGraph ---------------------------------------------------
reachgraph-web:
<<: *resources-light
image: stellaops/reachgraph-web:dev
container_name: stellaops-reachgraph-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${REACHGRAPH_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "reachgraph"
volumes:
- *cert-volume
ports:
- "127.1.0.22:80:80"
networks:
stellaops:
aliases:
- reachgraph.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 23: Timeline Indexer ---------------------------------------------
timeline-indexer-web:
<<: *resources-light
image: stellaops/timeline-indexer-web:dev
container_name: stellaops-timeline-indexer-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
TIMELINE_Postgres__Timeline__ConnectionString: *postgres-connection
Router__Enabled: "${TIMELINE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "timelineindexer"
volumes:
- *cert-volume
ports:
- "127.1.0.23:80:80"
networks:
stellaops:
aliases:
- timelineindexer.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
timeline-indexer-worker:
<<: *resources-light
image: stellaops/timeline-indexer-worker:dev
container_name: stellaops-timeline-indexer-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
TIMELINE_Postgres__Timeline__ConnectionString: *postgres-connection
volumes:
- *cert-volume
healthcheck:
<<: *healthcheck-worker
networks:
stellaops:
aliases:
- timeline-indexer-worker.stella-ops.local
labels: *release-labels
# --- Slot 24: Timeline ----------------------------------------------------
timeline-web:
<<: *resources-light
image: stellaops/timeline-web:dev
container_name: stellaops-timeline-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "http://authority.stella-ops.local/"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "172.20.0.0/16"
Router__Enabled: "${TIMELINE_SERVICE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "timeline"
volumes:
- *cert-volume
ports:
- "127.1.0.24:80:80"
networks:
stellaops:
aliases:
- timeline.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 25: Findings Ledger ----------------------------------------------
findings-ledger-web:
<<: *resources-medium
image: stellaops/findings-ledger-web:dev
container_name: stellaops-findings-ledger-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__FindingsLedger: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
findings__ledger__Database__ConnectionString: *postgres-connection
findings__ledger__Authority__Issuer: "https://authority.stella-ops.local/"
findings__ledger__Authority__RequireHttpsMetadata: "false"
# Local compose UI tokens may omit aud; keep audience validation relaxed.
findings__ledger__Authority__Audiences__0: ""
findings__ledger__Authority__RequiredScopes__0: "findings:read"
findings__ledger__Authority__BypassNetworks__0: "172.19.0.0/16"
# Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Information"
# Logging__LogLevel__Microsoft.IdentityModel: "Debug"
Logging__LogLevel__Microsoft.IdentityModel: "Information"
findings__ledger__Attachments__EncryptionKey: "IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI="
findings__ledger__Attachments__SignedUrlBase: "http://findings.stella-ops.local/attachments"
findings__ledger__Attachments__SignedUrlSecret: "dev-signed-url-secret"
findings__ledger__Attachments__SignedUrlLifetime: "00:15:00"
findings__ledger__Attachments__RequireConsoleCsrf: "false"
Router__Enabled: "${FINDINGS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "findings-ledger"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.25:80:80"
networks:
stellaops:
aliases:
- findings.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 26: Doctor -------------------------------------------------------
doctor-web:
<<: *resources-light
image: stellaops/doctor-web:dev
container_name: stellaops-doctor-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Doctor__Authority__Issuer: "https://authority.stella-ops.local/"
Doctor__Authority__RequireHttpsMetadata: "false"
Doctor__Authority__BypassNetworks__0: "172.19.0.0/16"
Router__Enabled: "${DOCTOR_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "doctor"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.26:80:80"
networks:
stellaops:
aliases:
- doctor.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
doctor-scheduler:
<<: *resources-light
image: stellaops/doctor-scheduler:dev
container_name: stellaops-doctor-scheduler
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:80"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${DOCTOR_SCHEDULER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "doctor-scheduler"
volumes:
- *cert-volume
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
networks:
stellaops:
aliases:
- doctor-scheduler.stella-ops.local
labels: *release-labels
# --- Slot 27: OpsMemory (src/AdvisoryAI/StellaOps.OpsMemory.WebService) ---
opsmemory-web:
<<: *resources-light
image: stellaops/opsmemory-web:dev
container_name: stellaops-opsmemory-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${OPSMEMORY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "opsmemory"
volumes:
- *cert-volume
ports:
- "127.1.0.27:80:80"
networks:
stellaops:
aliases:
- opsmemory.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 28: Notifier ----------------------------------------------------
notifier-web:
<<: *resources-medium
image: stellaops/notifier-web:dev
container_name: stellaops-notifier-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${NOTIFIER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "notifier"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.28:80:80"
networks:
stellaops:
aliases:
- notifier.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
notifier-worker:
<<: *resources-light
image: stellaops/notifier-worker:dev
container_name: stellaops-notifier-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
notifier__queue__Transport: "redis"
notifier__queue__Redis__ConnectionString: "cache.stella-ops.local:6379"
notifier__storage__postgres__ConnectionString: *postgres-connection
volumes:
- *cert-volume
healthcheck:
<<: *healthcheck-worker
networks:
stellaops:
aliases:
- notifier-worker.stella-ops.local
labels: *release-labels
# --- Slot 29: Notify ------------------------------------------------------
notify-web:
<<: *resources-medium
image: stellaops/notify-web:dev
container_name: stellaops-notify-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
DOTNET_ENVIRONMENT: Production
NOTIFY_NOTIFY__STORAGE__DRIVER: "postgres"
NOTIFY_NOTIFY__STORAGE__CONNECTIONSTRING: *postgres-connection
NOTIFY_NOTIFY__STORAGE__DATABASE: "notify"
NOTIFY_NOTIFY__PLUGINS__BASEDIRECTORY: "/tmp/stellaops"
NOTIFY_NOTIFY__AUTHORITY__ENABLED: "false"
NOTIFY_NOTIFY__AUTHORITY__ALLOWANONYMOUSFALLBACK: "true"
NOTIFY_NOTIFY__AUTHORITY__DEVELOPMENTSIGNINGKEY: "StellaOps-Development-Key-NotifyService-2026!!"
NOTIFY_Postgres__Notify__ConnectionString: *postgres-connection
Postgres__Notify__ConnectionString: *postgres-connection
Router__Enabled: "${NOTIFY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "notify"
volumes:
- ../../etc/notify:/app/etc/notify:ro
- *cert-volume
ports:
- "127.1.0.29:80:80"
networks:
stellaops:
aliases:
- notify.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 30: Signer ------------------------------------------------------
signer:
<<: *resources-light
image: stellaops/signer:dev
container_name: stellaops-signer
restart: unless-stopped
depends_on:
- authority
- valkey
environment:
ASPNETCORE_URLS: "http://+:8441"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__KeyManagement: *postgres-connection
ConnectionStrings__Default: *postgres-connection
Router__Enabled: "${SIGNER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "signer"
volumes:
- *cert-volume
ports:
- "127.1.0.30:80:80"
networks:
stellaops:
aliases:
- signer.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 31: SmRemote ----------------------------------------------------
smremote:
<<: *resources-light
image: stellaops/smremote:dev
container_name: stellaops-smremote
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${SMREMOTE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "smremote"
volumes:
- *cert-volume
ports:
- "127.1.0.31:80:80"
networks:
stellaops:
aliases:
- smremote.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/8080'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 32: AirGap Controller --------------------------------------------
airgap-controller:
<<: *resources-light
image: stellaops/airgap-controller:dev
container_name: stellaops-airgap-controller
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${AIRGAP_CONTROLLER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "airgap-controller"
volumes:
- *cert-volume
ports:
- "127.1.0.32:80:80"
networks:
stellaops:
aliases:
- airgap-controller.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 33: AirGap Time -------------------------------------------------
airgap-time:
<<: *resources-light
image: stellaops/airgap-time:dev
container_name: stellaops-airgap-time
restart: unless-stopped
profiles: ["airgap"] # Requires time anchor file - air-gap specific
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
Router__Enabled: "${AIRGAP_TIME_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "airgap-time"
volumes:
- *cert-volume
ports:
- "127.1.0.33:80:80"
networks:
stellaops:
aliases:
- airgap-time.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 34: PacksRegistry -----------------------------------------------
packsregistry-web:
<<: *resources-light
image: stellaops/packsregistry-web:dev
container_name: stellaops-packsregistry-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
PACKSREGISTRY__STORAGE__DRIVER: "postgres"
PACKSREGISTRY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
PACKSREGISTRY__STORAGE__OBJECTSTORE__DRIVER: "seed-fs"
PACKSREGISTRY__STORAGE__OBJECTSTORE__SEEDFS__ROOTPATH: "/app/data/packs"
Router__Enabled: "${PACKSREGISTRY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "packsregistry"
volumes:
- *cert-volume
ports:
- "127.1.0.34:80:80"
networks:
stellaops:
aliases:
- packsregistry.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
packsregistry-worker:
<<: *resources-light
image: stellaops/packsregistry-worker:dev
container_name: stellaops-packsregistry-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
volumes:
- *cert-volume
healthcheck:
<<: *healthcheck-worker
networks:
stellaops:
aliases:
- packsregistry-worker.stella-ops.local
labels: *release-labels
# --- Slot 35: Registry Token -----------------------------------------------
registry-token:
<<: *resources-light
image: stellaops/registry-token:dev
container_name: stellaops-registry-token
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
RegistryTokenService__Signing__Issuer: "http://registry-token.stella-ops.local"
RegistryTokenService__Signing__KeyPath: "/app/etc/certs/kestrel-dev.pfx"
RegistryTokenService__Signing__Lifetime: "00:05:00"
RegistryTokenService__Registry__Realm: "http://registry.stella-ops.local"
RegistryTokenService__Authority__Issuer: "https://authority.stella-ops.local/"
RegistryTokenService__Authority__Audience: "api://registry"
RegistryTokenService__Authority__RequireHttpsMetadata: "false"
RegistryTokenService__Plans__0__Name: "default"
RegistryTokenService__Plans__0__Repositories__0__Pattern: "*"
RegistryTokenService__Plans__0__Repositories__0__Actions__0: "pull"
RegistryTokenService__Plans__0__Repositories__0__Actions__1: "push"
Router__Enabled: "${REGISTRY_TOKEN_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "registry-token"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.35:80:80"
networks:
stellaops:
aliases:
- registry-token.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 36: BinaryIndex --------------------------------------------------
binaryindex-web:
<<: *resources-light
image: stellaops/binaryindex-web:dev
container_name: stellaops-binaryindex-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${BINARYINDEX_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "binaryindex"
volumes:
- *cert-volume
ports:
- "127.1.0.36:80:80"
networks:
stellaops:
aliases:
- binaryindex.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 37: Issuer Directory ---------------------------------------------
issuer-directory:
<<: *resources-light
image: stellaops/issuer-directory-web:dev
container_name: stellaops-issuer-directory
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ISSUERDIRECTORY__AUTHORITY__ENABLED: "true"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER:-http://authority.stella-ops.local}"
ISSUERDIRECTORY__AUTHORITY__AUDIENCES__0: "api://issuer-directory"
ISSUERDIRECTORY__AUTHORITY__REQUIREHTTPSMETADATA: "false"
ISSUERDIRECTORY__PERSISTENCE__PROVIDER: "Postgres"
ISSUERDIRECTORY__PERSISTENCE__POSTGRESCONNECTIONSTRING: *postgres-connection
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "false"
Router__Enabled: "${ISSUERDIRECTORY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "issuerdirectory"
volumes:
- ../../etc/issuer-directory:/app/etc/issuer-directory:ro
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.37:80:80"
networks:
stellaops:
aliases:
- issuerdirectory.stella-ops.local
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 38: Symbols ------------------------------------------------------
symbols:
<<: *resources-light
image: stellaops/symbols:dev
container_name: stellaops-symbols
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Router__Enabled: "${SYMBOLS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "symbols"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.38:80:80"
networks:
stellaops:
aliases:
- symbols.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 39: SbomService --------------------------------------------------
sbomservice:
<<: *resources-light
image: stellaops/sbomservice:dev
container_name: stellaops-sbomservice
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${SBOMSERVICE_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "sbomservice"
volumes:
- *cert-volume
ports:
- "127.1.0.39:80:80"
networks:
stellaops:
aliases:
- sbomservice.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 40: ExportCenter -------------------------------------------------
export:
<<: *resources-light
image: stellaops/export:dev
container_name: stellaops-export
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Export__AllowInMemoryRepositories: "true"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${EXPORTCENTER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "exportcenter"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.40:80:80"
networks:
stellaops:
aliases:
- exportcenter.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
export-worker:
<<: *resources-light
image: stellaops/export-worker:dev
container_name: stellaops-export-worker
restart: unless-stopped
depends_on: *depends-infra
environment:
<<: [*kestrel-cert, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Export__AllowInMemoryRepositories: "true"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
volumes:
- *cert-volume
- *ca-bundle
networks:
stellaops:
aliases:
- export-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 41: Replay -------------------------------------------------------
replay-web:
<<: *resources-light
image: stellaops/replay-web:dev
container_name: stellaops-replay-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
REPLAY__STORAGE__DRIVER: "postgres"
REPLAY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
REPLAY__STORAGE__OBJECTSTORE__DRIVER: "seed-fs"
REPLAY__STORAGE__OBJECTSTORE__SEEDFS__ROOTPATH: "/app/data/replay-snapshots"
Router__Enabled: "${REPLAY_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "replay"
volumes:
- *cert-volume
ports:
- "127.1.0.41:80:80"
networks:
stellaops:
aliases:
- replay.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 42: Integrations ------------------------------------------------
integrations-web:
<<: *resources-light
image: stellaops/integrations-web:dev
container_name: stellaops-integrations-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__IntegrationsDb: *postgres-connection
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${INTEGRATIONS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "integrations"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.42:80:80"
networks:
stellaops:
aliases:
- integrations.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 43: Zastava Webhook ----------------------------------------------
zastava-webhook:
<<: *resources-light
image: stellaops/zastava-webhook:dev
container_name: stellaops-zastava-webhook
restart: unless-stopped
depends_on:
authority:
condition: service_healthy
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *gc-light]
# Runtime authority (used by token provider for OIDC discovery)
zastava__runtime__authority__Issuer: "https://authority.stella-ops.local/"
zastava__runtime__authority__allowStaticTokenFallback: "true"
zastava__runtime__authority__staticTokenValue: "dev-bypass-token"
zastava__runtime__tenant: "default"
zastava__runtime__environment: "local"
# Webhook authority
zastava__webhook__authority__Issuer: "https://authority.stella-ops.local/"
zastava__webhook__authority__staticTokenValue: "dev-bypass-token"
# TLS (PFX from cert volume)
zastava__webhook__tls__mode: "Secret"
zastava__webhook__tls__pfxPath: "/app/etc/certs/kestrel-dev.pfx"
zastava__webhook__tls__pfxPassword: "devpass"
# Backend (scanner service)
zastava__webhook__backend__baseAddress: "http://scanner.stella-ops.local"
zastava__webhook__backend__allowInsecureHttp: "true"
volumes:
- *cert-volume
- *ca-bundle
networks:
stellaops:
aliases:
- zastava-webhook.stella-ops.local
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/8080'"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
labels: *release-labels
# --- Slot 44: Signals ------------------------------------------------------
signals:
<<: *resources-light
image: stellaops/signals:dev
container_name: stellaops-signals
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Authority__ResourceServer__Authority: "https://authority.stella-ops.local/"
Authority__ResourceServer__MetadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration"
Authority__ResourceServer__RequireHttpsMetadata: "false"
Authority__ResourceServer__Audiences__0: ""
Authority__ResourceServer__BypassNetworks__0: "172.19.0.0/16"
Authority__ResourceServer__BypassNetworks__1: "127.0.0.1/32"
Authority__ResourceServer__BypassNetworks__2: "::1/128"
Authority__ResourceServer__BypassNetworks__3: "0.0.0.0/0"
Authority__ResourceServer__BypassNetworks__4: "::/0"
Router__Enabled: "${SIGNALS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "signals"
volumes:
- *cert-volume
- *ca-bundle
ports:
- "127.1.0.43:80:80"
networks:
stellaops:
aliases:
- signals.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Slot 45: Advisory AI --------------------------------------------------
advisory-ai-web:
<<: *resources-medium
image: stellaops/advisory-ai-web:dev
container_name: stellaops-advisory-ai-web
restart: unless-stopped
depends_on:
- scanner-web
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-medium]
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner.stella-ops.local}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Adapters__Llm__Enabled: "${ADVISORY_AI_LLM_ADAPTERS_ENABLED:-true}"
ADVISORYAI__AdvisoryAI__LlmProviders__ConfigDirectory: "${ADVISORY_AI_LLM_PROVIDERS_DIRECTORY:-/app/etc/llm-providers}"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
ADVISORYAI__KnowledgeSearch__ConnectionString: *postgres-connection
ADVISORYAI__KnowledgeSearch__FindingsAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__FindingsAdapterBaseUrl: "http://scanner.stella-ops.local"
ADVISORYAI__KnowledgeSearch__VexAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__VexAdapterBaseUrl: "http://concelier.stella-ops.local"
ADVISORYAI__KnowledgeSearch__PolicyAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__PolicyAdapterBaseUrl: "http://policy-gateway.stella-ops.local"
Router__Enabled: "${ADVISORYAI_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "advisoryai"
ports:
- "127.1.0.44:80:80"
volumes:
- *cert-volume
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
stellaops:
aliases:
- advisoryai.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
advisory-ai-worker:
<<: *resources-medium
image: stellaops/advisory-ai-worker:dev
container_name: stellaops-advisory-ai-worker
restart: unless-stopped
depends_on:
- scanner-web
environment:
<<: [*kestrel-cert, *gc-medium]
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner.stella-ops.local}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/tmp/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/tmp/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/tmp/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
ADVISORYAI__KnowledgeSearch__ConnectionString: *postgres-connection
ADVISORYAI__KnowledgeSearch__FindingsAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__FindingsAdapterBaseUrl: "http://scanner.stella-ops.local"
ADVISORYAI__KnowledgeSearch__VexAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__VexAdapterBaseUrl: "http://concelier.stella-ops.local"
ADVISORYAI__KnowledgeSearch__PolicyAdapterEnabled: "true"
ADVISORYAI__KnowledgeSearch__PolicyAdapterBaseUrl: "http://policy-gateway.stella-ops.local"
volumes:
- *cert-volume
networks:
stellaops:
aliases:
- advisory-ai-worker.stella-ops.local
healthcheck:
<<: *healthcheck-worker
labels: *release-labels
# --- Slot 46: Unknowns ----------------------------------------------------
unknowns-web:
<<: *resources-light
image: stellaops/unknowns-web:dev
container_name: stellaops-unknowns-web
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:8080"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__UnknownsDb: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${UNKNOWNS_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "unknowns"
volumes:
- *cert-volume
ports:
- "127.1.0.45:80:80"
networks:
stellaops:
aliases:
- unknowns.stella-ops.local
frontdoor: {}
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
labels: *release-labels
# --- Console (Angular frontend) -------------------------------------------
# web-ui is replaced by router-gateway serving static files from console-dist volume.
# The console-builder init container copies Angular dist to the shared volume.