devops folders consolidate

This commit is contained in:
master
2026-01-25 23:27:41 +02:00
parent 6e687b523a
commit a50bbb38ef
334 changed files with 35079 additions and 5569 deletions

View File

@@ -26,17 +26,16 @@ POSTGRES_PASSWORD=ci_test_password
POSTGRES_DB=stellaops_test
# =============================================================================
# CACHE & MESSAGING
# CACHE & MESSAGING (Valkey)
# =============================================================================
# Valkey (Redis-compatible) - Port 6380 to avoid conflicts
# Valkey handles both caching and message queuing
VALKEY_CONNECTION_STRING="localhost:6380"
VALKEY_HOST=localhost
VALKEY_PORT=6380
# NATS JetStream - Port 4223 to avoid conflicts
#NATS_URL="nats://localhost:4223"
#NATS_HOST=localhost
#NATS_PORT=4223
# Queue broker using Valkey streams
QUEUE_BROKER="valkey://localhost:6380"
# =============================================================================
# MOCK CONTAINER REGISTRY

View File

@@ -1,150 +1,459 @@
# StellaOps Compose Profiles
# Stella Ops Docker Compose Profiles
These Compose bundles ship the minimum services required to exercise the scanner pipeline plus control-plane dependencies. Every profile is pinned to immutable image digests sourced from `deploy/releases/*.yaml` and is linted via `docker compose config` in CI.
Consolidated Docker Compose configuration for the StellaOps platform. All profiles use immutable image digests from `deploy/releases/*.yaml` and are validated via `docker compose config` in CI.
## Layout
## Quick Reference
| I want to... | Command |
|--------------|---------|
| Run the full platform | `docker compose -f docker-compose.stella-ops.yml up -d` |
| Add observability | `docker compose -f docker-compose.stella-ops.yml -f docker-compose.telemetry.yml up -d` |
| Run CI/testing infrastructure | `docker compose -f docker-compose.testing.yml --profile ci up -d` |
| Deploy with China compliance | See [China Compliance](#china-compliance-sm2sm3sm4) |
| Deploy with Russia compliance | See [Russia Compliance](#russia-compliance-gost) |
| Deploy with EU compliance | See [EU Compliance](#eu-compliance-eidas) |
---
## File Structure
### Core Stack Files
| File | Purpose |
|------|---------|
| `docker-compose.stella-ops.yml` | **Main stack**: PostgreSQL 18.1, Valkey 9.0.1, RustFS, Rekor v2, all StellaOps services |
| `docker-compose.telemetry.yml` | **Observability**: OpenTelemetry collector, Prometheus, Tempo, Loki |
| `docker-compose.testing.yml` | **CI/Testing**: Test databases, mock services, Gitea for integration tests |
| `docker-compose.dev.yml` | **Minimal dev infrastructure**: PostgreSQL, Valkey, RustFS only |
### Specialized Infrastructure
| File | Purpose |
|------|---------|
| `docker-compose.bsim.yml` | **BSim analysis**: PostgreSQL for Ghidra binary similarity corpus |
| `docker-compose.corpus.yml` | **Function corpus**: PostgreSQL for function behavior database |
| `docker-compose.sealed-ci.yml` | **Air-gapped CI**: Sealed testing environment with authority, signer, attestor |
| `docker-compose.telemetry-offline.yml` | **Offline observability**: Air-gapped Loki, Promtail, OTEL collector, Tempo, Prometheus |
### Regional Compliance Overlays
| File | Purpose | Jurisdiction |
|------|---------|--------------|
| `docker-compose.compliance-china.yml` | SM2/SM3/SM4 ShangMi crypto configuration | China (OSCCA) |
| `docker-compose.compliance-russia.yml` | GOST R 34.10-2012 crypto configuration | Russia (FSB) |
| `docker-compose.compliance-eu.yml` | eIDAS qualified trust services configuration | EU |
### Crypto Provider Overlays
| File | Purpose | Use Case |
|------|---------|----------|
| `docker-compose.crypto-sim.yml` | Universal crypto simulation | Testing without licensed crypto |
| `docker-compose.cryptopro.yml` | CryptoPro CSP (real GOST) | Production Russia deployments |
| `docker-compose.sm-remote.yml` | SM Remote service (real SM2) | Production China deployments |
### Additional Overlays
| File | Purpose | Use Case |
|------|---------|----------|
| `docker-compose.gpu.yaml` | NVIDIA GPU acceleration | Advisory AI inference with GPU |
| `docker-compose.cas.yaml` | Content Addressable Storage | Dedicated CAS with retention policies |
| `docker-compose.tile-proxy.yml` | Rekor tile caching proxy | Air-gapped Sigstore deployments |
### Supporting Files
| Path | Purpose |
| ---- | ------- |
| `docker-compose.dev.yaml` | Edge/nightly stack tuned for laptops and iterative work. |
| `docker-compose.stage.yaml` | Stable channel stack mirroring pre-production clusters. |
| `docker-compose.prod.yaml` | Production cutover stack with front-door network hand-off and Notify events enabled. |
| `docker-compose.airgap.yaml` | Stable stack with air-gapped defaults (no outbound hostnames). |
| `docker-compose.mirror.yaml` | Managed mirror topology for `*.stella-ops.org` distribution (Concelier + Excititor + CDN gateway). |
| `docker-compose.rekor-v2.yaml` | Rekor v2 tiles overlay (MySQL-free) for bundled transparency logs. |
| `docker-compose.telemetry.yaml` | Optional OpenTelemetry collector overlay (mutual TLS, OTLP ingest endpoints). |
| `docker-compose.telemetry-storage.yaml` | Prometheus/Tempo/Loki storage overlay with multi-tenant defaults. |
| `docker-compose.gpu.yaml` | Optional GPU overlay enabling NVIDIA devices for Advisory AI web/worker. Apply with `-f docker-compose.<env>.yaml -f docker-compose.gpu.yaml`. |
| `env/*.env.example` | Seed `.env` files that document required secrets and ports per profile. |
| `scripts/backup.sh` | Pauses workers and creates tar.gz of Mongo/MinIO/Valkey volumes (deterministic snapshot). |
| `scripts/reset.sh` | Stops the stack and removes Mongo/MinIO/Valkey volumes after explicit confirmation. |
| `scripts/quickstart.sh` | Helper to validate config and start dev stack; set `USE_MOCK=1` to include `docker-compose.mock.yaml` overlay. |
| `docker-compose.mock.yaml` | Dev-only overlay with placeholder digests for missing services (orchestrator, policy-registry, packs, task-runner, VEX/Vuln stack). Use only with mock release manifest `deploy/releases/2025.09-mock-dev.yaml`. |
|------|---------|
| `env/*.env.example` | Environment variable templates per profile |
| `scripts/backup.sh` | Create deterministic volume snapshots |
| `scripts/reset.sh` | Stop stack and remove volumes (with confirmation) |
## Usage
---
## Usage Patterns
### Basic Development
```bash
cp env/dev.env.example dev.env
docker compose --env-file dev.env -f docker-compose.dev.yaml config
docker compose --env-file dev.env -f docker-compose.dev.yaml up -d
# Copy environment template
cp env/stellaops.env.example .env
# Validate configuration
docker compose -f docker-compose.stella-ops.yml config
# Start the platform
docker compose -f docker-compose.stella-ops.yml up -d
# View logs
docker compose -f docker-compose.stella-ops.yml logs -f scanner-web
```
The stage and airgap variants behave the same way—swap the file names accordingly. All profiles expose 443/8443 for the UI and REST APIs, and they share a `stellaops` Docker network scoped to the compose project.
### Rekor v2 overlay (tiles)
Use the overlay below and set the Rekor env vars in your `.env` file (see
`env/dev.env.example`):
```bash
docker compose --env-file dev.env \
-f docker-compose.dev.yaml \
-f docker-compose.rekor-v2.yaml \
--profile sigstore up -d
```
> **Surface.Secrets:** set `SCANNER_SURFACE_SECRETS_PROVIDER`/`SCANNER_SURFACE_SECRETS_ROOT` in your `.env` and point `SURFACE_SECRETS_HOST_PATH` to the decrypted bundle path (default `./offline/surface-secrets`). The stack mounts that path read-only into Scanner Web/Worker so `secret://` references resolve without embedding plaintext.
> **Graph Explorer reminder:** If you enable Cartographer or Graph API containers alongside these profiles, update `etc/authority.yaml` so the `cartographer-service` client is marked with `properties.serviceIdentity: "cartographer"` and carries a tenant hint. The Authority host now refuses `graph:write` tokens without that marker, so apply the configuration change before rolling out the updated images.
### Telemetry collector overlay
The OpenTelemetry collector overlay is optional and can be layered on top of any profile:
### With Observability
```bash
# Generate TLS certificates for telemetry
./ops/devops/telemetry/generate_dev_tls.sh
docker compose -f docker-compose.telemetry.yaml up -d
python ../../ops/devops/telemetry/smoke_otel_collector.py --host localhost
docker compose -f docker-compose.telemetry-storage.yaml up -d
# Start platform with telemetry
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.telemetry.yml up -d
```
The generator script creates a development CA plus server/client certificates under
`deploy/telemetry/certs/`. The smoke test sends OTLP/HTTP payloads using the generated
client certificate and asserts the collector reports accepted traces, metrics, and logs.
The storage overlay starts Prometheus, Tempo, and Loki with multitenancy enabled so you
can validate the end-to-end pipeline before promoting changes to staging. Adjust the
configs in `deploy/telemetry/storage/` before running in production.
Mount the same certificates when running workloads so the collector can enforce mutual TLS.
For production cutovers copy `env/prod.env.example` to `prod.env`, update the secret placeholders, and create the external network expected by the profile:
### CI/Testing Infrastructure
```bash
# Start CI infrastructure only (different ports to avoid conflicts)
docker compose -f docker-compose.testing.yml --profile ci up -d
# Start mock services for integration testing
docker compose -f docker-compose.testing.yml --profile mock up -d
# Start Gitea for SCM integration tests
docker compose -f docker-compose.testing.yml --profile gitea up -d
# Start everything
docker compose -f docker-compose.testing.yml --profile all up -d
```
**Test Infrastructure Ports:**
| Service | Port | Purpose |
|---------|------|---------|
| postgres-test | 5433 | PostgreSQL 18 for tests |
| valkey-test | 6380 | Valkey for cache/queue tests |
| rustfs-test | 8180 | S3-compatible storage |
| mock-registry | 5001 | Container registry mock |
| gitea | 3000 | Git hosting for SCM tests |
---
## Regional Compliance Deployments
### China Compliance (SM2/SM3/SM4)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production (real SM crypto):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.sm-remote.yml up -d
```
**With OSCCA-certified HSM:**
```bash
# Set HSM connection details in environment
export SM_REMOTE_HSM_URL="https://sm-hsm.example.com:8900"
export SM_REMOTE_HSM_API_KEY="your-api-key"
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.sm-remote.yml up -d
```
**Algorithms:**
- SM2: Public key cryptography (GM/T 0003-2012)
- SM3: Hash function, 256-bit (GM/T 0004-2012)
- SM4: Block cipher, 128-bit (GM/T 0002-2012)
---
### Russia Compliance (GOST)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-russia.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production (CryptoPro CSP):**
```bash
# CryptoPro requires EULA acceptance
CRYPTOPRO_ACCEPT_EULA=1 docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-russia.yml \
-f docker-compose.cryptopro.yml up -d
```
**Requirements for CryptoPro:**
- CryptoPro CSP license files in `opt/cryptopro/downloads/`
- `CRYPTOPRO_ACCEPT_EULA=1` environment variable
- Valid CryptoPro container images
**Algorithms:**
- GOST R 34.10-2012: Digital signature (256/512-bit)
- GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
- GOST R 34.12-2015: Block cipher (Kuznyechik, Magma)
---
### EU Compliance (eIDAS)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-eu.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production:**
EU eIDAS deployments typically integrate with external Qualified Trust Service Providers (QTSPs) rather than hosting crypto locally. Configure your QTSP integration in the application settings.
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-eu.yml up -d
```
**Standards:**
- ETSI TS 119 312 compliant algorithms
- Qualified electronic signatures
- QTSP integration for qualified trust services
---
## Crypto Simulation Details
The `docker-compose.crypto-sim.yml` overlay provides a unified simulation service for all sovereign crypto profiles:
| Algorithm ID | Simulation | Use Case |
|--------------|------------|----------|
| `SM2`, `sm.sim` | HMAC-SHA256 | China testing |
| `GOST12-256`, `GOST12-512` | HMAC-SHA256 | Russia testing |
| `ru.magma.sim`, `ru.kuznyechik.sim` | HMAC-SHA256 | Russia testing |
| `DILITHIUM3`, `FALCON512`, `pq.sim` | HMAC-SHA256 | Post-quantum testing |
| `fips.sim`, `eidas.sim`, `kcmvp.sim` | ECDSA P-256 | FIPS/EU/Korea testing |
**Important:** Simulation is for testing only. Uses deterministic HMAC or static ECDSA keys—not suitable for production or compliance certification.
---
## Configuration Reference
### Infrastructure Services
| Service | Default Port | Purpose |
|---------|--------------|---------|
| PostgreSQL | 5432 | Primary database |
| Valkey | 6379 | Cache, queues, events |
| RustFS | 8080 | S3-compatible artifact storage |
| Rekor v2 | (internal) | Sigstore transparency log |
### Application Services
| Service | Default Port | Purpose |
|---------|--------------|---------|
| Authority | 8440 | OAuth2/OIDC identity provider |
| Signer | 8441 | Cryptographic signing |
| Attestor | 8442 | SLSA attestation |
| Scanner Web | 8444 | SBOM/vulnerability scanning API |
| Concelier | 8445 | Advisory aggregation |
| Notify Web | 8446 | Notification service |
| Issuer Directory | 8447 | CSAF publisher registry |
| Advisory AI Web | 8448 | AI-powered advisory analysis |
| Web UI | 8443 | Angular frontend |
### Environment Variables
Key variables (see `env/*.env.example` for complete list):
```bash
# Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=<secret>
POSTGRES_DB=stellaops_platform
# Authority
AUTHORITY_ISSUER=https://authority.example.com
# Scanner
SCANNER_EVENTS_ENABLED=false
SCANNER_OFFLINEKIT_ENABLED=false
# Crypto (for compliance overlays)
STELLAOPS_CRYPTO_PROFILE=default # or: china, russia, eu
STELLAOPS_CRYPTO_ENABLE_SIM=0 # set to 1 for simulation
# CryptoPro (Russia only)
CRYPTOPRO_ACCEPT_EULA=0 # must be 1 to use CryptoPro
# SM Remote (China only)
SM_SOFT_ALLOWED=1 # software-only SM2
SM_REMOTE_HSM_URL= # optional: OSCCA-certified HSM
```
---
## Networking
All profiles use a shared `stellaops` Docker network. Production deployments can attach a `frontdoor` network for reverse proxy integration:
```bash
# Create external network for load balancer
docker network create stellaops_frontdoor
docker compose --env-file prod.env -f docker-compose.prod.yaml config
# Set in environment
export FRONTDOOR_NETWORK=stellaops_frontdoor
```
### Scanner event stream settings
Only externally-reachable services (Authority, Signer, Attestor, Concelier, Scanner Web, Notify Web, UI) attach to the frontdoor network. Infrastructure services (PostgreSQL, Valkey, RustFS) remain on the private network.
Scanner WebService can emit signed `scanner.report.*` events to Redis Streams when `SCANNER__EVENTS__ENABLED=true`. Each profile ships environment placeholders you can override in the `.env` file:
---
- `SCANNER_EVENTS_ENABLED` toggle emission on/off (defaults to `false`).
- `SCANNER_EVENTS_DRIVER` currently only `redis` is supported.
- `SCANNER_EVENTS_DSN` Redis endpoint; leave blank to reuse the queue DSN when it uses `redis://`.
- `SCANNER_EVENTS_STREAM` stream name (`stella.events` by default).
- `SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS` per-publish timeout window (defaults to `5`).
- `SCANNER_EVENTS_MAX_STREAM_LENGTH` max stream length before Redis trims entries (defaults to `10000`).
## Sigstore Tools
Helm values mirror the same knobs under each services `env` map (see `deploy/helm/stellaops/values-*.yaml`).
### Scheduler worker configuration
Every Compose profile now provisions the `scheduler-worker` container (backed by the
`StellaOps.Scheduler.Worker.Host` entrypoint). The environment placeholders exposed
in the `.env` samples match the options bound by `AddSchedulerWorker`:
- `SCHEDULER_QUEUE_KIND` queue transport (`Nats` or `Redis`).
- `SCHEDULER_QUEUE_NATS_URL` NATS connection string used by planner/runner consumers.
- `SCHEDULER_STORAGE_DATABASE` PostgreSQL database name for scheduler state.
- `SCHEDULER_SCANNER_BASEADDRESS` base URL the runner uses when invoking Scanners
`/api/v1/reports` (defaults to the in-cluster `http://scanner-web:8444`).
Helm deployments inherit the same defaults from `services.scheduler-worker.env` in
`values.yaml`; override them per environment as needed.
### Advisory AI configuration
`advisory-ai-web` hosts the API/plan cache while `advisory-ai-worker` executes queued tasks. Both containers mount the shared volumes (`advisory-ai-queue`, `advisory-ai-plans`, `advisory-ai-outputs`) so they always read/write the same deterministic state. New environment knobs:
- `ADVISORY_AI_SBOM_BASEADDRESS` endpoint the SBOM context client hits (defaults to the in-cluster Scanner URL).
- `ADVISORY_AI_INFERENCE_MODE` `Local` (default) keeps inference on-prem; `Remote` posts sanitized prompts to the URL supplied via `ADVISORY_AI_REMOTE_BASEADDRESS`. Optional `ADVISORY_AI_REMOTE_APIKEY` carries the bearer token when remote inference is enabled.
- `ADVISORY_AI_WEB_PORT` host port for `advisory-ai-web`.
The Helm chart mirrors these settings under `services.advisory-ai-web` / `advisory-ai-worker` and expects a PVC named `stellaops-advisory-ai-data` so both deployments can mount the same RWX volume.
### Front-door network hand-off
`docker-compose.prod.yaml` adds a `frontdoor` network so operators can attach Traefik, Envoy, or an on-prem load balancer that terminates TLS. Override `FRONTDOOR_NETWORK` in `prod.env` if your reverse proxy uses a different bridge name. Attach only the externally reachable services (Authority, Signer, Attestor, Concelier, Scanner Web, Notify Web, UI) to that network—internal infrastructure (Mongo, MinIO, RustFS, NATS) stays on the private `stellaops` network.
### Updating to a new release
1. Import the new manifest into `deploy/releases/` (see `deploy/README.md`).
2. Update image digests in the relevant Compose file(s).
3. Re-run `docker compose config` to confirm the bundle is deterministic.
### Mock overlay for missing digests (dev only)
Until official digests land, you can exercise Compose packaging with mock placeholders:
Enable Sigstore CLI tools (rekor-cli, cosign) with the `sigstore` profile:
```bash
# assumes docker-compose.dev.yaml as the base profile
USE_MOCK=1 ./scripts/quickstart.sh env/dev.env.example
docker compose -f docker-compose.stella-ops.yml --profile sigstore up -d
```
The overlay pins the missing services (orchestrator, policy-registry, packs-registry, task-runner, VEX/Vuln stack) to mock digests from `deploy/releases/2025.09-mock-dev.yaml` and starts their real entrypoints so integration flows can be exercised end-to-end. Replace the mock pins with production digests once releases publish; keep the mock overlay dev-only.
---
Keep digests synchronized between Compose, Helm, and the release manifest to preserve reproducibility guarantees. `deploy/tools/validate-profiles.sh` performs a quick audit.
## GPU Support for Advisory AI
### GPU toggle for Advisory AI
GPU is disabled by default. To run inference on NVIDIA GPUs:
GPU is disabled by default. To enable NVIDIA GPU inference:
```bash
docker compose \
--env-file prod.env \
-f docker-compose.prod.yaml \
-f docker-compose.gpu.yaml \
up -d
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.gpu.yaml up -d
```
The GPU overlay requests one GPU for `advisory-ai-worker` and `advisory-ai-web` and sets `ADVISORY_AI_INFERENCE_GPU=true`. Ensure the host has the NVIDIA container runtime and that the base compose file still sets the correct digests.
**Requirements:**
- NVIDIA GPU with CUDA support
- nvidia-container-toolkit installed
- Docker configured with nvidia runtime
---
## Content Addressable Storage (CAS)
The CAS overlay provides dedicated RustFS instances with retention policies for different artifact types:
```bash
# Standalone CAS infrastructure
docker compose -f docker-compose.cas.yaml up -d
# Combined with main stack
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.cas.yaml up -d
```
**CAS Services:**
| Service | Port | Purpose |
|---------|------|---------|
| rustfs-cas | 8180 | Runtime facts, signals, replay artifacts |
| rustfs-evidence | 8181 | Merkle roots, hash chains, evidence bundles (immutable) |
| rustfs-attestation | 8182 | DSSE envelopes, in-toto attestations (immutable) |
**Retention Policies (configurable via `env/cas.env.example`):**
- Vulnerability DB: 7 days
- SBOM artifacts: 365 days
- Scan results: 90 days
- Evidence bundles: Indefinite (immutable)
- Attestations: Indefinite (immutable)
---
## Tile Proxy (Air-Gapped Sigstore)
For air-gapped deployments, the tile-proxy caches Rekor transparency log tiles locally from public Sigstore:
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.tile-proxy.yml up -d
```
**Tile Proxy vs Rekor v2:**
- Use `--profile sigstore` when running your own Rekor transparency log locally
- Use `docker-compose.tile-proxy.yml` when caching tiles from public Sigstore (rekor.sigstore.dev)
**Configuration:**
| Variable | Default | Purpose |
|----------|---------|---------|
| `REKOR_SERVER_URL` | `https://rekor.sigstore.dev` | Upstream Rekor to proxy |
| `TILE_PROXY_SYNC_ENABLED` | `true` | Enable periodic tile sync |
| `TILE_PROXY_SYNC_SCHEDULE` | `0 */6 * * *` | Sync every 6 hours |
| `TILE_PROXY_CACHE_MAX_SIZE_GB` | `10` | Local cache size limit |
The proxy syncs tiles on schedule and serves them to internal services for offline verification.
---
## Maintenance
### Backup
```bash
./scripts/backup.sh # Creates timestamped tar.gz of volumes
```
### Reset
```bash
./scripts/reset.sh # Stops stack, removes volumes (requires confirmation)
```
### Validate Configuration
```bash
docker compose -f docker-compose.stella-ops.yml config
```
### Update to New Release
1. Import new manifest to `deploy/releases/`
2. Update image digests in compose files
3. Run `docker compose config` to validate
4. Run `deploy/tools/validate-profiles.sh` for audit
---
## Troubleshooting
### Port Conflicts
Override ports in your `.env` file:
```bash
POSTGRES_PORT=5433
VALKEY_PORT=6380
SCANNER_WEB_PORT=8544
```
### Service Dependencies
Services declare `depends_on` with health checks. If a service fails to start, check its dependencies:
```bash
docker compose -f docker-compose.stella-ops.yml ps
docker compose -f docker-compose.stella-ops.yml logs postgres
docker compose -f docker-compose.stella-ops.yml logs valkey
```
### Crypto Provider Issues
For crypto simulation issues:
```bash
# Check sim-crypto service
docker compose logs sim-crypto
curl http://localhost:18090/keys
```
For CryptoPro issues:
```bash
# Verify EULA acceptance
echo $CRYPTOPRO_ACCEPT_EULA # must be 1
# Check CryptoPro service
docker compose logs cryptopro-csp
```
---
## Related Documentation
- [Deployment Upgrade Runbook](../../docs/operations/devops/runbooks/deployment-upgrade.md)
- [Local CI Guide](../../docs/technical/testing/LOCAL_CI_GUIDE.md)
- [Crypto Profile Configuration](../../docs/security/crypto-profile-configuration.md)
- [Regional Deployments](../../docs/operations/regional-deployments.md)

View File

@@ -1,403 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2-airgap"
com.stellaops.release.channel: "airgap"
com.stellaops.profile: "airgap"
networks:
stellaops:
driver: bridge
volumes:
valkey-data:
rustfs-data:
concelier-jobs:
nats-data:
scanner-surface-cache:
postgres-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d:ro
command:
- "postgres"
- "-c"
- "shared_preload_libraries=pg_stat_statements"
- "-c"
- "pg_stat_statements.track=all"
ports:
- "${POSTGRES_PORT:-25432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-26379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-24222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:5551a3269b7008cd5aceecf45df018c67459ed519557ccbe48b093b926a39bcc
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:ddbbd664a42846cea6b40fca6465bc679b30f72851158f300d01a8571c5478fc
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:1ff0a3124d66d3a2702d8e421df40fbd98cc75cb605d95510598ebbae1433c50
restart: unless-stopped
depends_on:
- signer
- postgres
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:3df8ca21878126758203c1a0444e39fd97f77ddacf04a69685cda9f1e5e94718
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
# Surface.Env configuration (see docs/modules/scanner/design/surface-env.md)
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:eea5d6cfe7835950c5ec7a735a651f2f0d727d3e470cf9027a4a402ea89c4fb5
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
# Surface.Env configuration (see docs/modules/scanner/design/surface-env.md)
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}"
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2}
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
DOTNET_ENVIRONMENT: Production
volumes:
- ../../etc/notify.airgap.yaml:/app/etc/notify.yaml:ro
ports:
- "${NOTIFY_WEB_PORT:-9446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:65c0ee13f773efe920d7181512349a09d363ab3f3e177d276136bd2742325a68
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2-airgap
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- 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
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2-airgap
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
volumes:
- 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
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:bee9668011ff414572131dc777faab4da24473fe12c230893f161cabee092a1d
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-9443}:8443"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,15 +1,14 @@
# Copyright (c) StellaOps. All rights reserved.
# Licensed under BUSL-1.1.
# BSim PostgreSQL Database and Ghidra Headless Services
# =============================================================================
# BSIM - BINARY SIMILARITY ANALYSIS
# =============================================================================
# BSim PostgreSQL Database and Ghidra Headless Services for binary analysis.
#
# Usage:
# docker compose -f docker-compose.bsim.yml up -d
#
# Environment variables:
# Environment:
# BSIM_DB_PASSWORD - PostgreSQL password for BSim database
version: '3.8'
# =============================================================================
services:
bsim-postgres:
@@ -22,9 +21,9 @@ services:
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
volumes:
- bsim-data:/var/lib/postgresql/data
- ./scripts/init-bsim.sql:/docker-entrypoint-initdb.d/10-init-bsim.sql:ro
- ../docker/ghidra/scripts/init-bsim.sql:/docker-entrypoint-initdb.d/10-init-bsim.sql:ro
ports:
- "5433:5432"
- "${BSIM_DB_PORT:-5433}:5432"
networks:
- stellaops-bsim
healthcheck:
@@ -34,10 +33,9 @@ services:
retries: 5
restart: unless-stopped
# Ghidra Headless service for BSim analysis
ghidra-headless:
build:
context: .
context: ../docker/ghidra
dockerfile: Dockerfile.headless
image: stellaops/ghidra-headless:11.2
container_name: stellaops-ghidra
@@ -61,13 +59,11 @@ services:
limits:
cpus: '4'
memory: 8G
# Keep container running for ad-hoc analysis
entrypoint: ["tail", "-f", "/dev/null"]
restart: unless-stopped
volumes:
bsim-data:
driver: local
ghidra-projects:
ghidra-scripts:
ghidra-output:
@@ -75,4 +71,3 @@ volumes:
networks:
stellaops-bsim:
driver: bridge

View File

@@ -2,9 +2,11 @@
# Uses RustFS for S3-compatible immutable object storage
# Aligned with best-in-class vulnerability scanner retention policies
#
# Usage:
# Usage (standalone):
# docker compose -f docker-compose.cas.yaml up -d
# docker compose -f docker-compose.cas.yaml -f docker-compose.dev.yaml up -d
#
# Usage (with main stack):
# docker compose -f docker-compose.stella-ops.yml -f docker-compose.cas.yaml up -d
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: SM2, SM3, SM4 (ShangMi / Commercial Cipher - temporarily using NIST)
# Provider: offline-verification
# Jurisdiction: china, world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "china"
com.stellaops.crypto.profile: "china"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "china"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
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-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:china
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:china
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:china
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:china
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,152 +0,0 @@
# =============================================================================
# LOCAL CI TESTING SERVICES
# =============================================================================
# Docker Compose profile for running CI tests locally.
# Uses different ports to avoid conflicts with development services.
#
# Usage:
# docker compose -f devops/compose/docker-compose.ci.yaml up -d
# docker compose -f devops/compose/docker-compose.ci.yaml down -v
#
# Services:
# - postgres-ci: PostgreSQL 18.1 for integration tests (port 5433)
# - valkey-ci: Valkey/Redis for caching tests (port 6380)
# - nats-ci: NATS JetStream for messaging tests (port 4223)
# - mock-registry: Local container registry for release testing (port 5001)
# - rekor-cli: Rekor CLI tool (profile: sigstore)
# - cosign: Cosign tool (profile: sigstore)
#
# =============================================================================
networks:
ci-net:
driver: bridge
name: stellaops-ci-net
volumes:
ci-postgres-data:
name: stellaops-ci-postgres
ci-valkey-data:
name: stellaops-ci-valkey
services:
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Primary database for integration tests
# ---------------------------------------------------------------------------
postgres-ci:
image: postgres:18.1-alpine
container_name: stellaops-postgres-ci
environment:
POSTGRES_USER: stellaops_ci
POSTGRES_PASSWORD: ci_test_password
POSTGRES_DB: stellaops_test
# Performance tuning for tests
POSTGRES_INITDB_ARGS: "--data-checksums"
ports:
- "5433:5432" # Different port to avoid conflicts with dev
volumes:
- ci-postgres-data:/var/lib/postgresql/data
networks:
- ci-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellaops_ci -d stellaops_test"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
restart: unless-stopped
# ---------------------------------------------------------------------------
# Valkey 9.0.1 - Redis-compatible cache for caching tests
# ---------------------------------------------------------------------------
valkey-ci:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-valkey-ci
command: ["valkey-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
ports:
- "6380:6379" # Different port to avoid conflicts
volumes:
- ci-valkey-data:/data
networks:
- ci-net
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Sigstore tools - Rekor CLI and Cosign (on-demand)
# ---------------------------------------------------------------------------
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- ci-net
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- ci-net
# ---------------------------------------------------------------------------
# NATS JetStream - Message queue for messaging tests
# ---------------------------------------------------------------------------
nats-ci:
image: nats:2.10-alpine
container_name: stellaops-nats-ci
command: ["-js", "-sd", "/data", "-m", "8222"]
ports:
- "4223:4222" # Client port (different from dev)
- "8223:8222" # Monitoring port
networks:
- ci-net
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8222/healthz"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Mock Container Registry - For release dry-run testing
# ---------------------------------------------------------------------------
mock-registry:
image: registry:2
container_name: stellaops-registry-ci
ports:
- "5001:5000"
environment:
REGISTRY_STORAGE_DELETE_ENABLED: "true"
networks:
- ci-net
restart: unless-stopped
# ---------------------------------------------------------------------------
# Mock S3 (MinIO) - For artifact storage tests
# ---------------------------------------------------------------------------
minio-ci:
image: minio/minio:latest
container_name: stellaops-minio-ci
command: server /data --console-address ":9001"
ports:
- "9100:9000" # S3 API port
- "9101:9001" # Console port
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
networks:
- ci-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

View File

@@ -0,0 +1,197 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: CHINA
# =============================================================================
# SM2/SM3/SM4 ShangMi (Commercial Cipher) crypto overlay.
# This file extends docker-compose.stella-ops.yml with China-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-china.yml up -d
#
# Cryptography:
# - SM2: Elliptic curve cryptography (signature, key exchange)
# - SM3: Hash function (256-bit digest)
# - SM4: Block cipher (128-bit)
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "china"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - China crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:china
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Signer - China crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Attestor - China crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Concelier - China crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:china
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scanner Web - China crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:china
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scanner Worker - China crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:china
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scheduler Worker - China crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Notify Web - China crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:china
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Excititor - China crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Advisory AI Web - China crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:china
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Advisory AI Worker - China crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:china
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Web UI - China crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:china
labels:
com.stellaops.crypto.profile: "china"

View File

@@ -0,0 +1,209 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: EU
# =============================================================================
# eIDAS qualified trust services crypto overlay.
# This file extends docker-compose.stella-ops.yml with EU-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-eu.yml up -d
#
# Cryptography:
# - eIDAS-compliant qualified electronic signatures
# - ETSI TS 119 312 compliant algorithms
# - Qualified Trust Service Provider (QTSP) integration
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "eu"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - EU crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Signer - EU crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Attestor - EU crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Concelier - EU crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:eu
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scanner Web - EU crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scanner Worker - EU crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:eu
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scheduler Worker - EU crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Notify Web - EU crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Excititor - EU crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Advisory AI Web - EU crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:eu
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Advisory AI Worker - EU crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:eu
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Web UI - EU crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:eu
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"

View File

@@ -0,0 +1,216 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: RUSSIA
# =============================================================================
# GOST R 34.10-2012, GOST R 34.11-2012 (Streebog) crypto overlay.
# This file extends docker-compose.stella-ops.yml with Russia-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-russia.yml up -d
#
# With CryptoPro CSP:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-russia.yml \
# -f devops/compose/docker-compose.cryptopro.yml up -d
#
# Cryptography:
# - GOST R 34.10-2012: Digital signature
# - GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
# - GOST R 34.12-2015: Block cipher (Kuznyechik)
#
# Providers: openssl.gost, pkcs11.gost, cryptopro.gost
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "russia"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
STELLAOPS_CRYPTO_PROVIDERS: "openssl.gost,pkcs11.gost,cryptopro.gost"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - Russia crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Signer - Russia crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Attestor - Russia crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Concelier - Russia crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:russia
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scanner Web - Russia crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scanner Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:russia
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scheduler Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Notify Web - Russia crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Excititor - Russia crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Advisory AI Web - Russia crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:russia
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Advisory AI Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:russia
environment:
<<: *crypto-env
volumes:
- ../../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
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Web UI - Russia crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:russia
labels:
com.stellaops.crypto.profile: "russia"

View File

@@ -1,13 +1,14 @@
# Copyright (c) StellaOps. All rights reserved.
# Licensed under BUSL-1.1.
# Function Behavior Corpus PostgreSQL Database
# =============================================================================
# CORPUS - FUNCTION BEHAVIOR DATABASE
# =============================================================================
# PostgreSQL database for function behavior corpus analysis.
#
# Usage:
# docker compose -f docker-compose.corpus.yml up -d
#
# Environment variables:
# Environment:
# CORPUS_DB_PASSWORD - PostgreSQL password for corpus database
# =============================================================================
services:
corpus-postgres:
@@ -20,10 +21,10 @@ services:
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
volumes:
- corpus-data:/var/lib/postgresql/data
- ../../../docs/db/schemas/corpus.sql:/docker-entrypoint-initdb.d/10-corpus-schema.sql:ro
- ./scripts/init-test-data.sql:/docker-entrypoint-initdb.d/20-test-data.sql:ro
- ../../docs/db/schemas/corpus.sql:/docker-entrypoint-initdb.d/10-corpus-schema.sql:ro
- ../docker/corpus/scripts/init-test-data.sql:/docker-entrypoint-initdb.d/20-test-data.sql:ro
ports:
- "5435:5432"
- "${CORPUS_DB_PORT:-5435}:5432"
networks:
- stellaops-corpus
healthcheck:
@@ -35,9 +36,7 @@ services:
volumes:
corpus-data:
driver: local
networks:
stellaops-corpus:
driver: bridge

View File

@@ -0,0 +1,119 @@
# =============================================================================
# STELLA OPS - CRYPTO SIMULATION OVERLAY
# =============================================================================
# Universal crypto simulation service for testing sovereign crypto without
# licensed hardware or certified modules.
#
# This overlay provides the sim-crypto-service which simulates:
# - GOST R 34.10-2012 (Russia): GOST12-256, GOST12-512, ru.magma.sim, ru.kuznyechik.sim
# - SM2/SM3/SM4 (China): SM2, sm.sim, sm2.sim
# - Post-Quantum: DILITHIUM3, FALCON512, pq.sim
# - FIPS/eIDAS/KCMVP: fips.sim, eidas.sim, kcmvp.sim, world.sim
#
# Usage with China compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with Russia compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with EU compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# IMPORTANT: This is for TESTING/DEVELOPMENT ONLY.
# - Uses deterministic HMAC-SHA256 for SM/GOST/PQ (not real algorithms)
# - Uses static ECDSA P-256 key for FIPS/eIDAS/KCMVP
# - NOT suitable for production or compliance certification
#
# =============================================================================
x-crypto-sim-labels: &crypto-sim-labels
com.stellaops.component: "crypto-sim"
com.stellaops.profile: "simulation"
com.stellaops.production: "false"
x-sim-crypto-env: &sim-crypto-env
STELLAOPS_CRYPTO_ENABLE_SIM: "1"
STELLAOPS_CRYPTO_SIM_URL: "http://sim-crypto:8080"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# Sim Crypto Service - Universal sovereign crypto simulator
# ---------------------------------------------------------------------------
sim-crypto:
build:
context: ../services/crypto/sim-crypto-service
dockerfile: Dockerfile
image: registry.stella-ops.org/stellaops/sim-crypto:dev
container_name: stellaops-sim-crypto
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
ASPNETCORE_ENVIRONMENT: "Development"
ports:
- "${SIM_CRYPTO_PORT:-18090}:8080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/keys"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
labels: *crypto-sim-labels
# ---------------------------------------------------------------------------
# Override services to use sim-crypto
# ---------------------------------------------------------------------------
# Authority - Enable sim crypto
authority:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Signer - Enable sim crypto
signer:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Attestor - Enable sim crypto
attestor:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Scanner Web - Enable sim crypto
scanner-web:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Scanner Worker - Enable sim crypto
scanner-worker:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Excititor - Enable sim crypto
excititor:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"

View File

@@ -0,0 +1,149 @@
# =============================================================================
# STELLA OPS - CRYPTOPRO CSP OVERLAY (Russia)
# =============================================================================
# CryptoPro CSP licensed provider overlay for compliance-russia.yml.
# Adds real CryptoPro CSP service for certified GOST R 34.10-2012 operations.
#
# IMPORTANT: Requires EULA acceptance before use.
#
# Usage (MUST be combined with stella-ops AND compliance-russia):
# CRYPTOPRO_ACCEPT_EULA=1 docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.cryptopro.yml up -d
#
# For development/testing without CryptoPro license, use crypto-sim.yml instead:
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Requirements:
# - CryptoPro CSP license files in opt/cryptopro/downloads/
# - CRYPTOPRO_ACCEPT_EULA=1 environment variable
# - CryptoPro container images with GOST engine
#
# GOST Algorithms Provided:
# - GOST R 34.10-2012: Digital signature (256/512-bit)
# - GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
# - GOST R 34.12-2015: Block cipher (Kuznyechik, Magma)
#
# =============================================================================
x-cryptopro-labels: &cryptopro-labels
com.stellaops.component: "cryptopro-csp"
com.stellaops.crypto.provider: "cryptopro"
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.certified: "true"
x-cryptopro-env: &cryptopro-env
STELLAOPS_CRYPTO_PROVIDERS: "cryptopro.gost"
STELLAOPS_CRYPTO_CRYPTOPRO_URL: "http://cryptopro-csp:8080"
STELLAOPS_CRYPTO_CRYPTOPRO_ENABLED: "true"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# CryptoPro CSP - Certified GOST cryptography provider
# ---------------------------------------------------------------------------
cryptopro-csp:
build:
context: ../..
dockerfile: devops/services/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
image: registry.stella-ops.org/stellaops/cryptopro-csp:2025.10.0
container_name: stellaops-cryptopro-csp
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
# GOST algorithm configuration
CRYPTOPRO_GOST_SIGNATURE_ALGORITHM: "GOST R 34.10-2012"
CRYPTOPRO_GOST_HASH_ALGORITHM: "GOST R 34.11-2012"
# Container and key store settings
CRYPTOPRO_CONTAINER_NAME: "${CRYPTOPRO_CONTAINER_NAME:-stellaops-signing}"
CRYPTOPRO_USE_MACHINE_STORE: "${CRYPTOPRO_USE_MACHINE_STORE:-true}"
CRYPTOPRO_PROVIDER_TYPE: "${CRYPTOPRO_PROVIDER_TYPE:-80}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
- ../../etc/cryptopro:/app/etc/cryptopro:ro
# Optional: Mount key containers
- cryptopro-keys:/var/opt/cprocsp/keys
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
labels: *cryptopro-labels
# ---------------------------------------------------------------------------
# Override services to use CryptoPro
# ---------------------------------------------------------------------------
# Authority - Use CryptoPro for GOST signatures
authority:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Signer - Use CryptoPro for GOST signatures
signer:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Attestor - Use CryptoPro for GOST signatures
attestor:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Scanner Web - Use CryptoPro for verification
scanner-web:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Scanner Worker - Use CryptoPro for verification
scanner-worker:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Excititor - Use CryptoPro for VEX signing
excititor:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
volumes:
cryptopro-keys:
name: stellaops-cryptopro-keys

View File

@@ -1,385 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "dev"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
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:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
restart: unless-stopped
depends_on:
- postgres
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority/plugins"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
restart: unless-stopped
depends_on:
- authority
- valkey
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
restart: unless-stopped
depends_on:
- signer
- valkey
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/app/etc/issuer-directory/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory:/app/etc/issuer-directory:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
restart: unless-stopped
depends_on:
- postgres
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:e0dfdb087e330585a5953029fb4757f5abdf7610820a085bd61b457dbead9a11
restart: unless-stopped
depends_on:
- postgres
- concelier
- rustfs
- nats
- valkey
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://nats:4222"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-valkey:6379}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
# Offline kit paths (for air-gap mode)
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-../../etc/certificates/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
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
restart: unless-stopped
depends_on:
- scanner-web
- rustfs
- nats
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://nats:4222"
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- nats
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__QUEUE__KIND: "Nats"
SCHEDULER__QUEUE__NATS__URL: "nats://nats:4222"
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.10.0-edge}
restart: unless-stopped
depends_on:
- postgres
- authority
- valkey
environment:
DOTNET_ENVIRONMENT: Development
NOTIFY__STORAGE__DRIVER: "postgres"
NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
NOTIFY__QUEUE__DRIVER: "nats"
NOTIFY__QUEUE__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/notify:/app/etc/notify:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/llm-providers:/app/etc/llm-providers:ro
# Runtime data
- 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
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/llm-providers:/app/etc/llm-providers:ro
# Runtime data
- 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
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
cryptopro-csp:
build:
context: ../..
dockerfile: ops/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -0,0 +1,73 @@
# =============================================================================
# DEVELOPMENT STACK - MINIMAL LOCAL DEVELOPMENT
# =============================================================================
# Minimal infrastructure for local development. Use this when you only need
# the core infrastructure without all application services.
#
# For full platform, use docker-compose.stella-ops.yml instead.
#
# Usage:
# docker compose -f docker-compose.dev.yml up -d
#
# This provides:
# - PostgreSQL 18.1 on port 5432
# - Valkey 9.0.1 on port 6379
# - RustFS on port 8080
# =============================================================================
services:
postgres:
image: postgres:18.1-alpine
container_name: stellaops-dev-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-stellaops}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-stellaops}
POSTGRES_DB: ${POSTGRES_DB:-stellaops_dev}
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT:-5432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-stellaops}"]
interval: 10s
timeout: 5s
retries: 5
valkey:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-dev-valkey
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-dev-rustfs
restart: unless-stopped
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_PORT:-8080}:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres-data:
valkey-data:
rustfs-data:

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: eIDAS-compliant qualified trust services (temporarily using NIST)
# Provider: offline-verification
# Jurisdiction: eu, world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "eu"
com.stellaops.crypto.profile: "eu"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "eu"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
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-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:eu
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:eu
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:eu
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:eu
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,61 +0,0 @@
# docker-compose.gitea-test.yaml - Local Gitea instance for testing package registry
# Sprint: SPRINT_20251226_004_CICD
#
# Usage:
# docker compose -f devops/compose/docker-compose.gitea-test.yaml up -d
# # Wait for Gitea to start, then:
# # 1. Open http://localhost:3000 and complete initial setup
# # 2. Create a user and generate access token with package:write scope
# # 3. Test NuGet push:
# # dotnet nuget push pkg.nupkg --source http://localhost:3000/api/packages/owner/nuget/index.json --api-key YOUR_TOKEN
#
# Cleanup:
# docker compose -f devops/compose/docker-compose.gitea-test.yaml down -v
services:
gitea:
image: gitea/gitea:1.21
container_name: stellaops-gitea-test
environment:
- USER_UID=1000
- USER_GID=1000
# Enable package registry
- GITEA__packages__ENABLED=true
- GITEA__packages__CHUNKED_UPLOAD_PATH=/data/tmp/package-upload
# Enable NuGet
- GITEA__packages__NUGET_ENABLED=true
# Enable Container registry
- GITEA__packages__CONTAINER_ENABLED=true
# Database (SQLite for simplicity)
- GITEA__database__DB_TYPE=sqlite3
- GITEA__database__PATH=/data/gitea/gitea.db
# Server config
- GITEA__server__ROOT_URL=http://localhost:3000/
- GITEA__server__HTTP_PORT=3000
# Disable metrics/telemetry
- GITEA__metrics__ENABLED=false
# Session config
- GITEA__session__PROVIDER=memory
# Cache config
- GITEA__cache__ADAPTER=memory
# Log level
- GITEA__log__LEVEL=Warn
volumes:
- gitea-data:/data
- gitea-config:/etc/gitea
ports:
- "3000:3000" # Web UI
- "3022:22" # SSH (optional)
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
gitea-data:
driver: local
gitea-config:
driver: local

View File

@@ -1,4 +1,18 @@
version: "3.9"
# =============================================================================
# STELLA OPS GPU OVERLAY
# =============================================================================
# Enables NVIDIA GPU acceleration for Advisory AI inference services.
#
# Prerequisites:
# - NVIDIA GPU with CUDA support
# - nvidia-container-toolkit installed
# - Docker configured with nvidia runtime
#
# Usage:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.gpu.yaml up -d
#
# =============================================================================
services:
advisory-ai-worker:

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: Standard NIST algorithms (ECDSA, RSA, SHA-2)
# Provider: offline-verification
# Jurisdiction: world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "international"
com.stellaops.crypto.profile: "international"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "international"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
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-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:international
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:international
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:international
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:international
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,152 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "mirror-managed"
networks:
mirror:
driver: bridge
volumes:
mongo-data:
minio-data:
concelier-jobs:
concelier-exports:
excititor-exports:
nginx-cache:
services:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
command: ["mongod", "--bind_ip_all"]
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}"
volumes:
- mongo-data:/data/db
networks:
- mirror
labels: *release-labels
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
command: ["server", "/data", "--console-address", ":9001"]
restart: unless-stopped
environment:
MINIO_ROOT_USER: "${MINIO_ROOT_USER:-stellaops-mirror}"
MINIO_ROOT_PASSWORD: "${MINIO_ROOT_PASSWORD:-mirror-minio-secret}"
volumes:
- minio-data:/data
networks:
- mirror
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
restart: unless-stopped
depends_on:
- mongo
- minio
environment:
ASPNETCORE_URLS: "http://+:8445"
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}:${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}@mongo:27017/concelier?authSource=admin"
CONCELIER__STORAGE__S3__ENDPOINT: "http://minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "${MINIO_ROOT_USER:-stellaops-mirror}"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "${MINIO_ROOT_PASSWORD:-mirror-minio-secret}"
CONCELIER__TELEMETRY__SERVICENAME: "stellaops-concelier-mirror"
CONCELIER__MIRROR__ENABLED: "true"
CONCELIER__MIRROR__EXPORTROOT: "/exports/json"
CONCELIER__MIRROR__LATESTDIRECTORYNAME: "${CONCELIER_MIRROR_LATEST_SEGMENT:-latest}"
CONCELIER__MIRROR__MIRRORDIRECTORYNAME: "${CONCELIER_MIRROR_DIRECTORY_SEGMENT:-mirror}"
CONCELIER__MIRROR__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_REQUIRE_AUTH:-true}"
CONCELIER__MIRROR__MAXINDEXREQUESTSPERHOUR: "${CONCELIER_MIRROR_INDEX_BUDGET:-600}"
CONCELIER__MIRROR__DOMAINS__0__ID: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_ID:-primary}"
CONCELIER__MIRROR__DOMAINS__0__DISPLAYNAME: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_NAME:-Primary Mirror}"
CONCELIER__MIRROR__DOMAINS__0__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_AUTH:-true}"
CONCELIER__MIRROR__DOMAINS__0__MAXDOWNLOADREQUESTSPERHOUR: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET:-3600}"
CONCELIER__MIRROR__DOMAINS__1__ID: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_ID:-community}"
CONCELIER__MIRROR__DOMAINS__1__DISPLAYNAME: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_NAME:-Community Mirror}"
CONCELIER__MIRROR__DOMAINS__1__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_AUTH:-false}"
CONCELIER__MIRROR__DOMAINS__1__MAXDOWNLOADREQUESTSPERHOUR: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET:-1800}"
CONCELIER__AUTHORITY__ENABLED: "${CONCELIER_AUTHORITY_ENABLED:-true}"
CONCELIER__AUTHORITY__ALLOWANONYMOUSFALLBACK: "${CONCELIER_AUTHORITY_ALLOW_ANON:-false}"
CONCELIER__AUTHORITY__ISSUER: "${CONCELIER_AUTHORITY_ISSUER:-https://authority.stella-ops.org}"
CONCELIER__AUTHORITY__METADATAADDRESS: "${CONCELIER_AUTHORITY_METADATA:-}"
CONCELIER__AUTHORITY__CLIENTID: "${CONCELIER_AUTHORITY_CLIENT_ID:-stellaops-concelier-mirror}"
CONCELIER__AUTHORITY__CLIENTSECRETFILE: "/run/secrets/concelier-authority-client"
CONCELIER__AUTHORITY__CLIENTSCOPES__0: "${CONCELIER_AUTHORITY_SCOPE:-concelier.mirror.read}"
CONCELIER__AUTHORITY__AUDIENCES__0: "${CONCELIER_AUTHORITY_AUDIENCE:-api://concelier.mirror}"
CONCELIER__AUTHORITY__BYPASSNETWORKS__0: "10.0.0.0/8"
CONCELIER__AUTHORITY__BYPASSNETWORKS__1: "127.0.0.1/32"
CONCELIER__AUTHORITY__BYPASSNETWORKS__2: "::1/128"
CONCELIER__AUTHORITY__RESILIENCE__ENABLERETRIES: "true"
CONCELIER__AUTHORITY__RESILIENCE__RETRYDELAYS__0: "00:00:01"
CONCELIER__AUTHORITY__RESILIENCE__RETRYDELAYS__1: "00:00:02"
CONCELIER__AUTHORITY__RESILIENCE__RETRYDELAYS__2: "00:00:05"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "00:10:00"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- concelier-exports:/exports/json
- ./mirror-secrets:/run/secrets:ro
networks:
- mirror
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
restart: unless-stopped
depends_on:
- mongo
environment:
ASPNETCORE_URLS: "http://+:8448"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}:${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}@mongo:27017/excititor?authSource=admin"
EXCITITOR__STORAGE__MONGO__DATABASENAME: "${EXCITITOR_MONGO_DATABASE:-excititor}"
EXCITITOR__ARTIFACTS__FILESYSTEM__ROOT: "/exports"
EXCITITOR__ARTIFACTS__FILESYSTEM__OVERWRITEEXISTING: "${EXCITITOR_FILESYSTEM_OVERWRITE:-false}"
EXCITITOR__MIRROR__DOMAINS__0__ID: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_ID:-primary}"
EXCITITOR__MIRROR__DOMAINS__0__DISPLAYNAME: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_NAME:-Primary Mirror}"
EXCITITOR__MIRROR__DOMAINS__0__REQUIREAUTHENTICATION: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_AUTH:-true}"
EXCITITOR__MIRROR__DOMAINS__0__MAXINDEXREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_INDEX_BUDGET:-300}"
EXCITITOR__MIRROR__DOMAINS__0__MAXDOWNLOADREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET:-2400}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__KEY: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_KEY:-consensus-json}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__FORMAT: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_FORMAT:-json}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__VIEW: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_VIEW:-consensus}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__KEY: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_KEY:-consensus-openvex}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__FORMAT: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_FORMAT:-openvex}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__VIEW: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_VIEW:-consensus}"
EXCITITOR__MIRROR__DOMAINS__1__ID: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_ID:-community}"
EXCITITOR__MIRROR__DOMAINS__1__DISPLAYNAME: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_NAME:-Community Mirror}"
EXCITITOR__MIRROR__DOMAINS__1__REQUIREAUTHENTICATION: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_AUTH:-false}"
EXCITITOR__MIRROR__DOMAINS__1__MAXINDEXREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_INDEX_BUDGET:-120}"
EXCITITOR__MIRROR__DOMAINS__1__MAXDOWNLOADREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET:-600}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__KEY: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_KEY:-community-consensus}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__FORMAT: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_FORMAT:-json}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__VIEW: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_VIEW:-consensus}"
volumes:
- excititor-exports:/exports
- ./mirror-secrets:/run/secrets:ro
expose:
- "8448"
networks:
- mirror
labels: *release-labels
mirror-gateway:
image: docker.io/library/nginx@sha256:208b70eefac13ee9be00e486f79c695b15cef861c680527171a27d253d834be9
restart: unless-stopped
depends_on:
- concelier
- excititor
ports:
- "${MIRROR_GATEWAY_HTTP_PORT:-8080}:80"
- "${MIRROR_GATEWAY_HTTPS_PORT:-9443}:443"
volumes:
- nginx-cache:/var/cache/nginx
- ./mirror-gateway/conf.d:/etc/nginx/conf.d:ro
- ./mirror-gateway/tls:/etc/nginx/tls:ro
- ./mirror-gateway/secrets:/etc/nginx/secrets:ro
networks:
- mirror
labels: *release-labels

View File

@@ -1,90 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2-mock"
com.stellaops.release.channel: "dev-mock"
com.stellaops.profile: "mock-overlay"
services:
orchestrator:
image: registry.stella-ops.org/stellaops/orchestrator@sha256:97f12856ce870bafd3328bda86833bcccbf56d255941d804966b5557f6610119
command: ["dotnet", "StellaOps.Orchestrator.WebService.dll"]
depends_on:
- mongo
- nats
labels: *release-labels
networks: [stellaops]
policy-registry:
image: registry.stella-ops.org/stellaops/policy-registry@sha256:c6cad8055e9827ebcbebb6ad4d6866dce4b83a0a49b0a8a6500b736a5cb26fa7
command: ["dotnet", "StellaOps.Policy.Engine.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
vex-lens:
image: registry.stella-ops.org/stellaops/vex-lens@sha256:b44e63ecfeebc345a70c073c1ce5ace709c58be0ffaad0e2862758aeee3092fb
command: ["dotnet", "StellaOps.VexLens.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory@sha256:67e8ef02c97d3156741e857756994888f30c373ace8e84886762edba9dc51914
command: ["dotnet", "StellaOps.IssuerDirectory.Web.dll"]
depends_on:
- mongo
- authority
labels: *release-labels
networks: [stellaops]
findings-ledger:
image: registry.stella-ops.org/stellaops/findings-ledger@sha256:71d4c361ba8b2f8b69d652597bc3f2efc8a64f93fab854ce25272a88506df49c
command: ["dotnet", "StellaOps.Findings.Ledger.WebService.dll"]
depends_on:
- postgres
- authority
labels: *release-labels
networks: [stellaops]
vuln-explorer-api:
image: registry.stella-ops.org/stellaops/vuln-explorer-api@sha256:7fc7e43a05cbeb0106ce7d4d634612e83de6fdc119aaab754a71c1d60b82841d
command: ["dotnet", "StellaOps.VulnExplorer.Api.dll"]
depends_on:
- findings-ledger
- authority
labels: *release-labels
networks: [stellaops]
packs-registry:
image: registry.stella-ops.org/stellaops/packs-registry@sha256:1f5e9416c4dc608594ad6fad87c24d72134427f899c192b494e22b268499c791
command: ["dotnet", "StellaOps.PacksRegistry.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
task-runner:
image: registry.stella-ops.org/stellaops/task-runner@sha256:eb5ad992b49a41554f41516be1a6afcfa6522faf2111c08ff2b3664ad2fc954b
command: ["dotnet", "StellaOps.TaskRunner.WebService.dll"]
depends_on:
- packs-registry
- postgres
labels: *release-labels
networks: [stellaops]
cryptopro-csp:
build:
context: ../..
dockerfile: ops/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
labels: *release-labels
networks: [stellaops]

View File

@@ -1,34 +0,0 @@
# Rekor v2 tiles stack (MySQL-free).
# Usage:
# docker compose -f devops/compose/docker-compose.dev.yaml \
# -f devops/compose/docker-compose.rekor-v2.yaml --profile sigstore up -d
#
# Notes:
# - This overlay runs Rekor v2 (rekor-tiles) with a POSIX tiles volume.
# - Pin the image digest via REKOR_TILES_IMAGE in your env file.
# - Keep it on the internal stellaops network unless you explicitly need
# external access.
x-rekor-v2-labels: &rekor-v2-labels
com.stellaops.profile: "sigstore"
com.stellaops.component: "rekor-v2"
networks:
stellaops:
driver: bridge
volumes:
rekor-tiles-data:
services:
rekor-v2:
image: ${REKOR_TILES_IMAGE:-ghcr.io/sigstore/rekor-tiles:latest}
restart: unless-stopped
networks:
- stellaops
volumes:
- rekor-tiles-data:/var/lib/rekor-tiles
# Backend-specific flags/env are intentionally omitted here; follow the
# rekor-tiles documentation for POSIX backend defaults.
profiles: ["sigstore"]
labels: *rekor-v2-labels

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: GOST R 34.10-2012, GOST R 34.11-2012 (Streebog)
# Provider: openssl.gost, pkcs11.gost, cryptopro.gost
# Jurisdiction: world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "russia"
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost, pkcs11.gost, cryptopro.gost"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "russia"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
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-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:russia
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:russia
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:russia
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:russia
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -0,0 +1,121 @@
# =============================================================================
# SEALED CI - AIR-GAPPED TESTING ENVIRONMENT
# =============================================================================
# Sealed/air-gapped CI environment for testing offline functionality.
# All services run in isolated network with no external egress.
#
# Usage:
# docker compose -f docker-compose.sealed-ci.yml up -d
# =============================================================================
x-release-labels: &release-labels
com.stellaops.profile: 'sealed-ci'
com.stellaops.airgap.mode: 'sealed'
networks:
sealed-ci:
driver: bridge
volumes:
sealed-postgres-data:
sealed-valkey-data:
services:
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
restart: unless-stopped
environment:
POSTGRES_USER: sealedci
POSTGRES_PASSWORD: sealedci-secret
POSTGRES_DB: stellaops
volumes:
- sealed-postgres-data:/var/lib/postgresql/data
networks:
- sealed-ci
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sealedci -d stellaops"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1-alpine
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- sealed-valkey-data:/data
networks:
- sealed-ci
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:5088
STELLAOPS_AUTHORITY__ISSUER: http://authority.sealed-ci.local
STELLAOPS_AUTHORITY__STORAGE__DRIVER: postgres
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=authority;Username=sealedci;Password=sealedci-secret"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: /app/plugins
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: /app/plugins
STELLAOPS_AUTHORITY__SECURITY__SENDERCONSTRAINTS__DPOP__ENABLED: 'true'
STELLAOPS_AUTHORITY__SECURITY__SENDERCONSTRAINTS__MTLS__ENABLED: 'true'
STELLAOPS_AUTHORITY__AIRGAP__EGRESS__MODE: Sealed
volumes:
- ../services/sealed-mode-ci/authority.harness.yaml:/etc/authority.yaml:ro
- ../services/sealed-mode-ci/plugins:/app/plugins:ro
- ../../certificates:/certificates:ro
ports:
- '5088:5088'
networks:
- sealed-ci
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
depends_on:
- authority
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:6088
SIGNER__AUTHORITY__BASEURL: http://authority:5088
SIGNER__POE__INTROSPECTURL: http://authority:5088/device-code
SIGNER__STORAGE__DRIVER: postgres
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=signer;Username=sealedci;Password=sealedci-secret"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SIGNER__SEALED__MODE: Enabled
ports:
- '6088:6088'
networks:
- sealed-ci
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
depends_on:
- signer
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:7088
ATTESTOR__SIGNER__BASEURL: http://signer:6088
ATTESTOR__STORAGE__DRIVER: postgres
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=attestor;Username=sealedci;Password=sealedci-secret"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ATTESTOR__SEALED__MODE: Enabled
ports:
- '7088:7088'
networks:
- sealed-ci
labels: *release-labels

View File

@@ -0,0 +1,153 @@
# =============================================================================
# STELLA OPS - SM REMOTE OVERLAY (China)
# =============================================================================
# SM Remote service overlay for compliance-china.yml.
# Provides SM2/SM3/SM4 (ShangMi) cryptographic operations via software provider
# or integration with OSCCA-certified hardware security modules.
#
# Usage (MUST be combined with stella-ops AND compliance-china):
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.sm-remote.yml up -d
#
# For development/testing without SM hardware, use crypto-sim.yml instead:
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# SM Algorithms Provided:
# - SM2: Public key cryptography (ECDSA-like, 256-bit curve) - GM/T 0003-2012
# - SM3: Cryptographic hash function (256-bit output) - GM/T 0004-2012
# - SM4: Block cipher (128-bit key/block, AES-like) - GM/T 0002-2012
# - SM9: Identity-based cryptography - GM/T 0044-2016
#
# Providers:
# - cn.sm.soft: Software-only implementation using BouncyCastle
# - cn.sm.remote.http: Remote HSM integration via HTTP API
#
# OSCCA Compliance:
# - All cryptographic operations use SM algorithms exclusively
# - Hardware Security Modules should be OSCCA-certified
# - Certificates comply with GM/T 0015 (Certificate Profile)
#
# =============================================================================
x-sm-remote-labels: &sm-remote-labels
com.stellaops.component: "sm-remote"
com.stellaops.crypto.provider: "sm"
com.stellaops.crypto.profile: "china"
com.stellaops.crypto.jurisdiction: "china"
x-sm-remote-env: &sm-remote-env
STELLAOPS_CRYPTO_PROVIDERS: "cn.sm.soft,cn.sm.remote.http"
STELLAOPS_CRYPTO_SM_REMOTE_URL: "http://sm-remote:56080"
STELLAOPS_CRYPTO_SM_ENABLED: "true"
SM_SOFT_ALLOWED: "1"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# SM Remote Service - ShangMi cryptography provider
# ---------------------------------------------------------------------------
sm-remote:
build:
context: ../..
dockerfile: devops/services/sm-remote/Dockerfile
image: registry.stella-ops.org/stellaops/sm-remote:2025.10.0
container_name: stellaops-sm-remote
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:56080"
ASPNETCORE_ENVIRONMENT: "Production"
# Enable software-only SM2 provider (for testing/development)
SM_SOFT_ALLOWED: "${SM_SOFT_ALLOWED:-1}"
# Optional: Remote HSM configuration (for production with OSCCA-certified HSM)
SM_REMOTE_HSM_URL: "${SM_REMOTE_HSM_URL:-}"
SM_REMOTE_HSM_API_KEY: "${SM_REMOTE_HSM_API_KEY:-}"
SM_REMOTE_HSM_TIMEOUT: "${SM_REMOTE_HSM_TIMEOUT:-30000}"
# Optional: Client certificate authentication for HSM
SM_REMOTE_CLIENT_CERT_PATH: "${SM_REMOTE_CLIENT_CERT_PATH:-}"
SM_REMOTE_CLIENT_CERT_PASSWORD: "${SM_REMOTE_CLIENT_CERT_PASSWORD:-}"
volumes:
- ../../etc/sm-remote:/app/etc/sm-remote:ro
# Optional: Mount SM key containers
- sm-remote-keys:/var/lib/stellaops/sm-keys
ports:
- "${SM_REMOTE_PORT:-56080}:56080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:56080/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
labels: *sm-remote-labels
# ---------------------------------------------------------------------------
# Override services to use SM Remote
# ---------------------------------------------------------------------------
# Authority - Use SM Remote for SM2 signatures
authority:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Signer - Use SM Remote for SM2 signatures
signer:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Attestor - Use SM Remote for SM2 signatures
attestor:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Scanner Web - Use SM Remote for verification
scanner-web:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Scanner Worker - Use SM Remote for verification
scanner-worker:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Excititor - Use SM Remote for VEX signing
excititor:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
volumes:
sm-remote-keys:
name: stellaops-sm-remote-keys

View File

@@ -1,389 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2"
com.stellaops.release.channel: "stable"
com.stellaops.profile: "stage"
networks:
stellaops:
driver: bridge
volumes:
valkey-data:
rustfs-data:
concelier-jobs:
nats-data:
scanner-surface-cache:
postgres-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
postgres:
image: docker.io/library/postgres:18.1
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
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
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
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
restart: unless-stopped
depends_on:
- signer
- postgres
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}"
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2}
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
DOTNET_ENVIRONMENT: Production
volumes:
- ../../etc/notify.stage.yaml:/app/etc/notify.yaml:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- 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
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
volumes:
- 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
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,54 +1,148 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2"
com.stellaops.release.channel: "stable"
com.stellaops.profile: "prod"
networks:
stellaops:
driver: bridge
frontdoor:
external: true
name: ${FRONTDOOR_NETWORK:-stellaops_frontdoor}
volumes:
valkey-data:
rustfs-data:
concelier-jobs:
nats-data:
scanner-surface-cache:
postgres-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
# =============================================================================
# STELLA OPS - MAIN STACK
# =============================================================================
# Consolidated Docker Compose for the complete StellaOps platform.
# Infrastructure: PostgreSQL 18.1, Valkey 9.0.1, RustFS, Rekor v2
#
# 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=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
stellaops:
driver: bridge
name: stellaops
frontdoor:
external: true
name: ${FRONTDOOR_NETWORK:-stellaops_frontdoor}
volumes:
postgres-data:
valkey-data:
rustfs-data:
rekor-tiles-data:
concelier-jobs:
scanner-surface-cache:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
# ===========================================================================
# INFRASTRUCTURE SERVICES
# ===========================================================================
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Primary database
# ---------------------------------------------------------------------------
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:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
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 9.0.1 - Cache and message queue (Redis-compatible)
# ---------------------------------------------------------------------------
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:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
# ---------------------------------------------------------------------------
# RustFS - S3-compatible object storage
# ---------------------------------------------------------------------------
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-rustfs
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
labels: *release-labels
# ---------------------------------------------------------------------------
# Rekor v2 (tiles) - Sigstore transparency log
# ---------------------------------------------------------------------------
rekor-v2:
image: ${REKOR_TILES_IMAGE:-ghcr.io/sigstore/rekor-tiles:latest}
container_name: stellaops-rekor
restart: unless-stopped
volumes:
- rekor-tiles-data:/var/lib/rekor-tiles
networks:
- stellaops
profiles: ["sigstore"]
labels:
<<: *release-labels
com.stellaops.component: "rekor-v2"
# ---------------------------------------------------------------------------
# Sigstore CLI tools (on-demand)
# ---------------------------------------------------------------------------
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
@@ -67,334 +161,378 @@ services:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
- frontdoor
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
- frontdoor
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
restart: unless-stopped
depends_on:
- signer
- postgres
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
- frontdoor
labels: *release-labels
postgres:
image: docker.io/library/postgres:18.1
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
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
- frontdoor
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
- frontdoor
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}"
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2}
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
DOTNET_ENVIRONMENT: Production
volumes:
- ../../etc/notify.prod.yaml:/app/etc/notify.yaml:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
- frontdoor
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- 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
- frontdoor
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
volumes:
- 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
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ===========================================================================
# APPLICATION SERVICES
# ===========================================================================
# ---------------------------------------------------------------------------
# Authority - OAuth2/OIDC identity provider
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5
container_name: stellaops-authority
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority/plugins"
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Signer - Cryptographic signing service
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e
container_name: stellaops-signer
restart: unless-stopped
depends_on:
- authority
- valkey
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Attestor - SLSA attestation service
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
container_name: stellaops-attestor
restart: unless-stopped
depends_on:
- signer
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Issuer Directory - CSAF publisher registry
# ---------------------------------------------------------------------------
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0
container_name: stellaops-issuer-directory
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/app/etc/issuer-directory/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory:/app/etc/issuer-directory:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
# ---------------------------------------------------------------------------
# Concelier - Advisory aggregation service
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
container_name: stellaops-concelier
restart: unless-stopped
depends_on:
- postgres
- valkey
- rustfs
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Scanner Web - SBOM/vulnerability scanning API
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7
container_name: stellaops-scanner-web
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
# Queue configuration - Valkey only
SCANNER__QUEUE__BROKER: "valkey://valkey:6379"
# Event streaming
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "valkey:6379"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
# Offline kit
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
# Surface cache
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${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
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Scanner Worker - Background scanning jobs
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
container_name: stellaops-scanner-worker
restart: unless-stopped
depends_on:
- scanner-web
- valkey
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
# Queue configuration - Valkey only
SCANNER__QUEUE__BROKER: "valkey://valkey:6379"
# Surface cache
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
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}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
# ---------------------------------------------------------------------------
# Scheduler Worker - Background job scheduling
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0
container_name: stellaops-scheduler-worker
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
# Queue configuration - Valkey only
SCHEDULER__QUEUE__KIND: "Valkey"
SCHEDULER__QUEUE__VALKEY__URL: "valkey:6379"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
# ---------------------------------------------------------------------------
# Notify Web - Notification service
# ---------------------------------------------------------------------------
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.10.0}
container_name: stellaops-notify-web
restart: unless-stopped
depends_on:
- postgres
- authority
- valkey
environment:
DOTNET_ENVIRONMENT: Production
NOTIFY__STORAGE__DRIVER: "postgres"
NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
# Queue configuration - Valkey only
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "valkey:6379"
volumes:
- ../../etc/notify:/app/etc/notify:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Excititor - VEX generation service
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
container_name: stellaops-excititor
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
networks:
- stellaops
labels: *release-labels
# ---------------------------------------------------------------------------
# Advisory AI Web - AI-powered advisory analysis API
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0
container_name: stellaops-advisory-ai-web
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- ../../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
- frontdoor
labels: *release-labels
# ---------------------------------------------------------------------------
# Advisory AI Worker - Background AI processing
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.10.0
container_name: stellaops-advisory-ai-worker
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
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__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:-}"
volumes:
- ../../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
labels: *release-labels
# ---------------------------------------------------------------------------
# Web UI - Angular frontend
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
container_name: stellaops-web-ui
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
- frontdoor
labels: *release-labels

View File

@@ -0,0 +1,90 @@
# =============================================================================
# TELEMETRY OFFLINE - AIR-GAPPED OBSERVABILITY
# =============================================================================
# Offline-compatible telemetry stack for air-gapped deployments.
# Does not require external connectivity.
#
# Usage:
# docker compose -f docker-compose.telemetry-offline.yml up -d
#
# For online deployments, use docker-compose.telemetry.yml instead.
# =============================================================================
services:
loki:
image: grafana/loki:3.0.1
container_name: stellaops-loki-offline
command: ["-config.file=/etc/loki/local-config.yaml"]
volumes:
- loki-data:/loki
- ../offline/airgap/observability/loki-config.yaml:/etc/loki/local-config.yaml:ro
ports:
- "${LOKI_PORT:-3100}:3100"
networks:
- sealed
restart: unless-stopped
promtail:
image: grafana/promtail:3.0.1
container_name: stellaops-promtail-offline
command: ["-config.file=/etc/promtail/config.yml"]
volumes:
- promtail-data:/var/log
- ../offline/airgap/promtail-config.yaml:/etc/promtail/config.yml:ro
networks:
- sealed
restart: unless-stopped
otel-collector:
image: otel/opentelemetry-collector-contrib:0.97.0
container_name: stellaops-otel-offline
command: ["--config=/etc/otel/config.yaml"]
volumes:
- ../offline/airgap/otel-offline.yaml:/etc/otel/config.yaml:ro
- otel-data:/var/otel
ports:
- "${OTEL_GRPC_PORT:-4317}:4317"
- "${OTEL_HTTP_PORT:-4318}:4318"
networks:
- sealed
restart: unless-stopped
tempo:
image: grafana/tempo:2.4.1
container_name: stellaops-tempo-offline
command: ["-config.file=/etc/tempo/config.yaml"]
volumes:
- tempo-data:/var/tempo
- ../offline/airgap/observability/tempo-config.yaml:/etc/tempo/config.yaml:ro
ports:
- "${TEMPO_PORT:-3200}:3200"
networks:
- sealed
restart: unless-stopped
prometheus:
image: prom/prometheus:v2.51.0
container_name: stellaops-prometheus-offline
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
volumes:
- prometheus-data:/prometheus
- ../offline/airgap/observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
networks:
- sealed
restart: unless-stopped
networks:
sealed:
driver: bridge
volumes:
loki-data:
promtail-data:
otel-data:
tempo-data:
prometheus-data:

View File

@@ -1,57 +0,0 @@
version: "3.9"
services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: stellaops-prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yaml"
volumes:
- ../telemetry/storage/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-data:/prometheus
- ../telemetry/certs:/etc/telemetry/tls:ro
- ../telemetry/storage/auth:/etc/telemetry/auth:ro
environment:
PROMETHEUS_COLLECTOR_TARGET: stellaops-otel-collector:9464
ports:
- "9090:9090"
depends_on:
- tempo
- loki
tempo:
image: grafana/tempo:2.5.0
container_name: stellaops-tempo
command:
- "-config.file=/etc/tempo/tempo.yaml"
volumes:
- ../telemetry/storage/tempo.yaml:/etc/tempo/tempo.yaml:ro
- ../telemetry/storage/tenants/tempo-overrides.yaml:/etc/telemetry/tenants/tempo-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- tempo-data:/var/tempo
ports:
- "3200:3200"
environment:
TEMPO_ZONE: docker
loki:
image: grafana/loki:3.1.0
container_name: stellaops-loki
command:
- "-config.file=/etc/loki/loki.yaml"
volumes:
- ../telemetry/storage/loki.yaml:/etc/loki/loki.yaml:ro
- ../telemetry/storage/tenants/loki-overrides.yaml:/etc/telemetry/tenants/loki-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- loki-data:/var/loki
ports:
- "3100:3100"
volumes:
prometheus-data:
tempo-data:
loki-data:
networks:
default:
name: stellaops-telemetry

View File

@@ -1,42 +0,0 @@
version: "3.9"
services:
otel-collector:
image: otel/opentelemetry-collector:0.105.0
container_name: stellaops-otel-collector
command:
- "--config=/etc/otel-collector/config.yaml"
environment:
STELLAOPS_OTEL_TLS_CERT: /etc/otel-collector/tls/collector.crt
STELLAOPS_OTEL_TLS_KEY: /etc/otel-collector/tls/collector.key
STELLAOPS_OTEL_TLS_CA: /etc/otel-collector/tls/ca.crt
STELLAOPS_OTEL_PROMETHEUS_ENDPOINT: 0.0.0.0:9464
STELLAOPS_OTEL_REQUIRE_CLIENT_CERT: "true"
STELLAOPS_TENANT_ID: dev
STELLAOPS_TEMPO_ENDPOINT: https://stellaops-tempo:3200
STELLAOPS_TEMPO_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_TEMPO_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_TEMPO_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
STELLAOPS_LOKI_ENDPOINT: https://stellaops-loki:3100/loki/api/v1/push
STELLAOPS_LOKI_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_LOKI_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_LOKI_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
volumes:
- ../telemetry/otel-collector-config.yaml:/etc/otel-collector/config.yaml:ro
- ../telemetry/certs:/etc/otel-collector/tls:ro
ports:
- "4317:4317" # OTLP gRPC (mTLS)
- "4318:4318" # OTLP HTTP (mTLS)
- "9464:9464" # Prometheus exporter (mTLS)
- "13133:13133" # Health check
- "1777:1777" # pprof
healthcheck:
test: ["CMD", "curl", "-fsk", "--cert", "/etc/otel-collector/tls/client.crt", "--key", "/etc/otel-collector/tls/client.key", "--cacert", "/etc/otel-collector/tls/ca.crt", "https://localhost:13133/healthz"]
interval: 30s
start_period: 15s
timeout: 5s
retries: 3
networks:
default:
name: stellaops-telemetry

View File

@@ -0,0 +1,144 @@
# =============================================================================
# STELLA OPS - TELEMETRY STACK
# =============================================================================
# All-in-one observability: OpenTelemetry Collector, Prometheus, Tempo, Loki
#
# Usage:
# docker compose -f devops/compose/docker-compose.telemetry.yml up -d
#
# With main stack:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.telemetry.yml up -d
#
# =============================================================================
x-telemetry-labels: &telemetry-labels
com.stellaops.component: "telemetry"
com.stellaops.profile: "observability"
networks:
stellaops-telemetry:
driver: bridge
name: stellaops-telemetry
stellaops:
external: true
name: stellaops
volumes:
prometheus-data:
tempo-data:
loki-data:
services:
# ---------------------------------------------------------------------------
# OpenTelemetry Collector - Unified telemetry ingestion
# ---------------------------------------------------------------------------
otel-collector:
image: otel/opentelemetry-collector:0.105.0
container_name: stellaops-otel-collector
restart: unless-stopped
command:
- "--config=/etc/otel-collector/config.yaml"
environment:
STELLAOPS_OTEL_TLS_CERT: /etc/otel-collector/tls/collector.crt
STELLAOPS_OTEL_TLS_KEY: /etc/otel-collector/tls/collector.key
STELLAOPS_OTEL_TLS_CA: /etc/otel-collector/tls/ca.crt
STELLAOPS_OTEL_PROMETHEUS_ENDPOINT: 0.0.0.0:9464
STELLAOPS_OTEL_REQUIRE_CLIENT_CERT: "true"
STELLAOPS_TENANT_ID: ${STELLAOPS_TENANT_ID:-default}
STELLAOPS_TEMPO_ENDPOINT: http://tempo:3200
STELLAOPS_TEMPO_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_TEMPO_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_TEMPO_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
STELLAOPS_LOKI_ENDPOINT: http://loki:3100/loki/api/v1/push
STELLAOPS_LOKI_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_LOKI_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_LOKI_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
volumes:
- ../telemetry/otel-collector-config.yaml:/etc/otel-collector/config.yaml:ro
- ../telemetry/certs:/etc/otel-collector/tls:ro
ports:
- "${OTEL_GRPC_PORT:-4317}:4317" # OTLP gRPC
- "${OTEL_HTTP_PORT:-4318}:4318" # OTLP HTTP
- "${OTEL_PROMETHEUS_PORT:-9464}:9464" # Prometheus exporter
- "${OTEL_HEALTH_PORT:-13133}:13133" # Health check
- "${OTEL_PPROF_PORT:-1777}:1777" # pprof
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:13133/healthz"]
interval: 30s
start_period: 15s
timeout: 5s
retries: 3
networks:
- stellaops-telemetry
- stellaops
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Prometheus - Metrics storage
# ---------------------------------------------------------------------------
prometheus:
image: prom/prometheus:v2.53.0
container_name: stellaops-prometheus
restart: unless-stopped
command:
- "--config.file=/etc/prometheus/prometheus.yaml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-15d}"
- "--web.enable-lifecycle"
volumes:
- ../telemetry/storage/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-data:/prometheus
- ../telemetry/certs:/etc/telemetry/tls:ro
- ../telemetry/storage/auth:/etc/telemetry/auth:ro
environment:
PROMETHEUS_COLLECTOR_TARGET: otel-collector:9464
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
depends_on:
- otel-collector
networks:
- stellaops-telemetry
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Tempo - Distributed tracing backend
# ---------------------------------------------------------------------------
tempo:
image: grafana/tempo:2.5.0
container_name: stellaops-tempo
restart: unless-stopped
command:
- "-config.file=/etc/tempo/tempo.yaml"
volumes:
- ../telemetry/storage/tempo.yaml:/etc/tempo/tempo.yaml:ro
- ../telemetry/storage/tenants/tempo-overrides.yaml:/etc/telemetry/tenants/tempo-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- tempo-data:/var/tempo
environment:
TEMPO_ZONE: docker
ports:
- "${TEMPO_PORT:-3200}:3200"
networks:
- stellaops-telemetry
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Loki - Log aggregation
# ---------------------------------------------------------------------------
loki:
image: grafana/loki:3.1.0
container_name: stellaops-loki
restart: unless-stopped
command:
- "-config.file=/etc/loki/loki.yaml"
volumes:
- ../telemetry/storage/loki.yaml:/etc/loki/loki.yaml:ro
- ../telemetry/storage/tenants/loki-overrides.yaml:/etc/telemetry/tenants/loki-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- loki-data:/var/loki
ports:
- "${LOKI_PORT:-3100}:3100"
networks:
- stellaops-telemetry
labels: *telemetry-labels

View File

@@ -0,0 +1,327 @@
# =============================================================================
# STELLA OPS - TESTING STACK
# =============================================================================
# Consolidated CI, mock services, and Gitea for integration testing.
# Uses different ports to avoid conflicts with development/production services.
#
# Usage:
# docker compose -f devops/compose/docker-compose.testing.yml up -d
#
# CI infrastructure only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile ci up -d
#
# Mock services only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile mock up -d
#
# Gitea only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile gitea up -d
#
# =============================================================================
x-testing-labels: &testing-labels
com.stellaops.profile: "testing"
com.stellaops.environment: "ci"
networks:
testing-net:
driver: bridge
name: stellaops-testing
volumes:
# CI volumes
ci-postgres-data:
name: stellaops-ci-postgres
ci-valkey-data:
name: stellaops-ci-valkey
ci-rustfs-data:
name: stellaops-ci-rustfs
# Gitea volumes
gitea-data:
gitea-config:
services:
# ===========================================================================
# CI INFRASTRUCTURE (different ports to avoid conflicts)
# ===========================================================================
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Test database (port 5433)
# ---------------------------------------------------------------------------
postgres-test:
image: postgres:18.1-alpine
container_name: stellaops-postgres-test
profiles: ["ci", "all"]
environment:
POSTGRES_USER: stellaops_ci
POSTGRES_PASSWORD: ci_test_password
POSTGRES_DB: stellaops_test
POSTGRES_INITDB_ARGS: "--data-checksums"
ports:
- "${TEST_POSTGRES_PORT:-5433}:5432"
volumes:
- ci-postgres-data:/var/lib/postgresql/data
networks:
- testing-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellaops_ci -d stellaops_test"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Valkey 9.0.1 - Test cache/queue (port 6380)
# ---------------------------------------------------------------------------
valkey-test:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-valkey-test
profiles: ["ci", "all"]
command: ["valkey-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
ports:
- "${TEST_VALKEY_PORT:-6380}:6379"
volumes:
- ci-valkey-data:/data
networks:
- testing-net
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# RustFS - Test artifact storage (port 8180)
# ---------------------------------------------------------------------------
rustfs-test:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-rustfs-test
profiles: ["ci", "all"]
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
ports:
- "${TEST_RUSTFS_PORT:-8180}:8080"
volumes:
- ci-rustfs-data:/data
networks:
- testing-net
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Mock Container Registry (port 5001)
# ---------------------------------------------------------------------------
mock-registry:
image: registry:2
container_name: stellaops-registry-test
profiles: ["ci", "all"]
ports:
- "${TEST_REGISTRY_PORT:-5001}:5000"
environment:
REGISTRY_STORAGE_DELETE_ENABLED: "true"
networks:
- testing-net
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Sigstore CLI tools (on-demand)
# ---------------------------------------------------------------------------
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- testing-net
labels: *testing-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- testing-net
labels: *testing-labels
# ===========================================================================
# MOCK SERVICES (for extended integration testing)
# ===========================================================================
# ---------------------------------------------------------------------------
# Orchestrator mock
# ---------------------------------------------------------------------------
orchestrator:
image: registry.stella-ops.org/stellaops/orchestrator@sha256:97f12856ce870bafd3328bda86833bcccbf56d255941d804966b5557f6610119
container_name: stellaops-orchestrator-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Orchestrator.WebService.dll"]
depends_on:
- postgres-test
- valkey-test
environment:
ORCHESTRATOR__STORAGE__DRIVER: "postgres"
ORCHESTRATOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
ORCHESTRATOR__QUEUE__DRIVER: "valkey"
ORCHESTRATOR__QUEUE__VALKEY__URL: "valkey-test:6379"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Policy Registry mock
# ---------------------------------------------------------------------------
policy-registry:
image: registry.stella-ops.org/stellaops/policy-registry@sha256:c6cad8055e9827ebcbebb6ad4d6866dce4b83a0a49b0a8a6500b736a5cb26fa7
container_name: stellaops-policy-registry-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Policy.Engine.dll"]
depends_on:
- postgres-test
environment:
POLICY__STORAGE__DRIVER: "postgres"
POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# VEX Lens mock
# ---------------------------------------------------------------------------
vex-lens:
image: registry.stella-ops.org/stellaops/vex-lens@sha256:b44e63ecfeebc345a70c073c1ce5ace709c58be0ffaad0e2862758aeee3092fb
container_name: stellaops-vex-lens-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.VexLens.dll"]
depends_on:
- postgres-test
environment:
VEXLENS__STORAGE__DRIVER: "postgres"
VEXLENS__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Findings Ledger mock
# ---------------------------------------------------------------------------
findings-ledger:
image: registry.stella-ops.org/stellaops/findings-ledger@sha256:71d4c361ba8b2f8b69d652597bc3f2efc8a64f93fab854ce25272a88506df49c
container_name: stellaops-findings-ledger-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Findings.Ledger.WebService.dll"]
depends_on:
- postgres-test
environment:
FINDINGSLEDGER__STORAGE__DRIVER: "postgres"
FINDINGSLEDGER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Vuln Explorer API mock
# ---------------------------------------------------------------------------
vuln-explorer-api:
image: registry.stella-ops.org/stellaops/vuln-explorer-api@sha256:7fc7e43a05cbeb0106ce7d4d634612e83de6fdc119aaab754a71c1d60b82841d
container_name: stellaops-vuln-explorer-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.VulnExplorer.Api.dll"]
depends_on:
- findings-ledger
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Packs Registry mock
# ---------------------------------------------------------------------------
packs-registry:
image: registry.stella-ops.org/stellaops/packs-registry@sha256:1f5e9416c4dc608594ad6fad87c24d72134427f899c192b494e22b268499c791
container_name: stellaops-packs-registry-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.PacksRegistry.dll"]
depends_on:
- postgres-test
environment:
PACKSREGISTRY__STORAGE__DRIVER: "postgres"
PACKSREGISTRY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Task Runner mock
# ---------------------------------------------------------------------------
task-runner:
image: registry.stella-ops.org/stellaops/task-runner@sha256:eb5ad992b49a41554f41516be1a6afcfa6522faf2111c08ff2b3664ad2fc954b
container_name: stellaops-task-runner-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.TaskRunner.WebService.dll"]
depends_on:
- packs-registry
- postgres-test
environment:
TASKRUNNER__STORAGE__DRIVER: "postgres"
TASKRUNNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ===========================================================================
# GITEA (SCM integration testing)
# ===========================================================================
# ---------------------------------------------------------------------------
# Gitea - Git hosting with package registry
# ---------------------------------------------------------------------------
gitea:
image: gitea/gitea:1.21
container_name: stellaops-gitea-test
profiles: ["gitea", "all"]
environment:
- USER_UID=1000
- USER_GID=1000
# Enable package registry
- GITEA__packages__ENABLED=true
- GITEA__packages__CHUNKED_UPLOAD_PATH=/data/tmp/package-upload
# Enable NuGet
- GITEA__packages__NUGET_ENABLED=true
# Enable Container registry
- GITEA__packages__CONTAINER_ENABLED=true
# Database (SQLite for simplicity)
- GITEA__database__DB_TYPE=sqlite3
- GITEA__database__PATH=/data/gitea/gitea.db
# Server config
- GITEA__server__ROOT_URL=http://localhost:${TEST_GITEA_PORT:-3000}/
- GITEA__server__HTTP_PORT=3000
# Disable metrics/telemetry
- GITEA__metrics__ENABLED=false
# Session config
- GITEA__session__PROVIDER=memory
# Cache config
- GITEA__cache__ADAPTER=memory
# Log level
- GITEA__log__LEVEL=Warn
volumes:
- gitea-data:/data
- gitea-config:/etc/gitea
ports:
- "${TEST_GITEA_PORT:-3000}:3000"
- "${TEST_GITEA_SSH_PORT:-3022}:22"
networks:
- testing-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
labels: *testing-labels

View File

@@ -0,0 +1,80 @@
# =============================================================================
# STELLA OPS TILE PROXY OVERLAY
# =============================================================================
# Rekor tile caching proxy for air-gapped and offline deployments.
# Caches tiles from upstream Rekor (public Sigstore or private) locally.
#
# Use Cases:
# - Air-gapped deployments with periodic sync
# - Reduce latency by caching frequently-accessed tiles
# - Offline verification when upstream is unavailable
#
# Note: This is an ALTERNATIVE to running your own rekor-v2 instance.
# Use tile-proxy when you want to cache from public Sigstore.
# Use rekor-v2 (--profile sigstore) when running your own transparency log.
#
# Usage:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.tile-proxy.yml up -d
#
# =============================================================================
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0"
com.stellaops.release.channel: "stable"
com.stellaops.component: "tile-proxy"
volumes:
tile-cache:
driver: local
tuf-cache:
driver: local
services:
tile-proxy:
build:
context: ../..
dockerfile: src/Attestor/StellaOps.Attestor.TileProxy/Dockerfile
image: registry.stella-ops.org/stellaops/tile-proxy:2025.10.0
container_name: stellaops-tile-proxy
restart: unless-stopped
ports:
- "${TILE_PROXY_PORT:-8090}:8080"
volumes:
- tile-cache:/var/cache/stellaops/tiles
- tuf-cache:/var/cache/stellaops/tuf
environment:
# Upstream Rekor configuration
TILE_PROXY__UPSTREAMURL: "${REKOR_SERVER_URL:-https://rekor.sigstore.dev}"
TILE_PROXY__ORIGIN: "${REKOR_ORIGIN:-rekor.sigstore.dev - 1985497715}"
# TUF configuration (optional - for checkpoint signature validation)
TILE_PROXY__TUF__ENABLED: "${TILE_PROXY_TUF_ENABLED:-false}"
TILE_PROXY__TUF__URL: "${TILE_PROXY_TUF_ROOT_URL:-}"
TILE_PROXY__TUF__VALIDATECHECKPOINTSIGNATURE: "${TILE_PROXY_TUF_VALIDATE_CHECKPOINT:-true}"
# Cache configuration
TILE_PROXY__CACHE__BASEPATH: /var/cache/stellaops/tiles
TILE_PROXY__CACHE__MAXSIZEGB: "${TILE_PROXY_CACHE_MAX_SIZE_GB:-10}"
TILE_PROXY__CACHE__CHECKPOINTTTLMINUTES: "${TILE_PROXY_CHECKPOINT_TTL_MINUTES:-5}"
# Sync job configuration (for air-gapped pre-fetching)
TILE_PROXY__SYNC__ENABLED: "${TILE_PROXY_SYNC_ENABLED:-true}"
TILE_PROXY__SYNC__SCHEDULE: "${TILE_PROXY_SYNC_SCHEDULE:-0 */6 * * *}"
TILE_PROXY__SYNC__DEPTH: "${TILE_PROXY_SYNC_DEPTH:-10000}"
# Request handling
TILE_PROXY__REQUEST__COALESCINGENABLED: "${TILE_PROXY_COALESCING_ENABLED:-true}"
TILE_PROXY__REQUEST__TIMEOUTSECONDS: "${TILE_PROXY_REQUEST_TIMEOUT_SECONDS:-30}"
# Logging
Serilog__MinimumLevel__Default: "${TILE_PROXY_LOG_LEVEL:-Information}"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/_admin/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
networks:
- stellaops
labels: *release-labels

View File

@@ -1,104 +0,0 @@
# Substitutions for docker-compose.airgap.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=airgap-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=25432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=26379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.airgap.local
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:45:00
# Signer
SIGNER_POE_INTROSPECT_URL=file:///offline/poe/introspect.json
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=9446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=9443
# NATS
NATS_CLIENT_PORT=24222

View File

@@ -0,0 +1,48 @@
# =============================================================================
# STELLA OPS CHINA COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for China (SM2/SM3/SM4) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-china.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with SM Remote (production):
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.sm-remote.yml up -d
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=china
# =============================================================================
# SM REMOTE SERVICE CONFIGURATION
# =============================================================================
SM_REMOTE_PORT=56080
# Software-only SM2 provider (for testing/development)
SM_SOFT_ALLOWED=1
# OSCCA-certified HSM configuration (for production)
# Set these when using a certified hardware security module
SM_REMOTE_HSM_URL=
SM_REMOTE_HSM_API_KEY=
SM_REMOTE_HSM_TIMEOUT=30000
# Client certificate authentication for HSM (optional)
SM_REMOTE_CLIENT_CERT_PATH=
SM_REMOTE_CLIENT_CERT_PASSWORD=
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -0,0 +1,40 @@
# =============================================================================
# STELLA OPS EU COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for EU (eIDAS) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-eu.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage for production:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml up -d
#
# Note: EU eIDAS deployments typically integrate with external Qualified Trust
# Service Providers (QTSPs) rather than hosting crypto locally.
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=eu
# =============================================================================
# eIDAS / QTSP CONFIGURATION
# =============================================================================
# Qualified Trust Service Provider integration (configure in application settings)
# EIDAS_QTSP_URL=https://qtsp.example.eu
# EIDAS_QTSP_CLIENT_ID=
# EIDAS_QTSP_CLIENT_SECRET=
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -0,0 +1,51 @@
# =============================================================================
# STELLA OPS RUSSIA COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for Russia (GOST R 34.10-2012) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-russia.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with CryptoPro CSP (production):
# CRYPTOPRO_ACCEPT_EULA=1 docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.cryptopro.yml up -d
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=russia
# =============================================================================
# CRYPTOPRO CSP CONFIGURATION
# =============================================================================
CRYPTOPRO_PORT=18080
# IMPORTANT: Set to 1 to accept CryptoPro EULA (required for production)
CRYPTOPRO_ACCEPT_EULA=0
# CryptoPro container settings
CRYPTOPRO_CONTAINER_NAME=stellaops-signing
CRYPTOPRO_USE_MACHINE_STORE=true
CRYPTOPRO_PROVIDER_TYPE=80
# =============================================================================
# GOST ALGORITHM CONFIGURATION
# =============================================================================
# Default GOST algorithms
CRYPTOPRO_GOST_SIGNATURE_ALGORITHM=GOST R 34.10-2012
CRYPTOPRO_GOST_HASH_ALGORITHM=GOST R 34.11-2012
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -1,91 +0,0 @@
# Substitutions for docker-compose.dev.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=dev-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.localtest.me
AUTHORITY_PORT=8440
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.svc.local/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=nats://nats:4222
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=valkey:6379
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env defaults keep worker/web service aligned with local RustFS and inline secrets
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080/api/v1
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_SECRETS_PROVIDER=inline
SCANNER_SURFACE_SECRETS_ROOT=
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
ZASTAVA_SURFACE_SECRETS_PROVIDER=${SCANNER_SURFACE_SECRETS_PROVIDER}
ZASTAVA_SURFACE_SECRETS_ROOT=${SCANNER_SURFACE_SECRETS_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Nats
SCHEDULER_QUEUE_NATS_URL=nats://nats:4222
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222
# CryptoPro (optional)
CRYPTOPRO_PORT=18080
CRYPTOPRO_ACCEPT_EULA=0

View File

@@ -1,64 +0,0 @@
# Managed mirror profile substitutions
# Core infrastructure credentials
MONGO_INITDB_ROOT_USERNAME=stellaops_mirror
MONGO_INITDB_ROOT_PASSWORD=mirror-password
MINIO_ROOT_USER=stellaops-mirror
MINIO_ROOT_PASSWORD=mirror-minio-secret
RUSTFS_HTTP_PORT=8080
# Scanner surface integration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080/api/v1
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
# Mirror HTTP listeners
MIRROR_GATEWAY_HTTP_PORT=8080
MIRROR_GATEWAY_HTTPS_PORT=9443
# Concelier mirror configuration
CONCELIER_MIRROR_LATEST_SEGMENT=latest
CONCELIER_MIRROR_DIRECTORY_SEGMENT=mirror
CONCELIER_MIRROR_REQUIRE_AUTH=true
CONCELIER_MIRROR_INDEX_BUDGET=600
CONCELIER_MIRROR_DOMAIN_PRIMARY_ID=primary
CONCELIER_MIRROR_DOMAIN_PRIMARY_NAME=Primary Mirror
CONCELIER_MIRROR_DOMAIN_PRIMARY_AUTH=true
CONCELIER_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET=3600
CONCELIER_MIRROR_DOMAIN_SECONDARY_ID=community
CONCELIER_MIRROR_DOMAIN_SECONDARY_NAME=Community Mirror
CONCELIER_MIRROR_DOMAIN_SECONDARY_AUTH=false
CONCELIER_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET=1800
# Authority integration (tokens issued by production Authority)
CONCELIER_AUTHORITY_ENABLED=true
CONCELIER_AUTHORITY_ALLOW_ANON=false
CONCELIER_AUTHORITY_ISSUER=https://authority.stella-ops.org
CONCELIER_AUTHORITY_METADATA=
CONCELIER_AUTHORITY_CLIENT_ID=stellaops-concelier-mirror
CONCELIER_AUTHORITY_SCOPE=concelier.mirror.read
CONCELIER_AUTHORITY_AUDIENCE=api://concelier.mirror
# Excititor mirror configuration
EXCITITOR_MONGO_DATABASE=excititor
EXCITITOR_FILESYSTEM_OVERWRITE=false
EXCITITOR_MIRROR_DOMAIN_PRIMARY_ID=primary
EXCITITOR_MIRROR_DOMAIN_PRIMARY_NAME=Primary Mirror
EXCITITOR_MIRROR_DOMAIN_PRIMARY_AUTH=true
EXCITITOR_MIRROR_DOMAIN_PRIMARY_INDEX_BUDGET=300
EXCITITOR_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET=2400
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_KEY=consensus-json
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_FORMAT=json
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_VIEW=consensus
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_KEY=consensus-openvex
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_FORMAT=openvex
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_VIEW=consensus
EXCITITOR_MIRROR_DOMAIN_SECONDARY_ID=community
EXCITITOR_MIRROR_DOMAIN_SECONDARY_NAME=Community Mirror
EXCITITOR_MIRROR_DOMAIN_SECONDARY_AUTH=false
EXCITITOR_MIRROR_DOMAIN_SECONDARY_INDEX_BUDGET=120
EXCITITOR_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET=600
EXCITITOR_MIRROR_SECONDARY_EXPORT_KEY=community-consensus
EXCITITOR_MIRROR_SECONDARY_EXPORT_FORMAT=json
EXCITITOR_MIRROR_SECONDARY_EXPORT_VIEW=consensus

View File

@@ -1,12 +0,0 @@
# Dev-only overlay env for docker-compose.mock.yaml
# Use together with dev.env.example:
# docker compose --env-file env/dev.env.example --env-file env/mock.env.example -f docker-compose.dev.yaml -f docker-compose.mock.yaml config
# Optional: override ports if you expose mock services
ORCHESTRATOR_PORT=8450
POLICY_REGISTRY_PORT=8451
VEX_LENS_PORT=8452
FINDINGS_LEDGER_PORT=8453
VULN_EXPLORER_API_PORT=8454
PACKS_REGISTRY_PORT=8455
TASK_RUNNER_PORT=8456

View File

@@ -1,109 +0,0 @@
# Substitutions for docker-compose.prod.yaml
# WARNING: Replace all placeholder secrets with values sourced from your secret manager.
# PostgreSQL Database
POSTGRES_USER=stellaops-prod
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.prod.stella-ops.org
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.prod.stella-ops.org/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
# `true` enables signed scanner events for Notify ingestion.
SCANNER_EVENTS_ENABLED=true
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=https://surfacefs.prod.stella-ops.org/api/v1
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=kubernetes
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=stellaops/scanner
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=https://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222
# External reverse proxy (Traefik, Envoy, etc.) that terminates TLS.
FRONTDOOR_NETWORK=stellaops_frontdoor

View File

@@ -1,104 +0,0 @@
# Substitutions for docker-compose.stage.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=stage-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.stage.stella-ops.internal
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.stage.stella-ops.internal/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=kubernetes
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=stellaops/scanner
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222

171
devops/compose/env/stellaops.env.example vendored Normal file
View File

@@ -0,0 +1,171 @@
# =============================================================================
# STELLA OPS ENVIRONMENT CONFIGURATION
# =============================================================================
# Main environment template for docker-compose.stella-ops.yml
# Copy to .env and customize for your deployment.
#
# Usage:
# cp env/stellaops.env.example .env
# docker compose -f docker-compose.stella-ops.yml up -d
#
# =============================================================================
# =============================================================================
# INFRASTRUCTURE
# =============================================================================
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# =============================================================================
# CORE SERVICES
# =============================================================================
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.example.com
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.example.com/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Notify
NOTIFY_WEB_PORT=8446
# Web UI
UI_PORT=8443
# =============================================================================
# SCANNER CONFIGURATION
# =============================================================================
SCANNER_WEB_PORT=8444
# Queue configuration (Valkey only - NATS removed)
SCANNER__QUEUE__BROKER=valkey://valkey:6379
# Event streaming
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=valkey:6379
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface cache configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# =============================================================================
# SCHEDULER CONFIGURATION
# =============================================================================
# Queue configuration (Valkey only - NATS removed)
SCHEDULER__QUEUE__KIND=Valkey
SCHEDULER__QUEUE__VALKEY__URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# =============================================================================
# REKOR / SIGSTORE CONFIGURATION
# =============================================================================
# Rekor server URL (default: public Sigstore, use http://rekor-v2:3000 for local)
REKOR_SERVER_URL=https://rekor.sigstore.dev
REKOR_VERSION=V2
REKOR_TILE_BASE_URL=
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# =============================================================================
# ADVISORY AI CONFIGURATION
# =============================================================================
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# =============================================================================
# CRYPTO CONFIGURATION
# =============================================================================
# Crypto profile: default, china, russia, eu
STELLAOPS_CRYPTO_PROFILE=default
# Enable crypto simulation (for testing)
STELLAOPS_CRYPTO_ENABLE_SIM=0
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
# CryptoPro (Russia only) - requires EULA acceptance
CRYPTOPRO_PORT=18080
CRYPTOPRO_ACCEPT_EULA=0
CRYPTOPRO_CONTAINER_NAME=stellaops-signing
CRYPTOPRO_USE_MACHINE_STORE=true
CRYPTOPRO_PROVIDER_TYPE=80
# SM Remote (China only)
SM_REMOTE_PORT=56080
SM_SOFT_ALLOWED=1
SM_REMOTE_HSM_URL=
SM_REMOTE_HSM_API_KEY=
SM_REMOTE_HSM_TIMEOUT=30000
# =============================================================================
# NETWORKING
# =============================================================================
# External reverse proxy network (Traefik, Envoy, etc.)
FRONTDOOR_NETWORK=stellaops_frontdoor
# =============================================================================
# TELEMETRY (optional)
# =============================================================================
OTEL_GRPC_PORT=4317
OTEL_HTTP_PORT=4318
OTEL_PROMETHEUS_PORT=9464
PROMETHEUS_PORT=9090
TEMPO_PORT=3200
LOKI_PORT=3100
PROMETHEUS_RETENTION=15d

45
devops/compose/env/testing.env.example vendored Normal file
View File

@@ -0,0 +1,45 @@
# =============================================================================
# STELLA OPS TESTING ENVIRONMENT CONFIGURATION
# =============================================================================
# Environment template for docker-compose.testing.yml
# Uses different ports to avoid conflicts with development/production.
#
# Usage:
# cp env/testing.env.example .env
# docker compose -f docker-compose.testing.yml --profile ci up -d
#
# =============================================================================
# =============================================================================
# CI INFRASTRUCTURE (different ports to avoid conflicts)
# =============================================================================
# PostgreSQL Test Database (port 5433)
TEST_POSTGRES_PORT=5433
TEST_POSTGRES_USER=stellaops_ci
TEST_POSTGRES_PASSWORD=ci_test_password
TEST_POSTGRES_DB=stellaops_test
# Valkey Test (port 6380)
TEST_VALKEY_PORT=6380
# RustFS Test (port 8180)
TEST_RUSTFS_PORT=8180
# Mock Registry (port 5001)
TEST_REGISTRY_PORT=5001
# =============================================================================
# GITEA CONFIGURATION
# =============================================================================
TEST_GITEA_PORT=3000
TEST_GITEA_SSH_PORT=3022
# =============================================================================
# SIGSTORE TOOLS
# =============================================================================
# Rekor CLI and Cosign versions (for sigstore profile)
REKOR_CLI_VERSION=v1.4.3
COSIGN_VERSION=v3.0.4

View File

@@ -2,7 +2,7 @@
set -euo pipefail
echo "StellaOps Compose Backup"
echo "This will create a tar.gz of Mongo, MinIO (object-store), and Redis data volumes."
echo "This will create a tar.gz of PostgreSQL, RustFS (object-store), and Valkey data volumes."
read -rp "Proceed? [y/N] " ans
[[ ${ans:-N} =~ ^[Yy]$ ]] || { echo "Aborted."; exit 1; }
@@ -17,9 +17,9 @@ docker compose pause scanner-worker scheduler-worker taskrunner-worker || true
echo "Backing up volumes..."
docker run --rm \
-v stellaops-mongo:/data/db:ro \
-v stellaops-minio:/data/minio:ro \
-v stellaops-redis:/data/redis:ro \
-v stellaops-postgres:/data/postgres:ro \
-v stellaops-rustfs:/data/rustfs:ro \
-v stellaops-valkey:/data/valkey:ro \
-v "$PWD/$OUT_DIR":/out \
alpine sh -c "cd / && tar czf /out/stellaops-backup-$TS.tar.gz data"

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail
echo "WARNING: This will stop the stack and wipe Mongo, MinIO, and Redis volumes."
echo "WARNING: This will stop the stack and wipe PostgreSQL, RustFS, and Valkey volumes."
read -rp "Type 'RESET' to continue: " ans
[[ ${ans:-} == "RESET" ]] || { echo "Aborted."; exit 1; }
docker compose down
for vol in stellaops-mongo stellaops-minio stellaops-redis; do
for vol in stellaops-postgres stellaops-rustfs stellaops-valkey; do
echo "Removing volume $vol"
docker volume rm "$vol" || true
done

View File

@@ -1,161 +0,0 @@
# Tile Proxy Docker Compose
This directory contains the Docker Compose configuration for deploying the StellaOps Tile Proxy service.
## Overview
The Tile Proxy acts as a caching intermediary between StellaOps clients and upstream Rekor transparency logs. It provides:
- **Tile Caching**: Caches tiles locally for faster subsequent requests
- **Request Coalescing**: Deduplicates concurrent requests for the same tile
- **Offline Support**: Serves from cache when upstream is unavailable
- **TUF Integration**: Optional validation using TUF trust anchors
## Quick Start
```bash
# Start with default configuration
docker compose up -d
# Check health
curl http://localhost:8090/_admin/health
# View cache statistics
curl http://localhost:8090/_admin/cache/stats
```
## Configuration
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `REKOR_UPSTREAM_URL` | Upstream Rekor URL | `https://rekor.sigstore.dev` |
| `REKOR_ORIGIN` | Log origin identifier | `rekor.sigstore.dev - 1985497715` |
| `TUF_ENABLED` | Enable TUF integration | `false` |
| `TUF_ROOT_URL` | TUF repository URL | - |
| `TUF_VALIDATE_CHECKPOINT` | Validate checkpoint signatures | `true` |
| `CACHE_MAX_SIZE_GB` | Maximum cache size | `10` |
| `CHECKPOINT_TTL_MINUTES` | Checkpoint cache TTL | `5` |
| `SYNC_ENABLED` | Enable scheduled sync | `true` |
| `SYNC_SCHEDULE` | Sync cron schedule | `0 */6 * * *` |
| `SYNC_DEPTH` | Entries to sync tiles for | `10000` |
| `LOG_LEVEL` | Logging level | `Information` |
### Using a .env file
Create a `.env` file to customize configuration:
```bash
# .env
REKOR_UPSTREAM_URL=https://rekor.sigstore.dev
CACHE_MAX_SIZE_GB=20
SYNC_ENABLED=true
SYNC_SCHEDULE=0 */4 * * *
LOG_LEVEL=Debug
```
## API Endpoints
### Proxy Endpoints
| Endpoint | Description |
|----------|-------------|
| `GET /tile/{level}/{index}` | Get a tile (cache-through) |
| `GET /tile/{level}/{index}.p/{width}` | Get partial tile |
| `GET /checkpoint` | Get current checkpoint |
### Admin Endpoints
| Endpoint | Description |
|----------|-------------|
| `GET /_admin/cache/stats` | Cache statistics |
| `GET /_admin/metrics` | Proxy metrics |
| `POST /_admin/cache/sync` | Trigger manual sync |
| `DELETE /_admin/cache/prune` | Prune old tiles |
| `GET /_admin/health` | Health check |
| `GET /_admin/ready` | Readiness check |
## Volumes
| Volume | Path | Description |
|--------|------|-------------|
| `tile-cache` | `/var/cache/stellaops/tiles` | Cached tiles |
| `tuf-cache` | `/var/cache/stellaops/tuf` | TUF metadata |
## Integration with StellaOps
Configure your StellaOps Attestor to use the tile proxy:
```yaml
attestor:
rekor:
url: http://tile-proxy:8080
# or if running standalone:
# url: http://localhost:8090
```
## Monitoring
### Prometheus Metrics
The tile proxy exposes metrics at `/_admin/metrics`:
```bash
curl http://localhost:8090/_admin/metrics
```
Example response:
```json
{
"cacheHits": 12450,
"cacheMisses": 234,
"hitRatePercent": 98.15,
"upstreamRequests": 234,
"upstreamErrors": 2,
"inflightRequests": 0
}
```
### Health Checks
```bash
# Liveness (is the service running?)
curl http://localhost:8090/_admin/health
# Readiness (can it serve requests?)
curl http://localhost:8090/_admin/ready
```
## Troubleshooting
### Cache is not being used
1. Check cache stats: `curl http://localhost:8090/_admin/cache/stats`
2. Verify cache volume is mounted correctly
3. Check logs for write errors
### Upstream connection failures
1. Check network connectivity to upstream
2. Verify `REKOR_UPSTREAM_URL` is correct
3. Check for firewall/proxy issues
### High memory usage
1. Reduce `CACHE_MAX_SIZE_GB`
2. Trigger manual prune: `curl -X DELETE http://localhost:8090/_admin/cache/prune?targetSizeBytes=5368709120`
## Development
Build the image locally:
```bash
docker compose build
```
Run with local source:
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
```

View File

@@ -1,64 +0,0 @@
# -----------------------------------------------------------------------------
# docker-compose.yml
# Sprint: SPRINT_20260125_002_Attestor_trust_automation
# Task: PROXY-008 - Docker Compose for tile-proxy stack
# Description: Docker Compose configuration for tile-proxy deployment
# -----------------------------------------------------------------------------
services:
tile-proxy:
build:
context: ../../..
dockerfile: src/Attestor/StellaOps.Attestor.TileProxy/Dockerfile
image: stellaops/tile-proxy:latest
container_name: stellaops-tile-proxy
ports:
- "8090:8080"
volumes:
- tile-cache:/var/cache/stellaops/tiles
- tuf-cache:/var/cache/stellaops/tuf
environment:
# Upstream Rekor configuration
- TILE_PROXY__UPSTREAMURL=${REKOR_UPSTREAM_URL:-https://rekor.sigstore.dev}
- TILE_PROXY__ORIGIN=${REKOR_ORIGIN:-rekor.sigstore.dev - 1985497715}
# TUF configuration (optional)
- TILE_PROXY__TUF__ENABLED=${TUF_ENABLED:-false}
- TILE_PROXY__TUF__URL=${TUF_ROOT_URL:-}
- TILE_PROXY__TUF__VALIDATECHECKPOINTSIGNATURE=${TUF_VALIDATE_CHECKPOINT:-true}
# Cache configuration
- TILE_PROXY__CACHE__BASEPATH=/var/cache/stellaops/tiles
- TILE_PROXY__CACHE__MAXSIZEGB=${CACHE_MAX_SIZE_GB:-10}
- TILE_PROXY__CACHE__CHECKPOINTTTLMINUTES=${CHECKPOINT_TTL_MINUTES:-5}
# Sync job configuration
- TILE_PROXY__SYNC__ENABLED=${SYNC_ENABLED:-true}
- TILE_PROXY__SYNC__SCHEDULE=${SYNC_SCHEDULE:-0 */6 * * *}
- TILE_PROXY__SYNC__DEPTH=${SYNC_DEPTH:-10000}
# Request handling
- TILE_PROXY__REQUEST__COALESCINGENABLED=${COALESCING_ENABLED:-true}
- TILE_PROXY__REQUEST__TIMEOUTSECONDS=${REQUEST_TIMEOUT_SECONDS:-30}
# Logging
- Serilog__MinimumLevel__Default=${LOG_LEVEL:-Information}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/_admin/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
restart: unless-stopped
networks:
- stellaops
volumes:
tile-cache:
driver: local
tuf-cache:
driver: local
networks:
stellaops:
driver: bridge

View File

@@ -1,32 +0,0 @@
version: "3.9"
services:
stella-postgres:
image: postgres:18.1
container_name: stella-postgres
restart: unless-stopped
environment:
POSTGRES_USER: stella
POSTGRES_PASSWORD: stella
POSTGRES_DB: stella
ports:
- "5432:5432"
volumes:
- stella-postgres-data:/var/lib/postgresql/data
- ./init:/docker-entrypoint-initdb.d:ro
command:
- "postgres"
- "-c"
- "shared_preload_libraries=pg_stat_statements"
- "-c"
- "pg_stat_statements.track=all"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
interval: 10s
timeout: 5s
retries: 5
volumes:
stella-postgres-data:
driver: local

View File

@@ -1,16 +0,0 @@
# MongoDB Provenance Indexes
Indexes supporting Sprint 401 reachability/provenance queries.
## Available indexes
- `events_by_subject_kind_provenance`: `(subject.digest.sha256, kind, provenance.dsse.rekor.logIndex)` for subject/kind lookups with Rekor presence.
- `events_unproven_by_kind`: `(kind, trust.verified, provenance.dsse.rekor.logIndex)` to find unverified or missing-Rekor events per kind.
- `events_by_rekor_logindex`: `(provenance.dsse.rekor.logIndex)` to audit Rekor alignment.
## Apply
```js
// From mongo shell (connected to provenance database)
load('ops/mongo/indices/events_provenance_indices.js');
```
Indexes are idempotent; rerunning is safe.

View File

@@ -1,89 +0,0 @@
/**
* MongoDB indexes for DSSE provenance queries on the events collection.
* Run with: mongosh stellaops_db < events_provenance_indices.js
*
* These indexes support:
* - Proven VEX/SBOM/SCAN lookup by subject digest
* - Compliance gap queries (unverified events)
* - Rekor log index lookups
* - Backfill service queries
*
* Created: 2025-11-27 (PROV-INDEX-401-030)
* C# equivalent: src/StellaOps.Events.Mongo/MongoIndexes.cs
*/
// Switch to the target database (override via --eval "var dbName='custom'" if needed)
const targetDb = typeof dbName !== 'undefined' ? dbName : 'stellaops';
db = db.getSiblingDB(targetDb);
print(`Creating provenance indexes on ${targetDb}.events...`);
// Index 1: Lookup proven events by subject digest + kind
db.events.createIndex(
{
"subject.digest.sha256": 1,
"kind": 1,
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_by_subject_kind_provenance",
background: true
}
);
print(" - events_by_subject_kind_provenance");
// Index 2: Find unproven evidence by kind (compliance gap queries)
db.events.createIndex(
{
"kind": 1,
"trust.verified": 1,
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_unproven_by_kind",
background: true
}
);
print(" - events_unproven_by_kind");
// Index 3: Direct Rekor log index lookup
db.events.createIndex(
{
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_by_rekor_logindex",
background: true
}
);
print(" - events_by_rekor_logindex");
// Index 4: Envelope digest lookup (for backfill deduplication)
db.events.createIndex(
{
"provenance.dsse.envelopeDigest": 1
},
{
name: "events_by_envelope_digest",
background: true,
sparse: true
}
);
print(" - events_by_envelope_digest");
// Index 5: Timestamp + kind for compliance reporting time ranges
db.events.createIndex(
{
"ts": -1,
"kind": 1,
"trust.verified": 1
},
{
name: "events_by_ts_kind_verified",
background: true
}
);
print(" - events_by_ts_kind_verified");
print("\nProvenance indexes created successfully.");
print("Run 'db.events.getIndexes()' to verify.");

View File

@@ -1,67 +0,0 @@
/**
* MongoDB indexes for the shared reachability store collections used by Signals/Policy/Scanner.
* Run with: mongosh stellaops_db < reachability_store_indices.js
*
* Collections:
* - func_nodes: canonical function nodes keyed by graph + symbol ID and joinable by (purl, symbolDigest)
* - call_edges: canonical call edges keyed by graph and joinable by (purl, symbolDigest)
* - cve_func_hits: per-subject mapping of CVE -> affected/reachable functions with evidence pointers
*
* Created: 2025-12-13 (SIG-STORE-401-016)
*/
// Switch to the target database (override via --eval "var dbName='custom'" if needed)
const targetDb = typeof dbName !== 'undefined' ? dbName : 'stellaops';
db = db.getSiblingDB(targetDb);
print(`Creating reachability store indexes on ${targetDb}...`);
print(`- func_nodes`);
db.func_nodes.createIndex(
{ "graphHash": 1, "symbolId": 1 },
{ name: "func_nodes_by_graph_symbol", unique: true, background: true }
);
db.func_nodes.createIndex(
{ "purl": 1, "symbolDigest": 1 },
{ name: "func_nodes_by_purl_symboldigest", background: true, sparse: true }
);
db.func_nodes.createIndex(
{ "codeId": 1 },
{ name: "func_nodes_by_code_id", background: true, sparse: true }
);
print(`- call_edges`);
db.call_edges.createIndex(
{ "graphHash": 1, "sourceId": 1, "targetId": 1, "type": 1 },
{ name: "call_edges_by_graph_edge", unique: true, background: true }
);
db.call_edges.createIndex(
{ "graphHash": 1, "sourceId": 1 },
{ name: "call_edges_by_graph_source", background: true }
);
db.call_edges.createIndex(
{ "graphHash": 1, "targetId": 1 },
{ name: "call_edges_by_graph_target", background: true }
);
db.call_edges.createIndex(
{ "purl": 1, "symbolDigest": 1 },
{ name: "call_edges_by_purl_symboldigest", background: true, sparse: true }
);
print(`- cve_func_hits`);
db.cve_func_hits.createIndex(
{ "subjectKey": 1, "cveId": 1 },
{ name: "cve_func_hits_by_subject_cve", background: true }
);
db.cve_func_hits.createIndex(
{ "cveId": 1, "purl": 1, "symbolDigest": 1 },
{ name: "cve_func_hits_by_cve_purl_symboldigest", background: true, sparse: true }
);
db.cve_func_hits.createIndex(
{ "graphHash": 1 },
{ name: "cve_func_hits_by_graph", background: true, sparse: true }
);
print("\nReachability store indexes created successfully.");
print("Run db.func_nodes.getIndexes(), db.call_edges.getIndexes(), db.cve_func_hits.getIndexes() to verify.");

View File

@@ -1,125 +0,0 @@
// Task Runner baseline collections and indexes
// Mirrors docs/modules/taskrunner/migrations/pack-run-collections.md (last updated 2025-11-06)
function ensureCollection(name, validator) {
const existing = db.getCollectionNames();
if (!existing.includes(name)) {
db.createCollection(name, { validator, validationLevel: "moderate" });
} else if (validator) {
db.runCommand({ collMod: name, validator, validationLevel: "moderate" });
}
}
const runValidator = {
$jsonSchema: {
bsonType: "object",
required: ["planHash", "plan", "failurePolicy", "requestedAt", "createdAt", "updatedAt", "steps"],
properties: {
_id: { bsonType: "string" },
planHash: { bsonType: "string" },
plan: { bsonType: "object" },
failurePolicy: { bsonType: "object" },
requestedAt: { bsonType: "date" },
createdAt: { bsonType: "date" },
updatedAt: { bsonType: "date" },
steps: {
bsonType: "array",
items: {
bsonType: "object",
required: ["stepId", "status", "attempts"],
properties: {
stepId: { bsonType: "string" },
status: { bsonType: "string" },
attempts: { bsonType: "int" },
kind: { bsonType: "string" },
enabled: { bsonType: "bool" },
continueOnError: { bsonType: "bool" },
maxParallel: { bsonType: ["int", "null"] },
approvalId: { bsonType: ["string", "null"] },
gateMessage: { bsonType: ["string", "null"] },
lastTransitionAt: { bsonType: ["date", "null"] },
nextAttemptAt: { bsonType: ["date", "null"] },
statusReason: { bsonType: ["string", "null"] }
}
}
},
tenantId: { bsonType: ["string", "null"] }
}
}
};
const logValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "sequence", "timestamp", "level", "eventType", "message"],
properties: {
runId: { bsonType: "string" },
sequence: { bsonType: "long" },
timestamp: { bsonType: "date" },
level: { bsonType: "string" },
eventType: { bsonType: "string" },
message: { bsonType: "string" },
stepId: { bsonType: ["string", "null"] },
metadata: { bsonType: ["object", "null"] }
}
}
};
const artifactsValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "name", "type", "status", "capturedAt"],
properties: {
runId: { bsonType: "string" },
name: { bsonType: "string" },
type: { bsonType: "string" },
status: { bsonType: "string" },
capturedAt: { bsonType: "date" },
sourcePath: { bsonType: ["string", "null"] },
storedPath: { bsonType: ["string", "null"] },
notes: { bsonType: ["string", "null"] },
expression: { bsonType: ["object", "null"] }
}
}
};
const approvalsValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "approvalId", "requestedAt", "status"],
properties: {
runId: { bsonType: "string" },
approvalId: { bsonType: "string" },
requiredGrants: { bsonType: "array", items: { bsonType: "string" } },
stepIds: { bsonType: "array", items: { bsonType: "string" } },
messages: { bsonType: "array", items: { bsonType: "string" } },
reasonTemplate: { bsonType: ["string", "null"] },
requestedAt: { bsonType: "date" },
status: { bsonType: "string" },
actorId: { bsonType: ["string", "null"] },
completedAt: { bsonType: ["date", "null"] },
summary: { bsonType: ["string", "null"] }
}
}
};
ensureCollection("pack_runs", runValidator);
ensureCollection("pack_run_logs", logValidator);
ensureCollection("pack_artifacts", artifactsValidator);
ensureCollection("pack_run_approvals", approvalsValidator);
// Indexes for pack_runs
db.pack_runs.createIndex({ updatedAt: -1 }, { name: "pack_runs_updatedAt_desc" });
db.pack_runs.createIndex({ tenantId: 1, updatedAt: -1 }, { name: "pack_runs_tenant_updatedAt_desc", sparse: true });
// Indexes for pack_run_logs
db.pack_run_logs.createIndex({ runId: 1, sequence: 1 }, { unique: true, name: "pack_run_logs_run_sequence" });
db.pack_run_logs.createIndex({ runId: 1, timestamp: 1 }, { name: "pack_run_logs_run_timestamp" });
// Indexes for pack_artifacts
db.pack_artifacts.createIndex({ runId: 1, name: 1 }, { unique: true, name: "pack_artifacts_run_name" });
db.pack_artifacts.createIndex({ runId: 1 }, { name: "pack_artifacts_run" });
// Indexes for pack_run_approvals
db.pack_run_approvals.createIndex({ runId: 1, approvalId: 1 }, { unique: true, name: "pack_run_approvals_run_approval" });
db.pack_run_approvals.createIndex({ runId: 1, status: 1 }, { name: "pack_run_approvals_run_status" });

View File

@@ -1,7 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: exportcenter-minio
name: exportcenter-rustfs
stringData:
accesskey: REPLACE_ME
secretkey: REPLACE_ME

View File

@@ -2,34 +2,44 @@
This directory contains operational tooling, deployment configurations, and CI/CD support for StellaOps.
## Infrastructure Stack
| Component | Technology | Purpose |
|-----------|------------|---------|
| Database | PostgreSQL 18.1 | Primary data store |
| Messaging/Cache | Valkey 9.0.1 | Queues, caching, pub/sub |
| Object Storage | RustFS | S3-compatible storage |
| Transparency Log | Rekor v2 | Sigstore transparency |
## Directory Structure
```
devops/
├── ansible/ # Ansible playbooks for deployment automation
├── compose/ # Docker Compose configurations
├── compose/ # Docker Compose configurations (consolidated)
│ ├── docker-compose.stella-ops.yml # Main stack
│ ├── docker-compose.telemetry.yml # Observability stack
│ ├── docker-compose.testing.yml # CI/testing services
│ └── docker-compose.compliance-*.yml # Regional crypto overlays
├── database/ # Database schemas and migrations
│ ├── mongo/ # MongoDB (deprecated)
│ └── postgres/ # PostgreSQL schemas
│ ├── migrations/ # Schema migration scripts
│ └── postgres/ # PostgreSQL configuration
├── docker/ # Dockerfiles and container build scripts
│ ├── Dockerfile.ci # CI runner environment
│ └── base/ # Base images
│ └── repro-builders/ # Reproducible build containers
├── docs/ # This documentation
├── gitlab/ # GitLab CI templates (legacy)
├── helm/ # Helm charts for Kubernetes deployment
│ └── stellaops/ # Main Helm chart with env-specific values
├── logging/ # Logging configuration templates
├── serilog.json.template # Serilog config for .NET services
│ ├── filebeat.yml # Filebeat for log shipping
│ └── logrotate.conf # Log rotation configuration
├── observability/ # Monitoring, metrics, and tracing
├── observability/ # Monitoring, alerting, and dashboards
├── offline/ # Air-gap deployment support
│ ├── airgap/ # Air-gap bundle scripts
│ └── kit/ # Offline installation kit
├── releases/ # Release artifacts and manifests
├── scripts/ # Operational scripts
├── scripts/ # Operational scripts and libraries
├── services/ # Per-service operational configs
├── telemetry/ # OpenTelemetry and metrics configs
└── tools/ # DevOps tooling
├── telemetry/ # OpenTelemetry collector and storage
└── tools/ # DevOps tooling and helpers
```
## Quick Start

View File

@@ -9,8 +9,8 @@ This directory contains deterministic deployment bundles for the core Stella Ops
- `compose/docker-compose.mirror.yaml` managed mirror bundle for `*.stella-ops.org` with gateway cache and multi-tenant auth.
- `compose/docker-compose.telemetry.yaml` optional OpenTelemetry collector overlay (mutual TLS, OTLP pipelines).
- `compose/docker-compose.telemetry-storage.yaml` optional Prometheus/Tempo/Loki stack for observability backends.
- `helm/stellaops/` multi-profile Helm chart with values files for dev/stage/airgap.
- `helm/stellaops/INSTALL.md` install/runbook for prod and airgap profiles with digest pins.
- `helm/stellaops/` multi-profile Helm chart with values files for dev/stage/airgap.
- `helm/stellaops/INSTALL.md` install/runbook for prod and airgap profiles with digest pins.
- `telemetry/` shared OpenTelemetry collector configuration and certificate artefacts (generated via tooling).
- `tools/validate-profiles.sh` helper that runs `docker compose config` and `helm lint/template` for every profile.
@@ -24,37 +24,30 @@ This directory contains deterministic deployment bundles for the core Stella Ops
`python ./ops/devops/telemetry/smoke_otel_collector.py` to verify the OTLP endpoints.
5. Commit the change alongside any documentation updates (e.g. install guide cross-links).
Maintaining the digest linkage keeps offline/air-gapped installs reproducible and avoids tag drift between environments.
### Surface.Env rollout warnings
- Compose (`deploy/compose/env/*.env.example`) and Helm (`deploy/helm/stellaops/values-*.yaml`) now seed `SCANNER_SURFACE_*` _and_ `ZASTAVA_SURFACE_*` variables so Scanner Worker/WebService and Zastava Observer/Webhook resolve cache roots, Surface.FS endpoints, and secrets providers through `StellaOps.Scanner.Surface.Env`.
- During rollout, watch for structured log messages (and readiness output) prefixed with `surface.env.`—for example, `surface.env.cache_root_missing`, `surface.env.endpoint_unreachable`, or `surface.env.secrets_provider_invalid`.
- Treat these warnings as deployment blockers: update the endpoint/cache/secrets values or permissions before promoting the environment, otherwise workers will fail fast at startup.
- Air-gapped bundles default the secrets provider to `file` with `/etc/stellaops/secrets`; connected clusters default to `kubernetes`. Adjust the provider/root pair if your secrets manager differs.
- Secret provisioning workflows for Kubernetes/Compose/Offline Kit are documented in `ops/devops/secrets/surface-secrets-provisioning.md`; follow that for `Surface.Secrets` handles and RBAC/permissions.
### Mongo2Go OpenSSL prerequisites
- Linux runners that execute Mongo2Go-backed suites (Excititor, Scheduler, Graph, etc.) must expose OpenSSL 1.1 (`libcrypto.so.1.1`, `libssl.so.1.1`). The canonical copies live under `tests/native/openssl-1.1/linux-x64`.
- Export `LD_LIBRARY_PATH="$(git rev-parse --show-toplevel)/tests/native/openssl-1.1/linux-x64:${LD_LIBRARY_PATH:-}"` before invoking `dotnet test`. Example:\
`LD_LIBRARY_PATH="$(pwd)/tests/native/openssl-1.1/linux-x64" dotnet test src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj --nologo`.
- CI agents or Dockerfiles that host these tests should either mount the directory into the container or copy the two `.so` files into a directory that is already on the runtime library path.
### Additional tooling
- `deploy/tools/check-channel-alignment.py` verifies that Helm/Compose profiles reference the exact images listed in a release manifest. Run it for each channel before promoting a release.
- `ops/devops/telemetry/generate_dev_tls.sh` produces local CA/server/client certificates for Compose-based collector testing.
- `ops/devops/telemetry/smoke_otel_collector.py` sends OTLP traffic and asserts the collector accepted traces, metrics, and logs.
- `ops/devops/telemetry/package_offline_bundle.py` packages telemetry assets (config/Helm/Compose) into a signed tarball for air-gapped installs.
- `docs/modules/devops/runbooks/deployment-upgrade.md` end-to-end instructions for upgrade, rollback, and channel promotion workflows (Helm + Compose).
### Tenancy observability & chaos (DEVOPS-TEN-49-001)
- Import `ops/devops/tenant/recording-rules.yaml` and `ops/devops/tenant/alerts.yaml` into your Prometheus rule groups.
- Add Grafana dashboard `ops/devops/tenant/dashboards/tenant-audit.json` (folder `StellaOps / Tenancy`) to watch latency/error/auth cache ratios per tenant/service.
- Run the multi-tenant k6 harness `ops/devops/tenant/k6-tenant-load.js` to hit 5k concurrent tenant-labelled requests (defaults to read/write 90/10, header `X-StellaOps-Tenant`).
- Execute JWKS outage chaos via `ops/devops/tenant/jwks-chaos.sh` on an isolated agent with sudo/iptables; watch alerts `jwks_cache_miss_spike` and `tenant_auth_failures_spike` while load is active.
Maintaining the digest linkage keeps offline/air-gapped installs reproducible and avoids tag drift between environments.
### Surface.Env rollout warnings
- Compose (`deploy/compose/env/*.env.example`) and Helm (`deploy/helm/stellaops/values-*.yaml`) now seed `SCANNER_SURFACE_*` _and_ `ZASTAVA_SURFACE_*` variables so Scanner Worker/WebService and Zastava Observer/Webhook resolve cache roots, Surface.FS endpoints, and secrets providers through `StellaOps.Scanner.Surface.Env`.
- During rollout, watch for structured log messages (and readiness output) prefixed with `surface.env.`—for example, `surface.env.cache_root_missing`, `surface.env.endpoint_unreachable`, or `surface.env.secrets_provider_invalid`.
- Treat these warnings as deployment blockers: update the endpoint/cache/secrets values or permissions before promoting the environment, otherwise workers will fail fast at startup.
- Air-gapped bundles default the secrets provider to `file` with `/etc/stellaops/secrets`; connected clusters default to `kubernetes`. Adjust the provider/root pair if your secrets manager differs.
- Secret provisioning workflows for Kubernetes/Compose/Offline Kit are documented in `ops/devops/secrets/surface-secrets-provisioning.md`; follow that for `Surface.Secrets` handles and RBAC/permissions.
### Additional tooling
- `deploy/tools/check-channel-alignment.py` verifies that Helm/Compose profiles reference the exact images listed in a release manifest. Run it for each channel before promoting a release.
- `ops/devops/telemetry/generate_dev_tls.sh` produces local CA/server/client certificates for Compose-based collector testing.
- `ops/devops/telemetry/smoke_otel_collector.py` sends OTLP traffic and asserts the collector accepted traces, metrics, and logs.
- `ops/devops/telemetry/package_offline_bundle.py` packages telemetry assets (config/Helm/Compose) into a signed tarball for air-gapped installs.
- `docs/modules/devops/runbooks/deployment-upgrade.md` end-to-end instructions for upgrade, rollback, and channel promotion workflows (Helm + Compose).
### Tenancy observability & chaos (DEVOPS-TEN-49-001)
- Import `ops/devops/tenant/recording-rules.yaml` and `ops/devops/tenant/alerts.yaml` into your Prometheus rule groups.
- Add Grafana dashboard `ops/devops/tenant/dashboards/tenant-audit.json` (folder `StellaOps / Tenancy`) to watch latency/error/auth cache ratios per tenant/service.
- Run the multi-tenant k6 harness `ops/devops/tenant/k6-tenant-load.js` to hit 5k concurrent tenant-labelled requests (defaults to read/write 90/10, header `X-StellaOps-Tenant`).
- Execute JWKS outage chaos via `ops/devops/tenant/jwks-chaos.sh` on an isolated agent with sudo/iptables; watch alerts `jwks_cache_miss_spike` and `tenant_auth_failures_spike` while load is active.
## CI smoke checks

View File

@@ -53,9 +53,8 @@ configMaps:
data:
notify.yaml: |
storage:
driver: mongo
connectionString: "mongodb://notify-mongo.prod.svc.cluster.local:27017"
database: "stellaops_notify"
driver: postgres
connectionString: "Host=stellaops-postgres;Port=5432;Database=notify;Username=stellaops;Password=stellaops"
commandTimeoutSeconds: 60
authority:
@@ -104,7 +103,9 @@ services:
port: 8440
env:
STELLAOPS_AUTHORITY__ISSUER: "https://stellaops-authority:8440"
STELLAOPS_AUTHORITY__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=authority;Username=stellaops;Password=stellaops"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
STELLAOPS_AUTHORITY__ALLOWANONYMOUSFALLBACK: "false"
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:ddbbd664a42846cea6b40fca6465bc679b30f72851158f300d01a8571c5478fc
@@ -113,23 +114,27 @@ services:
env:
SIGNER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
SIGNER__POE__INTROSPECTURL: "file:///offline/poe/introspect.json"
SIGNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=signer;Username=stellaops;Password=stellaops"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:1ff0a3124d66d3a2702d8e421df40fbd98cc75cb605d95510598ebbae1433c50
service:
port: 8442
env:
ATTESTOR__SIGNER__BASEURL: "https://stellaops-signer:8441"
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=attestor;Username=stellaops;Password=stellaops"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
service:
port: 8445
env:
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "stellaops-airgap"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "airgap-minio-secret"
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=concelier;Username=stellaops;Password=stellaops"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "00:45:00"
@@ -144,16 +149,17 @@ services:
service:
port: 8444
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -169,16 +175,17 @@ services:
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:eea5d6cfe7835950c5ec7a735a651f2f0d727d3e470cf9027a4a402ea89c4fb5
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -203,6 +210,8 @@ services:
port: 8446
env:
DOTNET_ENVIRONMENT: Production
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "stellaops-valkey:6379"
configMounts:
- name: notify-config
mountPath: /app/etc/notify.yaml
@@ -212,7 +221,8 @@ services:
image: registry.stella-ops.org/stellaops/excititor@sha256:65c0ee13f773efe920d7181512349a09d363ab3f3e177d276136bd2742325a68
env:
EXCITITOR__CONCELIER__BASEURL: "https://stellaops-concelier:8445"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-airgap:stellaops-airgap@stellaops-mongo:27017"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=excititor;Username=stellaops;Password=stellaops"
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2-airgap
service:
@@ -254,42 +264,38 @@ services:
targetPort: 8443
env:
STELLAOPS_UI__BACKEND__BASEURL: "https://stellaops-scanner-web:8444"
mongo:
# Infrastructure services
postgres:
class: infrastructure
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
service:
port: 27017
command:
- mongod
- --bind_ip_all
port: 5432
env:
MONGO_INITDB_ROOT_USERNAME: stellaops-airgap
MONGO_INITDB_ROOT_PASSWORD: stellaops-airgap
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: stellaops
volumeMounts:
- name: mongo-data
mountPath: /data/db
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaims:
- name: mongo-data
claimName: stellaops-mongo-data
minio:
- name: postgres-data
claimName: stellaops-postgres-data
valkey:
class: infrastructure
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
image: docker.io/valkey/valkey:9.0.1-alpine
service:
port: 9000
port: 6379
command:
- server
- /data
- --console-address
- :9001
env:
MINIO_ROOT_USER: stellaops-airgap
MINIO_ROOT_PASSWORD: airgap-minio-secret
- valkey-server
- --appendonly
- "yes"
volumeMounts:
- name: minio-data
- name: valkey-data
mountPath: /data
volumeClaims:
- name: minio-data
claimName: stellaops-minio-data
- name: valkey-data
claimName: stellaops-valkey-data
rustfs:
class: infrastructure
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
@@ -310,19 +316,3 @@ services:
volumeClaims:
- name: rustfs-data
claimName: stellaops-rustfs-data
nats:
class: infrastructure
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
service:
port: 4222
command:
- -js
- -sd
- /data
volumeMounts:
- name: nats-data
mountPath: /data
volumeClaims:
- name: nats-data
claimName: stellaops-nats-data

View File

@@ -21,9 +21,8 @@ configMaps:
data:
notify.yaml: |
storage:
driver: mongo
connectionString: "mongodb://notify-mongo.dev.svc.cluster.local:27017"
database: "stellaops_notify_dev"
driver: postgres
connectionString: "Host=stellaops-postgres;Port=5432;Database=notify;Username=stellaops;Password=stellaops"
commandTimeoutSeconds: 30
authority:
@@ -63,6 +62,7 @@ configMaps:
STELLAOPS_POLICY_ENGINE__ACTIVATION__FORCETWOPERSONAPPROVAL: "false"
STELLAOPS_POLICY_ENGINE__ACTIVATION__DEFAULTREQUIRESTWOPERSONAPPROVAL: "false"
STELLAOPS_POLICY_ENGINE__ACTIVATION__EMITAUDITLOGS: "true"
services:
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
@@ -70,7 +70,9 @@ services:
port: 8440
env:
STELLAOPS_AUTHORITY__ISSUER: "https://stellaops-authority:8440"
STELLAOPS_AUTHORITY__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=authority;Username=stellaops;Password=stellaops"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
signer:
@@ -80,23 +82,27 @@ services:
env:
SIGNER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
SIGNER__POE__INTROSPECTURL: "https://licensing.svc.local/introspect"
SIGNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=signer;Username=stellaops;Password=stellaops"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
service:
port: 8442
env:
ATTESTOR__SIGNER__BASEURL: "https://stellaops-signer:8441"
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=attestor;Username=stellaops;Password=stellaops"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
service:
port: 8445
env:
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "stellaops"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "dev-minio-secret"
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=concelier;Username=stellaops;Password=stellaops"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
volumeMounts:
- name: concelier-jobs
@@ -109,16 +115,17 @@ services:
service:
port: 8444
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -134,16 +141,17 @@ services:
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -157,6 +165,8 @@ services:
port: 8446
env:
DOTNET_ENVIRONMENT: Development
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "stellaops-valkey:6379"
configMounts:
- name: notify-config
mountPath: /app/etc/notify.yaml
@@ -166,7 +176,8 @@ services:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
env:
EXCITITOR__CONCELIER__BASEURL: "https://stellaops-concelier:8445"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops:stellaops@stellaops-mongo:27017"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=excititor;Username=stellaops;Password=stellaops"
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0-edge
service:
@@ -207,41 +218,37 @@ services:
port: 8443
env:
STELLAOPS_UI__BACKEND__BASEURL: "https://stellaops-scanner-web:8444"
mongo:
# Infrastructure services
postgres:
class: infrastructure
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
service:
port: 27017
command:
- mongod
- --bind_ip_all
port: 5432
env:
MONGO_INITDB_ROOT_USERNAME: stellaops
MONGO_INITDB_ROOT_PASSWORD: stellaops
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: stellaops
volumeMounts:
- name: mongo-data
mountPath: /data/db
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumes:
- name: mongo-data
- name: postgres-data
emptyDir: {}
minio:
valkey:
class: infrastructure
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
image: docker.io/valkey/valkey:9.0.1-alpine
service:
port: 9000
port: 6379
command:
- server
- /data
- --console-address
- :9001
env:
MINIO_ROOT_USER: stellaops
MINIO_ROOT_PASSWORD: dev-minio-secret
- valkey-server
- --appendonly
- "yes"
volumeMounts:
- name: minio-data
- name: valkey-data
mountPath: /data
volumes:
- name: minio-data
- name: valkey-data
emptyDir: {}
rustfs:
class: infrastructure
@@ -257,19 +264,3 @@ services:
volumes:
- name: rustfs-data
emptyDir: {}
nats:
class: infrastructure
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
service:
port: 4222
command:
- -js
- -sd
- /data
volumeMounts:
- name: nats-data
mountPath: /data
volumes:
- name: nats-data
emptyDir: {}

View File

@@ -3,10 +3,10 @@ exportcenter:
repository: registry.stella-ops.org/export-center
tag: latest
objectStorage:
endpoint: http://minio:9000
endpoint: http://rustfs:8080
bucket: export-prod
accessKeySecret: exportcenter-minio
secretKeySecret: exportcenter-minio
accessKeySecret: exportcenter-rustfs
secretKeySecret: exportcenter-rustfs
signing:
kmsKey: exportcenter-kms
kmsRegion: us-east-1

View File

@@ -106,28 +106,28 @@ configMaps:
proxy_cache off;
}
location / {
return 404;
}
policy-engine-activation:
data:
STELLAOPS_POLICY_ENGINE__ACTIVATION__FORCETWOPERSONAPPROVAL: "true"
STELLAOPS_POLICY_ENGINE__ACTIVATION__DEFAULTREQUIRESTWOPERSONAPPROVAL: "true"
STELLAOPS_POLICY_ENGINE__ACTIVATION__EMITAUDITLOGS: "true"
services:
location / {
return 404;
}
policy-engine-activation:
data:
STELLAOPS_POLICY_ENGINE__ACTIVATION__FORCETWOPERSONAPPROVAL: "true"
STELLAOPS_POLICY_ENGINE__ACTIVATION__DEFAULTREQUIRESTWOPERSONAPPROVAL: "true"
STELLAOPS_POLICY_ENGINE__ACTIVATION__EMITAUDITLOGS: "true"
services:
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
service:
port: 8445
env:
ASPNETCORE_URLS: "http://+:8445"
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops_mirror:mirror-password@stellaops-mongo:27017/concelier?authSource=admin"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "stellaops-mirror"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "mirror-minio-secret"
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=concelier;Username=stellaops;Password=stellaops"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
CONCELIER__TELEMETRY__SERVICENAME: "stellaops-concelier-mirror"
CONCELIER__MIRROR__ENABLED: "true"
CONCELIER__MIRROR__EXPORTROOT: "/exports/json"
@@ -183,8 +183,8 @@ services:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
env:
ASPNETCORE_URLS: "http://+:8448"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops_mirror:mirror-password@stellaops-mongo:27017/excititor?authSource=admin"
EXCITITOR__STORAGE__MONGO__DATABASENAME: "excititor"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=excititor;Username=stellaops;Password=stellaops"
EXCITITOR__ARTIFACTS__FILESYSTEM__ROOT: "/exports"
EXCITITOR__ARTIFACTS__FILESYSTEM__OVERWRITEEXISTING: "false"
EXCITITOR__MIRROR__DOMAINS__0__ID: "primary"
@@ -220,43 +220,59 @@ services:
secret:
secretName: excititor-mirror-auth
mongo:
# Infrastructure services
postgres:
class: infrastructure
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
service:
port: 27017
command:
- mongod
- --bind_ip_all
port: 5432
env:
MONGO_INITDB_ROOT_USERNAME: "stellaops_mirror"
MONGO_INITDB_ROOT_PASSWORD: "mirror-password"
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: stellaops
volumeMounts:
- name: mongo-data
mountPath: /data/db
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaims:
- name: mongo-data
claimName: mirror-mongo-data
- name: postgres-data
claimName: mirror-postgres-data
minio:
valkey:
class: infrastructure
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
image: docker.io/valkey/valkey:9.0.1-alpine
service:
port: 9000
port: 6379
command:
- server
- /data
- --console-address
- :9001
env:
MINIO_ROOT_USER: "stellaops-mirror"
MINIO_ROOT_PASSWORD: "mirror-minio-secret"
- valkey-server
- --appendonly
- "yes"
volumeMounts:
- name: minio-data
- name: valkey-data
mountPath: /data
volumeClaims:
- name: minio-data
claimName: mirror-minio-data
- name: valkey-data
claimName: mirror-valkey-data
rustfs:
class: infrastructure
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
service:
port: 8080
command:
- serve
- --listen
- 0.0.0.0:8080
- --root
- /data
env:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumeMounts:
- name: rustfs-data
mountPath: /data
volumeClaims:
- name: rustfs-data
claimName: mirror-rustfs-data
mirror-gateway:
image: docker.io/library/nginx@sha256:208b70eefac13ee9be00e486f79c695b15cef861c680527171a27d253d834be9

View File

@@ -75,9 +75,8 @@ configMaps:
data:
notify.yaml: |
storage:
driver: mongo
connectionString: "mongodb://stellaops-mongo:27017"
database: "stellaops_notify_prod"
driver: postgres
connectionString: "Host=stellaops-postgres;Port=5432;Database=notify;Username=stellaops;Password=stellaops"
commandTimeoutSeconds: 45
authority:
@@ -124,6 +123,9 @@ services:
port: 8440
env:
STELLAOPS_AUTHORITY__ISSUER: "https://authority.prod.stella-ops.org"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=authority;Username=stellaops;Password=stellaops"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
envFrom:
@@ -136,6 +138,9 @@ services:
env:
SIGNER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
SIGNER__POE__INTROSPECTURL: "https://licensing.prod.stella-ops.org/introspect"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=signer;Username=stellaops;Password=stellaops"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
envFrom:
- secretRef:
name: stellaops-prod-core
@@ -145,6 +150,9 @@ services:
port: 8442
env:
ATTESTOR__SIGNER__BASEURL: "https://stellaops-signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=attestor;Username=stellaops;Password=stellaops"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
envFrom:
- secretRef:
name: stellaops-prod-core
@@ -153,7 +161,10 @@ services:
service:
port: 8445
env:
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-minio:9000"
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=concelier;Username=stellaops;Password=stellaops"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
envFrom:
- secretRef:
@@ -169,15 +180,17 @@ services:
service:
port: 8444
env:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "true"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -197,15 +210,17 @@ services:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
replicas: 3
env:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "true"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -222,6 +237,8 @@ services:
port: 8446
env:
DOTNET_ENVIRONMENT: Production
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "stellaops-valkey:6379"
envFrom:
- secretRef:
name: stellaops-prod-notify
@@ -234,6 +251,8 @@ services:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
env:
EXCITITOR__CONCELIER__BASEURL: "https://stellaops-concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=excititor;Username=stellaops;Password=stellaops"
envFrom:
- secretRef:
name: stellaops-prod-core
@@ -283,42 +302,37 @@ services:
port: 8443
env:
STELLAOPS_UI__BACKEND__BASEURL: "https://stellaops-scanner-web:8444"
mongo:
# Infrastructure services
postgres:
class: infrastructure
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
service:
port: 27017
command:
- mongod
- --bind_ip_all
envFrom:
- secretRef:
name: stellaops-prod-mongo
port: 5432
env:
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: stellaops
volumeMounts:
- name: mongo-data
mountPath: /data/db
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaims:
- name: mongo-data
claimName: stellaops-mongo-data
minio:
- name: postgres-data
claimName: stellaops-postgres-data
valkey:
class: infrastructure
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
image: docker.io/valkey/valkey:9.0.1-alpine
service:
port: 9000
port: 6379
command:
- server
- /data
- --console-address
- :9001
envFrom:
- secretRef:
name: stellaops-prod-minio
- valkey-server
- --appendonly
- "yes"
volumeMounts:
- name: minio-data
- name: valkey-data
mountPath: /data
volumeClaims:
- name: minio-data
claimName: stellaops-minio-data
- name: valkey-data
claimName: stellaops-valkey-data
rustfs:
class: infrastructure
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2

View File

@@ -21,9 +21,8 @@ configMaps:
data:
notify.yaml: |
storage:
driver: mongo
connectionString: "mongodb://notify-mongo.stage.svc.cluster.local:27017"
database: "stellaops_notify_stage"
driver: postgres
connectionString: "Host=stellaops-postgres;Port=5432;Database=notify;Username=stellaops;Password=stellaops"
commandTimeoutSeconds: 45
authority:
@@ -70,7 +69,9 @@ services:
port: 8440
env:
STELLAOPS_AUTHORITY__ISSUER: "https://stellaops-authority:8440"
STELLAOPS_AUTHORITY__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=authority;Username=stellaops;Password=stellaops"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
signer:
@@ -80,23 +81,27 @@ services:
env:
SIGNER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
SIGNER__POE__INTROSPECTURL: "https://licensing.stage.stella-ops.internal/introspect"
SIGNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=signer;Username=stellaops;Password=stellaops"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
service:
port: 8442
env:
ATTESTOR__SIGNER__BASEURL: "https://stellaops-signer:8441"
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=attestor;Username=stellaops;Password=stellaops"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
service:
port: 8445
env:
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "stellaops-stage"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "stage-minio-secret"
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=concelier;Username=stellaops;Password=stellaops"
CONCELIER__STORAGE__S3__ENDPOINT: "http://stellaops-rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://stellaops-authority:8440"
volumeMounts:
- name: concelier-jobs
@@ -109,16 +114,17 @@ services:
service:
port: 8444
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -135,16 +141,17 @@ services:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
replicas: 2
env:
SCANNER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=scanner;Username=stellaops;Password=stellaops"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "stellaops-valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://stellaops-rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://stellaops-nats:4222"
SCANNER__QUEUE__BROKER: "valkey://stellaops-valkey:6379"
SCANNER__EVENTS__ENABLED: "false"
# Valkey (Redis-compatible) cache driver; keep "redis" for protocol compatibility.
SCANNER__EVENTS__DRIVER: "redis"
SCANNER__EVENTS__DSN: ""
SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "stellaops-valkey:6379"
SCANNER__EVENTS__STREAM: "stella.events"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "5"
SCANNER__EVENTS__MAXSTREAMLENGTH: "10000"
@@ -158,6 +165,8 @@ services:
port: 8446
env:
DOTNET_ENVIRONMENT: Production
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "stellaops-valkey:6379"
configMounts:
- name: notify-config
mountPath: /app/etc/notify.yaml
@@ -167,49 +176,46 @@ services:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
env:
EXCITITOR__CONCELIER__BASEURL: "https://stellaops-concelier:8445"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://stellaops-stage:stellaops-stage@stellaops-mongo:27017"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=stellaops-postgres;Port=5432;Database=excititor;Username=stellaops;Password=stellaops"
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
service:
port: 8443
env:
STELLAOPS_UI__BACKEND__BASEURL: "https://stellaops-scanner-web:8444"
mongo:
# Infrastructure services
postgres:
class: infrastructure
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
service:
port: 27017
command:
- mongod
- --bind_ip_all
port: 5432
env:
MONGO_INITDB_ROOT_USERNAME: stellaops-stage
MONGO_INITDB_ROOT_PASSWORD: stellaops-stage
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: stellaops
volumeMounts:
- name: mongo-data
mountPath: /data/db
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaims:
- name: mongo-data
claimName: stellaops-mongo-data
minio:
- name: postgres-data
claimName: stellaops-postgres-data
valkey:
class: infrastructure
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
image: docker.io/valkey/valkey:9.0.1-alpine
service:
port: 9000
port: 6379
command:
- server
- /data
- --console-address
- :9001
env:
MINIO_ROOT_USER: stellaops-stage
MINIO_ROOT_PASSWORD: stage-minio-secret
- valkey-server
- --appendonly
- "yes"
volumeMounts:
- name: minio-data
- name: valkey-data
mountPath: /data
volumeClaims:
- name: minio-data
claimName: stellaops-minio-data
- name: valkey-data
claimName: stellaops-valkey-data
rustfs:
class: infrastructure
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
@@ -230,19 +236,3 @@ services:
volumeClaims:
- name: rustfs-data
claimName: stellaops-rustfs-data
nats:
class: infrastructure
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
service:
port: 4222
command:
- -js
- -sd
- /data
volumeMounts:
- name: nats-data
mountPath: /data
volumeClaims:
- name: nats-data
claimName: stellaops-nats-data

View File

@@ -171,13 +171,10 @@ configMaps:
tenantHeader: X-StellaOps-Tenant
seedCsafPublishers: true
csafSeedPath: data/csaf-publishers.json
Mongo:
connectionString: mongodb://mongo:27017
database: issuer-directory
issuersCollection: issuers
issuerKeysCollection: issuer_keys
issuerTrustCollection: issuer_trust_overrides
auditCollection: issuer_audit
Storage:
Driver: postgres
Postgres:
ConnectionString: Host=postgres;Port=5432;Database=issuer_directory;Username=stellaops;Password=stellaops
policy-engine-activation:
data:
@@ -224,10 +221,10 @@ services:
- dotnet
- StellaOps.Scheduler.Worker.Host.dll
env:
SCHEDULER__QUEUE__KIND: Nats
SCHEDULER__QUEUE__NATS__URL: nats://nats:4222
SCHEDULER__STORAGE__CONNECTIONSTRING: mongodb://scheduler-mongo:27017
SCHEDULER__STORAGE__DATABASE: stellaops_scheduler
SCHEDULER__QUEUE__KIND: Valkey
SCHEDULER__QUEUE__VALKEY__URL: valkey:6379
SCHEDULER__STORAGE__DRIVER: postgres
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: Host=postgres;Port=5432;Database=scheduler;Username=stellaops;Password=stellaops
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: http://scanner-web:8444
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0-edge

View File

@@ -16,18 +16,20 @@ release:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:eea5d6cfe7835950c5ec7a735a651f2f0d727d3e470cf9027a4a402ea89c4fb5
- name: concelier
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
- name: excititor
image: registry.stella-ops.org/stellaops/excititor@sha256:65c0ee13f773efe920d7181512349a09d363ab3f3e177d276136bd2742325a68
- name: advisory-ai-web
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2-airgap
- name: advisory-ai-worker
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2-airgap
- name: web-ui
image: registry.stella-ops.org/stellaops/web-ui@sha256:bee9668011ff414572131dc777faab4da24473fe12c230893f161cabee092a1d
- name: excititor
image: registry.stella-ops.org/stellaops/excititor@sha256:65c0ee13f773efe920d7181512349a09d363ab3f3e177d276136bd2742325a68
- name: advisory-ai-web
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2-airgap
- name: advisory-ai-worker
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2-airgap
- name: web-ui
image: registry.stella-ops.org/stellaops/web-ui@sha256:bee9668011ff414572131dc777faab4da24473fe12c230893f161cabee092a1d
infrastructure:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
valkey:
image: docker.io/valkey/valkey@sha256:9a2cf7c980f2f28678a5e34b1c8d74e4b7b7b6c8c4d5e6f7a8b9c0d1e2f3a4b5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
checksums:
releaseManifestSha256: b787b833dddd73960c31338279daa0b0a0dce2ef32bd32ef1aaf953d66135f94

View File

@@ -41,9 +41,11 @@ release:
- name: task-runner
image: registry.stella-ops.org/stellaops/task-runner@sha256:eb5ad992b49a41554f41516be1a6afcfa6522faf2111c08ff2b3664ad2fc954b
infrastructure:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
valkey:
image: docker.io/valkey/valkey@sha256:9a2cf7c980f2f28678a5e34b1c8d74e4b7b7b6c8c4d5e6f7a8b9c0d1e2f3a4b5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
checksums:
releaseManifestSha256: dc3c8fe1ab83941c838ccc5a8a5862f7ddfa38c2078e580b5649db26554565b7

View File

@@ -16,18 +16,20 @@ release:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
- name: concelier
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
- name: excititor
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
- name: advisory-ai-web
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2
- name: advisory-ai-worker
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2
- name: web-ui
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
- name: excititor
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
- name: advisory-ai-web
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2
- name: advisory-ai-worker
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2
- name: web-ui
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
infrastructure:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
valkey:
image: docker.io/valkey/valkey@sha256:9a2cf7c980f2f28678a5e34b1c8d74e4b7b7b6c8c4d5e6f7a8b9c0d1e2f3a4b5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
checksums:
releaseManifestSha256: dc3c8fe1ab83941c838ccc5a8a5862f7ddfa38c2078e580b5649db26554565b7

View File

@@ -3,21 +3,21 @@
channel: "edge"
date: "2025-10-01T00:00:00Z"
calendar: "2025.10"
components:
- name: authority
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
- name: signer
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
components:
- name: authority
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
- name: signer
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
- name: attestor
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
- name: issuer-directory-web
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
- name: scanner-web
image: registry.stella-ops.org/stellaops/scanner-web@sha256:e0dfdb087e330585a5953029fb4757f5abdf7610820a085bd61b457dbead9a11
- name: scanner-worker
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
- name: concelier
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
- name: scanner-worker
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
- name: concelier
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
- name: excititor
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
- name: advisory-ai-web
@@ -27,10 +27,10 @@
- name: web-ui
image: registry.stella-ops.org/stellaops/web-ui@sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf
infrastructure:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
valkey:
image: docker.io/valkey/valkey@sha256:9a2cf7c980f2f28678a5e34b1c8d74e4b7b7b6c8c4d5e6f7a8b9c0d1e2f3a4b5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.10.0-edge
checksums:

View File

@@ -17,13 +17,13 @@ _CI_DOCKER_LOADED=1
# CONFIGURATION
# =============================================================================
CI_COMPOSE_FILE="${CI_COMPOSE_FILE:-devops/compose/docker-compose.ci.yaml}"
CI_COMPOSE_FILE="${CI_COMPOSE_FILE:-devops/compose/docker-compose.testing.yml}"
CI_IMAGE="${CI_IMAGE:-stellaops-ci:local}"
CI_DOCKERFILE="${CI_DOCKERFILE:-devops/docker/Dockerfile.ci}"
CI_PROJECT_NAME="${CI_PROJECT_NAME:-stellaops-ci}"
# Service names from docker-compose.ci.yaml
CI_SERVICES=(postgres-ci valkey-ci nats-ci mock-registry minio-ci)
# Service names from docker-compose.testing.yml
CI_SERVICES=(postgres-test valkey-test rustfs-test mock-registry)
# =============================================================================
# DOCKER CHECK

View File

@@ -1,6 +1,13 @@
version: "3.9"
# =============================================================================
# ADVISORY AI - LOCAL DEVELOPMENT STACK
# =============================================================================
# Local/offline deployment for AdvisoryAI WebService + Worker.
#
# Usage:
# docker compose -f docker-compose.advisoryai.yaml up -d
#
# For production, use compose/docker-compose.stella-ops.yml instead.
# =============================================================================
services:
advisoryai-web:
build:

View File

@@ -1,6 +1,6 @@
# StellaOps Authority Container Scaffold
This directory provides a distroless Dockerfile and `docker-compose` sample for bootstrapping the Authority service alongside MongoDB (required) and Redis (optional).
This directory provides a distroless Dockerfile and `docker-compose` sample for bootstrapping the Authority service alongside PostgreSQL (required) and Valkey (cache).
## Prerequisites
@@ -16,14 +16,14 @@ This directory provides a distroless Dockerfile and `docker-compose` sample for
docker compose -f ops/authority/docker-compose.authority.yaml up --build
```
`authority.yaml` is mounted read-only at `/etc/authority.yaml` inside the container. Plugin manifests are mounted to `/app/etc/authority.plugins`. Update the issuer URL plus any Mongo credentials in the compose file or via an `.env`.
`authority.yaml` is mounted read-only at `/etc/authority.yaml` inside the container. Plugin manifests are mounted to `/app/etc/authority.plugins`. Update the issuer URL plus any PostgreSQL credentials in the compose file or via an `.env`.
To run with pre-built images, replace the `build:` block in the compose file with an `image:` reference.
## Volumes
- `mongo-data` persists MongoDB state.
- `redis-data` optional Redis persistence (enable the service before use).
- `postgres-data` persists PostgreSQL state.
- `valkey-data` Valkey cache persistence.
- `authority-keys` writable volume for Authority signing keys.
## Environment overrides
@@ -33,6 +33,9 @@ Key environment variables (mirroring `StellaOpsAuthorityOptions`):
| Variable | Description |
| --- | --- |
| `STELLAOPS_AUTHORITY__ISSUER` | Public issuer URL advertised by Authority |
| `STELLAOPS_AUTHORITY__STORAGE__DRIVER` | Storage driver (postgres) |
| `STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING` | PostgreSQL connection string |
| `STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING` | Valkey/Redis cache connection |
| `STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0` | Primary plugin binaries directory inside the container |
| `STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY` | Path to plugin manifest directory |

View File

@@ -1,4 +1,13 @@
version: "3.9"
# =============================================================================
# AUTHORITY - LOCAL DEVELOPMENT STACK
# =============================================================================
# OAuth2/OIDC identity provider development environment.
#
# Usage:
# docker compose -f docker-compose.authority.yaml up -d
#
# For production, use compose/docker-compose.stella-ops.yml instead.
# =============================================================================
services:
authority:
@@ -8,12 +17,19 @@ services:
image: stellaops-authority:dev
container_name: stellaops-authority
depends_on:
mongo:
condition: service_started
postgres:
condition: service_healthy
valkey:
condition: service_healthy
environment:
# Override issuer to match your deployment URL.
STELLAOPS_AUTHORITY__ISSUER: "https://authority.localtest.me"
# Point the Authority host at the Mongo instance defined below.
# Storage configuration (PostgreSQL)
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=authority;Username=stellaops;Password=stellaops"
# Cache configuration (Valkey)
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
# Plugin configuration
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
@@ -26,17 +42,22 @@ services:
- "8080:8080"
restart: unless-stopped
mongo:
image: mongo:7
container_name: stellaops-authority-mongo
command: ["mongod", "--bind_ip_all"]
postgres:
image: postgres:18.1-alpine
container_name: stellaops-authority-postgres
environment:
MONGO_INITDB_ROOT_USERNAME: stellaops
MONGO_INITDB_ROOT_PASSWORD: stellaops
POSTGRES_USER: stellaops
POSTGRES_PASSWORD: stellaops
POSTGRES_DB: authority
volumes:
- mongo-data:/data/db
- postgres-data:/var/lib/postgresql/data
ports:
- "27017:27017"
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellaops -d authority"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
valkey:
@@ -47,13 +68,14 @@ services:
- valkey-data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# Uncomment to enable if/when Authority consumes Valkey.
# deploy:
# replicas: 0
volumes:
mongo-data:
postgres-data:
valkey-data:
authority-keys:

View File

@@ -2,7 +2,6 @@
# CI helper for DEVOPS-CI-110-001
# - Warms NuGet cache from local sources
# - Ensures OpenSSL 1.1 compatibility if available
# - Runs targeted Concelier and Excititor test slices with TRX output
# - Writes artefacts under ops/devops/artifacts/ci-110/<timestamp>/
@@ -27,25 +26,6 @@ log() {
printf '[%s] %s\n' "$(date -u +%H:%M:%S)" "$*"
}
ensure_openssl11() {
if openssl version 2>/dev/null | grep -q "1\\.1."; then
log "OpenSSL 1.1 detected: $(openssl version)"
return
fi
if command -v apt-get >/dev/null 2>&1; then
log "OpenSSL 1.1 not found; attempting install via apt-get (libssl1.1)"
sudo DEBIAN_FRONTEND=noninteractive apt-get update -y >/dev/null || true
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libssl1.1 || true
if openssl version 2>/dev/null | grep -q "1\\.1."; then
log "OpenSSL 1.1 available after install: $(openssl version)"
return
fi
fi
log "OpenSSL 1.1 still unavailable. Provide it via LD_LIBRARY_PATH if required."
}
restore_solution() {
local sln="$1"
log "Restore $sln"
@@ -71,12 +51,11 @@ run_test_slice() {
main() {
log "Starting CI-110 runner; artefacts -> $ARTIFACT_ROOT"
ensure_openssl11
restore_solution "$ROOT/concelier-webservice.slnf"
restore_solution "$ROOT/src/Excititor/StellaOps.Excititor.sln"
# Concelier: lightweight health slice to validate runner + Mongo wiring
# Concelier: lightweight health slice to validate runner + PostgreSQL wiring
run_test_slice "$ROOT/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/StellaOps.Concelier.WebService.Tests.csproj" \
"HealthAndReadyEndpointsRespond" \
"concelier-health"

View File

@@ -1,9 +1,9 @@
# Concelier CI Runner Harness (DEVOPS-CONCELIER-CI-24-101)
Purpose: provide a deterministic, offline-friendly harness that restores, builds, and runs Concelier WebService + Storage Mongo tests with warmed NuGet cache and TRX/binlog artefacts for downstream sprints (Concelier II/III).
Purpose: provide a deterministic, offline-friendly harness that restores, builds, and runs Concelier WebService + Storage PostgreSQL tests with warmed NuGet cache and TRX/binlog artefacts for downstream sprints (Concelier II/III).
Usage
- From repo root run: `ops/devops/concelier-ci-runner/run-concelier-ci.sh`
- From repo root run: `devops/services/concelier-ci-runner/run-concelier-ci.sh`
- Outputs land in `ops/devops/artifacts/concelier-ci/<UTC timestamp>/`:
- `build.binlog` (solution build)
- `tests/webservice.trx`, `tests/storage.trx` (VSTest results)
@@ -13,11 +13,11 @@ Usage
Environment
- Defaults: `DOTNET_CLI_TELEMETRY_OPTOUT=1`, `DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1`, `NUGET_PACKAGES=$REPO/.nuget/packages`.
- Uses `.nuget/packages` cache (can be overridden via `NUGET_SOURCES`).
- No external services required; Mongo2Go provides ephemeral Mongo for tests.
- No external services required; Testcontainers provides ephemeral PostgreSQL for tests.
What it does
1) `dotnet restore` + `dotnet build` on `concelier-webservice.slnf` with `/bl`.
3) Run WebService and Storage.Mongo test projects with TRX output and without rebuild (`--no-build`).
3) Run WebService and Storage.Postgres test projects with TRX output and without rebuild (`--no-build`).
4) Emit a concise `summary.json` listing artefacts and SHA256s for reproducibility.
Notes

View File

@@ -2,7 +2,7 @@
set -euo pipefail
# Concelier CI runner harness (DEVOPS-CONCELIER-CI-24-101)
# Produces warmed-cache restore, build binlog, and TRX outputs for WebService + Storage Mongo tests.
# Produces warmed-cache restore, build binlog, and TRX outputs for WebService + Storage tests.
repo_root="$(cd "$(dirname "$0")/../../.." && pwd)"
ts="$(date -u +%Y%m%dT%H%M%SZ)"
@@ -44,9 +44,9 @@ dotnet test "$repo_root/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tes
"${common_test_args[@]}" \
--logger "trx;LogFileName=$web_trx"
# Storage Mongo tests
# Storage PostgreSQL tests
storage_trx="storage.trx"
dotnet test "$repo_root/src/Concelier/__Tests/StellaOps.Concelier.Storage.Mongo.Tests/StellaOps.Concelier.Storage.Mongo.Tests.csproj" \
dotnet test "$repo_root/src/Concelier/__Tests/StellaOps.Concelier.Storage.Postgres.Tests/StellaOps.Concelier.Storage.Postgres.Tests.csproj" \
"${common_test_args[@]}" \
--logger "trx;LogFileName=$storage_trx"
@@ -58,7 +58,7 @@ summary="$out_dir/summary.json"
printf ' "build_binlog": "%s",\n' "${build_binlog#${repo_root}/}"
printf ' "tests": [\n'
printf ' {"project": "WebService", "trx": "%s"},\n' "${logs_dir#${repo_root}/}/$web_trx"
printf ' {"project": "Storage.Mongo", "trx": "%s"}\n' "${logs_dir#${repo_root}/}/$storage_trx"
printf ' {"project": "Storage.Postgres", "trx": "%s"}\n' "${logs_dir#${repo_root}/}/$storage_trx"
printf ' ],\n'
printf ' "nuget_packages": "%s",\n' "${NUGET_PACKAGES#${repo_root}/}"
printf ' "sources": [\n'

View File

@@ -1,21 +0,0 @@
version: '3.8'
services:
minio:
image: minio/minio:RELEASE.2024-10-08T09-56-18Z
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: exportci
MINIO_ROOT_PASSWORD: exportci123
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 5s
timeout: 3s
retries: 5
volumes:
minio-data:
driver: local

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
MINIO_ENDPOINT=${MINIO_ENDPOINT:-http://localhost:9000}
MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-exportci}
MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-exportci123}
BUCKET=${BUCKET:-export-ci}
TMP=$(mktemp)
cleanup(){ rm -f "$TMP"; }
trap cleanup EXIT
cat > "$TMP" <<'DATA'
{"id":"exp-001","object":"s3://export-ci/sample-export.ndjson","status":"ready"}
DATA
export AWS_ACCESS_KEY_ID="$MINIO_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="$MINIO_SECRET_KEY"
export AWS_EC2_METADATA_DISABLED=true
if ! aws --endpoint-url "$MINIO_ENDPOINT" s3 ls "s3://$BUCKET" >/dev/null 2>&1; then
aws --endpoint-url "$MINIO_ENDPOINT" s3 mb "s3://$BUCKET"
fi
aws --endpoint-url "$MINIO_ENDPOINT" s3 cp "$TMP" "s3://$BUCKET/sample-export.ndjson"
echo "Seeded $BUCKET/sample-export.ndjson"

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
RUSTFS_ENDPOINT=${RUSTFS_ENDPOINT:-http://localhost:8080}
BUCKET=${BUCKET:-export-ci}
TMP=$(mktemp)
cleanup(){ rm -f "$TMP"; }
trap cleanup EXIT
cat > "$TMP" <<'DATA'
{"id":"exp-001","object":"s3://export-ci/sample-export.ndjson","status":"ready"}
DATA
# RustFS uses S3-compatible API
export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-exportci}"
export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-exportci123}"
export AWS_EC2_METADATA_DISABLED=true
if ! aws --endpoint-url "$RUSTFS_ENDPOINT" s3 ls "s3://$BUCKET" >/dev/null 2>&1; then
aws --endpoint-url "$RUSTFS_ENDPOINT" s3 mb "s3://$BUCKET"
fi
aws --endpoint-url "$RUSTFS_ENDPOINT" s3 cp "$TMP" "s3://$BUCKET/sample-export.ndjson"
echo "Seeded $BUCKET/sample-export.ndjson"

View File

@@ -1,46 +1,39 @@
# Orchestrator Infra Bootstrap (DEVOPS-ORCH-32-001)
## Components
- Postgres 16 (state/config)
- Mongo 7 (job ledger history)
- NATS 2.10 JetStream (queue/bus)
- PostgreSQL 18.1 (state/config/job ledger)
- Valkey 9.0.1 (queue/bus/cache)
Compose file: `ops/devops/orchestrator/docker-compose.orchestrator.yml`
Compose file: `devops/compose/docker-compose.stella-ops.yml`
## Quick start (offline-friendly)
```bash
# bring up infra
COMPOSE_FILE=ops/devops/orchestrator/docker-compose.orchestrator.yml docker compose up -d
docker compose -f devops/compose/docker-compose.stella-ops.yml up -d stellaops-postgres stellaops-valkey
# smoke check and emit connection strings
scripts/orchestrator/smoke.sh
devops/tools/orchestrator-scripts/smoke.sh
cat out/orchestrator-smoke/readiness.txt
# synthetic probe (postgres/mongo/nats health)
scripts/orchestrator/probe.sh
# synthetic probe (postgres/valkey health)
devops/tools/orchestrator-scripts/probe.sh
cat out/orchestrator-probe/status.txt
# replay readiness (restart then smoke)
scripts/orchestrator/replay-smoke.sh
```
Connection strings
- Postgres: `postgres://orch:orchpass@localhost:55432/orchestrator`
- Mongo: `mongodb://localhost:57017`
- NATS: `nats://localhost:4222`
- Postgres: `postgres://stellaops:stellaops@localhost:5432/stellaops`
- Valkey: `valkey://localhost:6379`
## Observability
- Alerts: `ops/devops/orchestrator/alerts.yaml`
- Grafana dashboard: `ops/devops/orchestrator/grafana/orchestrator-overview.json`
- Alerts: `devops/observability/alerting/`
- Grafana dashboard: `devops/observability/dashboards/`
- Metrics expected: `job_queue_depth`, `job_failures_total`, `lease_extensions_total`, `job_latency_seconds_bucket`.
- Runbook: `ops/devops/orchestrator/incident-response.md`
- Synthetic probes: `scripts/orchestrator/probe.sh` (writes `out/orchestrator-probe/status.txt`).
- Replay smoke: `scripts/orchestrator/replay-smoke.sh` (idempotent restart + smoke).
- Synthetic probes: `devops/tools/orchestrator-scripts/probe.sh` (writes `out/orchestrator-probe/status.txt`).
## CI hook (suggested)
Add a workflow step (or local cron) to run `scripts/orchestrator/smoke.sh` with `SKIP_UP=1` against existing infra and publish the `readiness.txt` artifact for traceability.
Add a workflow step (or local cron) to run `devops/tools/orchestrator-scripts/smoke.sh` with `SKIP_UP=1` against existing infra and publish the `readiness.txt` artifact for traceability.
## Notes
- Uses fixed ports for determinism; adjust via COMPOSE overrides if needed.
- Data volumes: `orch_pg_data`, `orch_mongo_data` (docker volumes).
- Data volumes: `stellaops-postgres`, `stellaops-valkey` (docker volumes).
- No external downloads beyond base images; pin images to specific tags above.

View File

@@ -1,4 +1,14 @@
version: "3.9"
# =============================================================================
# ORCHESTRATOR - LOCAL DEVELOPMENT INFRASTRUCTURE
# =============================================================================
# Infrastructure services for Orchestrator local development.
#
# Usage:
# docker compose -f docker-compose.orchestrator.yml up -d
#
# For production, use compose/docker-compose.stella-ops.yml instead.
# =============================================================================
services:
orchestrator-postgres:
image: postgres:18.1-alpine
@@ -17,28 +27,15 @@ services:
retries: 5
restart: unless-stopped
orchestrator-mongo:
image: mongo:7
command: ["mongod", "--quiet", "--storageEngine=wiredTiger"]
orchestrator-valkey:
image: valkey/valkey:9.0.1-alpine
ports:
- "57017:27017"
- "56379:6379"
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- orch_mongo_data:/data/db
- orch_valkey_data:/data
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
orchestrator-nats:
image: nats:2.10-alpine
ports:
- "5422:4222"
- "5822:8222"
command: ["-js", "-m", "8222"]
healthcheck:
test: ["CMD", "nats", "--server", "localhost:4222", "ping"]
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
@@ -46,5 +43,4 @@ services:
volumes:
orch_pg_data:
orch_mongo_data:
orch_valkey_data:

View File

@@ -5,7 +5,7 @@ This harness supports `DEVOPS-AIRGAP-57-002` by exercising services with the `se
## Workflow
1. Run `./run-sealed-ci.sh` from this directory (the script now boots the stack, applies the iptables guard, and captures artefacts automatically).
2. The harness:
- Launches `sealed-mode-compose.yml` with Authority/Signer/Attestor + Mongo.
- Launches `sealed-mode-compose.yml` with Authority/Signer/Attestor + PostgreSQL + Valkey.
- Snapshots iptables, injects a `STELLAOPS_SEALED` chain into `DOCKER-USER`/`OUTPUT`, and whitelists only loopback + RFC1918 ranges so container egress is denied.
- Repeatedly polls `/healthz` on `5088/6088/7088` to verify sealed-mode bindings stay healthy while egress is blocked.
- Executes `egress_probe.py`, which runs curl probes from inside the compose network to confirm off-cluster addresses are unreachable.

View File

@@ -16,9 +16,11 @@ plugins:
enabled: true
configFile: standard.yaml
storage:
connectionString: mongodb://sealedci:sealedci@mongo:27017/authority?authSource=admin
databaseName: authority
driver: postgres
connectionString: "Host=postgres;Port=5432;Database=authority;Username=sealedci;Password=sealedci-secret"
commandTimeout: 00:00:30
cache:
connectionString: "valkey:6379"
signing:
enabled: true
activeKeyId: sealed-ci

View File

@@ -1,4 +1,11 @@
version: '3.9'
# =============================================================================
# SEALED MODE CI - AIR-GAPPED TESTING ENVIRONMENT
# =============================================================================
# Sealed/air-gapped CI environment for testing offline functionality.
#
# Usage:
# docker compose -f sealed-mode-compose.yml up -d
# =============================================================================
x-release-labels: &release-labels
com.stellaops.profile: 'sealed-ci'
@@ -9,31 +16,57 @@ networks:
driver: bridge
volumes:
sealed-mongo-data:
sealed-postgres-data:
sealed-valkey-data:
services:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
command: ['mongod', '--bind_ip_all']
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: sealedci
MONGO_INITDB_ROOT_PASSWORD: sealedci-secret
POSTGRES_USER: sealedci
POSTGRES_PASSWORD: sealedci-secret
POSTGRES_DB: stellaops
volumes:
- sealed-mongo-data:/data/db
- sealed-postgres-data:/var/lib/postgresql/data
networks:
- sealed-ci
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sealedci -d stellaops"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1-alpine
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- sealed-valkey-data:/data
networks:
- sealed-ci
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
depends_on:
- mongo
postgres:
condition: service_healthy
valkey:
condition: service_healthy
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:5088
STELLAOPS_AUTHORITY__ISSUER: http://authority.sealed-ci.local
STELLAOPS_AUTHORITY__MONGO__CONNECTIONSTRING: mongodb://sealedci:sealedci-secret@mongo:27017/authority?authSource=admin
STELLAOPS_AUTHORITY__STORAGE__DRIVER: postgres
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=authority;Username=sealedci;Password=sealedci-secret"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: /app/plugins
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: /app/plugins
STELLAOPS_AUTHORITY__SECURITY__SENDERCONSTRAINTS__DPOP__ENABLED: 'true'
@@ -58,7 +91,9 @@ services:
ASPNETCORE_URLS: http://+:6088
SIGNER__AUTHORITY__BASEURL: http://authority:5088
SIGNER__POE__INTROSPECTURL: http://authority:5088/device-code
SIGNER__STORAGE__MONGO__CONNECTIONSTRING: mongodb://sealedci:sealedci-secret@mongo:27017/signer?authSource=admin
SIGNER__STORAGE__DRIVER: postgres
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=signer;Username=sealedci;Password=sealedci-secret"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SIGNER__SEALED__MODE: Enabled
ports:
- '6088:6088'
@@ -74,7 +109,9 @@ services:
environment:
ASPNETCORE_URLS: http://+:7088
ATTESTOR__SIGNER__BASEURL: http://signer:6088
ATTESTOR__MONGO__CONNECTIONSTRING: mongodb://sealedci:sealedci-secret@mongo:27017/attestor?authSource=admin
ATTESTOR__STORAGE__DRIVER: postgres
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=attestor;Username=sealedci;Password=sealedci-secret"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ATTESTOR__SEALED__MODE: Enabled
ports:
- '7088:7088'

View File

@@ -1,31 +1,29 @@
# Signals CI/CD & Local Stack (DEVOPS-SIG-26-001)
Artifacts:
- Compose stack: `ops/devops/signals/docker-compose.signals.yml` (Signals API + Mongo + Valkey + artifact volume).
- Sample config: `ops/devops/signals/signals.yaml` (mounted into the container at `/app/signals.yaml` if desired).
- Dockerfile: `ops/devops/signals/Dockerfile` (multi-stage build on .NET 10 RC).
- Build/export helper: `scripts/signals/build.sh` (saves image tar to `out/signals/signals-image.tar`).
- Span sink stack: `ops/devops/signals/docker-compose.spansink.yml` + `otel-spansink.yaml` to collect OTLP traces (Excititor `/v1/vex/observations/**`) and write NDJSON to `spansink-data` volume. Run via `scripts/signals/run-spansink.sh`.
- Grafana dashboard stub: `ops/devops/signals/dashboards/excititor-vex-traces.json` (import into Tempo-enabled Grafana).
- Compose stack: `devops/compose/docker-compose.stella-ops.yml` (Signals API + PostgreSQL + Valkey + artifact volume).
- Sample config: `devops/services/signals-ops/signals.yaml` (mounted into the container at `/app/signals.yaml` if desired).
- Dockerfile: `devops/services/signals-ops/Dockerfile` (multi-stage build on .NET 10 RC).
- Build/export helper: `devops/tools/signals-scripts/build.sh` (saves image tar to `out/signals/signals-image.tar`).
- Span sink stack: `devops/services/signals-ops/docker-compose.spansink.yml` + `otel-spansink.yaml` to collect OTLP traces (Excititor `/v1/vex/observations/**`) and write NDJSON to `spansink-data` volume.
- Grafana dashboard stub: `devops/services/signals-ops/dashboards/excititor-vex-traces.json` (import into Tempo-enabled Grafana).
Quick start (offline-friendly):
```bash
# build image
scripts/signals/build.sh
devops/tools/signals-scripts/build.sh
# run stack
COMPOSE_FILE=ops/devops/signals/docker-compose.signals.yml docker compose up -d
docker compose -f devops/compose/docker-compose.stella-ops.yml up -d signals
# hit health
curl -s http://localhost:5088/health
# run span sink collector
scripts/signals/run-spansink.sh
```
Configuration (ENV or YAML):
- `Signals__Mongo__ConnectionString` default `mongodb://signals-mongo:27017/signals`
- `Signals__Cache__ConnectionString` default `signals-valkey:6379`
- `Signals__Storage__Driver` default `postgres`
- `Signals__Storage__ConnectionString` default `Host=stellaops-postgres;Port=5432;Database=signals;Username=stellaops;Password=stellaops`
- `Signals__Cache__ConnectionString` default `stellaops-valkey:6379`
- `Signals__Storage__RootPath` default `/data/artifacts`
- Authority disabled by default for local; enable with `Signals__Authority__Enabled=true` and issuer settings.
@@ -33,6 +31,6 @@ CI workflow:
- `.gitea/workflows/signals-ci.yml` restores, builds, tests, builds container, and uploads `signals-image.tar` artifact.
Dependencies:
- Mongo 7 (wiredTiger)
- Valkey 8 (cache, BSD-3 licensed Redis fork)
- PostgreSQL 18.1 (primary data store)
- Valkey 9.0.1 (cache, BSD-3 licensed Redis fork)
- Artifact volume `signals_artifacts` for callgraph blobs.

View File

@@ -1,4 +1,13 @@
version: "3.9"
# =============================================================================
# SIGNALS - LOCAL DEVELOPMENT STACK
# =============================================================================
# Signals API local development environment.
#
# Usage:
# docker compose -f docker-compose.signals.yml up -d
#
# For production, use compose/docker-compose.stella-ops.yml instead.
# =============================================================================
services:
signals-api:
@@ -8,8 +17,8 @@ services:
image: stellaops/signals:local
environment:
ASPNETCORE_URLS: "http://+:5088"
Signals__Mongo__ConnectionString: "mongodb://signals-mongo:27017/signals"
Signals__Mongo__Database: "signals"
Signals__Storage__Driver: "postgres"
Signals__Storage__Postgres__ConnectionString: "Host=signals-postgres;Port=5432;Database=signals;Username=signals;Password=signals"
Signals__Cache__ConnectionString: "signals-valkey:6379"
Signals__Storage__RootPath: "/data/artifacts"
Signals__Authority__Enabled: "false"
@@ -17,21 +26,26 @@ services:
ports:
- "5088:5088"
depends_on:
- signals-mongo
- signals-valkey
signals-postgres:
condition: service_healthy
signals-valkey:
condition: service_healthy
volumes:
- signals_artifacts:/data/artifacts
- ./signals.yaml:/app/signals.yaml:ro
signals-mongo:
image: mongo:7
command: ["mongod", "--quiet", "--storageEngine=wiredTiger"]
signals-postgres:
image: postgres:18.1-alpine
environment:
POSTGRES_USER: signals
POSTGRES_PASSWORD: signals
POSTGRES_DB: signals
ports:
- "57027:27017"
- "55433:5432"
volumes:
- signals_mongo:/data/db
- signals_postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping')"]
test: ["CMD-SHELL", "pg_isready -U signals -d signals"]
interval: 10s
timeout: 5s
retries: 5
@@ -49,5 +63,4 @@ services:
volumes:
signals_artifacts:
signals_mongo:
signals_postgres:

View File

@@ -1,13 +1,13 @@
# Sample offline configuration for Signals
Signals:
Mongo:
ConnectionString: "mongodb://signals-mongo:27017/signals"
Database: "signals"
Storage:
Driver: "postgres"
ConnectionString: "Host=signals-postgres;Port=5432;Database=signals;Username=stellaops;Password=stellaops"
Cache:
ConnectionString: "signals-valkey:6379"
DefaultTtlSeconds: 600
Storage:
Artifacts:
RootPath: "/data/artifacts"
Authority:
Enabled: false

View File

@@ -9,10 +9,10 @@ service:
env:
ASPNETCORE_URLS: "http://+:5088"
Signals__Mongo__ConnectionString: "mongodb://signals-mongo:27017/signals"
Signals__Mongo__Database: "signals"
Signals__Storage__Driver: "postgres"
Signals__Storage__ConnectionString: "Host=signals-postgres;Port=5432;Database=signals;Username=stellaops;Password=stellaops"
Signals__Cache__ConnectionString: "signals-valkey:6379"
Signals__Storage__RootPath: "/data/artifacts"
Signals__Artifacts__RootPath: "/data/artifacts"
Signals__Authority__Enabled: "false"
Signals__OpenApi__Enabled: "true"
@@ -27,9 +27,9 @@ valkey:
host: signals-valkey
port: 6379
mongo:
postgres:
enabled: true
connectionString: "mongodb://signals-mongo:27017/signals"
connectionString: "Host=signals-postgres;Port=5432;Database=signals;Username=stellaops;Password=stellaops"
ingress:
enabled: false

View File

@@ -1,33 +1,62 @@
version: "3.9"
# =============================================================================
# SYMBOLS SERVER - LOCAL DEVELOPMENT STACK
# =============================================================================
# Symbols server local development environment with PostgreSQL and RustFS.
#
# Usage:
# docker compose -f docker-compose.symbols.yaml up -d
#
# For production, use compose/docker-compose.stella-ops.yml instead.
# =============================================================================
services:
mongo:
image: mongo:7.0
restart: unless-stopped
command: ["mongod", "--bind_ip_all"]
ports:
- "27017:27017"
minio:
image: minio/minio:RELEASE.2024-08-17T00-00-00Z
postgres:
image: postgres:18.1-alpine
restart: unless-stopped
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
command: server /data --console-address :9001
POSTGRES_USER: symbols
POSTGRES_PASSWORD: ${SYMBOLS_DB_PASSWORD:-symbols_dev}
POSTGRES_DB: symbols
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "9000:9000"
- "9001:9001"
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U symbols -d symbols"]
interval: 10s
timeout: 5s
retries: 5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
restart: unless-stopped
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "9000:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
symbols:
image: ghcr.io/stella-ops/symbols-server:edge
depends_on:
- mongo
- minio
postgres:
condition: service_healthy
rustfs:
condition: service_healthy
environment:
Mongo__ConnectionString: mongodb://mongo:27017/symbols
Storage__Driver: postgres
Storage__Postgres__ConnectionString: "Host=postgres;Port=5432;Database=symbols;Username=symbols;Password=${SYMBOLS_DB_PASSWORD:-symbols_dev}"
Storage__Provider: S3
Storage__S3__Endpoint: http://minio:9000
Storage__S3__Endpoint: http://rustfs:8080
Storage__S3__Bucket: symbols
Storage__S3__AccessKeyId: minio
Storage__S3__SecretAccessKey: minio123
Storage__S3__UsePathStyle: "true"
Logging__Console__FormatterName: json
ports:
@@ -38,6 +67,11 @@ services:
timeout: 5s
retries: 6
start_period: 10s
volumes:
postgres-data:
rustfs-data:
networks:
default:
name: symbols-ci

View File

@@ -3,16 +3,14 @@ image:
repository: ghcr.io/stella-ops/symbols-server
tag: edge
mongodb:
postgres:
enabled: true
connectionString: "mongodb://mongo:27017/symbols"
connectionString: "Host=postgres;Port=5432;Database=symbols;Username=stellaops;Password=stellaops"
minio:
rustfs:
enabled: true
endpoint: "http://minio:9000"
endpoint: "http://rustfs:8080"
bucket: "symbols"
accessKey: "minio"
secretKey: "minio123"
ingress:
enabled: false

View File

@@ -11,7 +11,7 @@ Usage:
For every target file, the script scans `image:` declarations and verifies that
any image belonging to a repository listed in the release manifest matches the
exact digest or tag recorded there. Images outside of the manifest (for example,
supporting services such as `nats`) are ignored.
supporting services such as `valkey`) are ignored.
"""
from __future__ import annotations

View File

@@ -12,11 +12,6 @@ export DOTNET_CLI_TELEMETRY_OPTOUT=1
# Prefer the curated offline feed to avoid network flakiness during CI.
export NUGET_PACKAGES="${ROOT_DIR}/.nuget/packages"
RESTORE_SOURCE="--source ${ROOT_DIR}/.nuget/packages --ignore-failed-sources"
# Ensure Mongo2Go can find OpenSSL 1.1 (needed by bundled mongod)
OPENSSL11_DIR="$ROOT_DIR/tools/openssl1.1/lib"
if [[ -d "$OPENSSL11_DIR" ]]; then
export LD_LIBRARY_PATH="$OPENSSL11_DIR:${LD_LIBRARY_PATH:-}"
fi
RESULTS_DIR="$ROOT_DIR/out/test-results/linksets"
mkdir -p "$RESULTS_DIR"
# Restore explicitly against offline cache, then run tests without restoring again.

View File

@@ -6,11 +6,12 @@ COUNTS=$ARTifacts/lnm-counts.json
CONFLICTS=$ARTifacts/lnm-conflicts.ndjson
mkdir -p "$ARTifacts"
mongoexport --uri "${STAGING_MONGO_URI:?set STAGING_MONGO_URI}" --collection advisoryObservations --db concelier --type=json --query '{}' --out "$ARTifacts/obs.json" >/dev/null
mongoexport --uri "${STAGING_MONGO_URI:?set STAGING_MONGO_URI}" --collection linksets --db concelier --type=json --query '{}' --out "$ARTifacts/linksets.json" >/dev/null
# Export advisory observations from PostgreSQL
psql "${STAGING_POSTGRES_URI:?set STAGING_POSTGRES_URI}" -c "COPY (SELECT row_to_json(t) FROM advisory_observations t) TO STDOUT" > "$ARTifacts/obs.json"
psql "${STAGING_POSTGRES_URI:?set STAGING_POSTGRES_URI}" -c "COPY (SELECT row_to_json(t) FROM linksets t) TO STDOUT" > "$ARTifacts/linksets.json"
OBS=$(jq length "$ARTifacts/obs.json")
LNK=$(jq length "$ARTifacts/linksets.json")
OBS=$(wc -l < "$ARTifacts/obs.json" | tr -d ' ')
LNK=$(wc -l < "$ARTifacts/linksets.json" | tr -d ' ')
cat > "$COUNTS" <<JSON
{

View File

@@ -20,9 +20,8 @@ Microsoft.Extensions.Logging.Abstractions|9.0.0
Microsoft.Extensions.Options.ConfigurationExtensions|10.0.0-rc.2.25502.107
Microsoft.Extensions.Options|10.0.0-rc.2.25502.107
Microsoft.Extensions.Options|9.0.0
MongoDB.Driver|3.5.0
NATS.Client.Core|2.0.0
NATS.Client.JetStream|2.0.0
Npgsql|9.0.3
Npgsql.EntityFrameworkCore.PostgreSQL|9.0.3
RoaringBitmap|0.0.9
Serilog.AspNetCore|8.0.1
Serilog.Extensions.Hosting|8.0.0

View File

@@ -26,8 +26,8 @@
<PackageDownload Include="Microsoft.Extensions.Logging.Abstractions" Version="[10.0.0-rc.2.25502.107]" />
<PackageDownload Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="[10.0.0-rc.2.25502.107]" />
<PackageDownload Include="Microsoft.Extensions.Options" Version="[10.0.0-rc.2.25502.107]" />
<PackageDownload Include="NATS.Client.Core" Version="[2.0.0]" />
<PackageDownload Include="NATS.Client.JetStream" Version="[2.0.0]" />
<PackageDownload Include="Npgsql" Version="[9.0.3]" />
<PackageDownload Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="[9.0.3]" />
<PackageDownload Include="RoaringBitmap" Version="[0.0.9]" />
<PackageDownload Include="Serilog.AspNetCore" Version="[8.0.1]" />
<PackageDownload Include="Serilog.Extensions.Hosting" Version="[8.0.0]" />

View File

@@ -1,19 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
# DEVOPS-OBS-52-001: validate streaming pipeline knobs
# DEVOPS-OBS-52-001: validate streaming pipeline knobs (Valkey-based)
OUT="out/obs-stream"
mkdir -p "$OUT"
echo "[obs-stream] checking NATS connectivity"
if command -v nats >/dev/null 2>&1; then
nats --server "${NATS_URL:-nats://localhost:4222}" req health.ping ping || true
echo "[obs-stream] checking Valkey connectivity"
if command -v valkey-cli >/dev/null 2>&1; then
valkey-cli -h "${VALKEY_HOST:-localhost}" -p "${VALKEY_PORT:-6379}" ping || true
elif command -v redis-cli >/dev/null 2>&1; then
redis-cli -h "${VALKEY_HOST:-localhost}" -p "${VALKEY_PORT:-6379}" ping || true
else
echo "nats CLI not installed; skipping connectivity check" > "${OUT}/nats.txt"
echo "valkey-cli/redis-cli not installed; skipping connectivity check" > "${OUT}/valkey.txt"
fi
echo "[obs-stream] dumping retention/partitions (Kafka-like env variables)"
env | grep -E 'KAFKA_|REDIS_|NATS_' | sort > "${OUT}/env.txt"
echo "[obs-stream] dumping retention/partitions env variables"
env | grep -E 'KAFKA_|REDIS_|VALKEY_' | sort > "${OUT}/env.txt"
echo "[obs-stream] done; outputs in $OUT"

View File

@@ -1,77 +0,0 @@
/**
* Aggregation helper that surfaces advisory_raw duplicate candidates prior to enabling the
* idempotency unique index. Intended for staging/offline snapshots.
*
* Usage:
* mongo concelier ops/devops/scripts/check-advisory-raw-duplicates.js
*
* Environment variables:
* LIMIT - optional cap on number of duplicate groups to print (default 50).
*/
(function () {
function toInt(value, fallback) {
var parsed = parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}
var limit = typeof LIMIT !== "undefined" ? toInt(LIMIT, 50) : 50;
var database = db.getName ? db.getSiblingDB(db.getName()) : db;
if (!database) {
throw new Error("Unable to resolve database handle");
}
print("");
print("== advisory_raw duplicate audit ==");
print("Database: " + database.getName());
print("Limit : " + limit);
print("");
var pipeline = [
{
$group: {
_id: {
vendor: "$source.vendor",
upstreamId: "$upstream.upstream_id",
contentHash: "$upstream.content_hash",
tenant: "$tenant"
},
ids: { $addToSet: "$_id" },
count: { $sum: 1 }
}
},
{ $match: { count: { $gt: 1 } } },
{
$project: {
_id: 0,
vendor: "$_id.vendor",
upstreamId: "$_id.upstreamId",
contentHash: "$_id.contentHash",
tenant: "$_id.tenant",
count: 1,
ids: 1
}
},
{ $sort: { count: -1, vendor: 1, upstreamId: 1 } },
{ $limit: limit }
];
var cursor = database.getCollection("advisory_raw").aggregate(pipeline, { allowDiskUse: true });
var any = false;
while (cursor.hasNext()) {
var doc = cursor.next();
any = true;
print("---");
print("vendor : " + doc.vendor);
print("upstream_id : " + doc.upstreamId);
print("tenant : " + doc.tenant);
print("content_hash: " + doc.contentHash);
print("count : " + doc.count);
print("ids : " + doc.ids.join(", "));
}
if (!any) {
print("No duplicate advisory_raw documents detected.");
}
print("");
})();

View File

@@ -0,0 +1,46 @@
-- Advisory raw duplicate detection query
-- Surfaces advisory_raw duplicate candidates prior to enabling the idempotency unique index.
-- Intended for staging/offline snapshots.
--
-- Usage:
-- psql -d concelier -f ops/devops/tools/ops-scripts/check-advisory-raw-duplicates.sql
--
-- Environment variables:
-- LIMIT - optional cap on number of duplicate groups to print (default 50).
\echo '== advisory_raw duplicate audit =='
\conninfo
WITH duplicates AS (
SELECT
source_vendor,
upstream_id,
content_hash,
tenant,
COUNT(*) as count,
ARRAY_AGG(id) as ids
FROM advisory_raw
GROUP BY source_vendor, upstream_id, content_hash, tenant
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC, source_vendor, upstream_id
LIMIT COALESCE(NULLIF(:'LIMIT', '')::INT, 50)
)
SELECT
'vendor: ' || source_vendor || E'\n' ||
'upstream_id: ' || upstream_id || E'\n' ||
'tenant: ' || COALESCE(tenant, 'NULL') || E'\n' ||
'content_hash: ' || content_hash || E'\n' ||
'count: ' || count || E'\n' ||
'ids: ' || ARRAY_TO_STRING(ids, ', ') AS duplicate_info
FROM duplicates;
SELECT CASE WHEN COUNT(*) = 0
THEN 'No duplicate advisory_raw documents detected.'
ELSE 'Found ' || COUNT(*) || ' duplicate groups.'
END as status
FROM (
SELECT 1 FROM advisory_raw
GROUP BY source_vendor, upstream_id, content_hash, tenant
HAVING COUNT(*) > 1
LIMIT 1
) t;

View File

@@ -1,100 +0,0 @@
/**
* Rollback script for LNM-21-102-DEV legacy advisory backfill migration.
* Removes backfilled observations and linksets by querying the backfill_marker field,
* then clears the tombstone markers from advisory_raw.
*
* Usage:
* mongo concelier ops/devops/scripts/rollback-lnm-backfill.js
*
* Environment variables:
* DRY_RUN - if set to "1", only reports what would be deleted without making changes.
* BATCH_SIZE - optional batch size for deletions (default 500).
*
* After running this script, delete the migration record:
* db.schema_migrations.deleteOne({ _id: "20251127_lnm_legacy_backfill" })
*
* Then restart the Concelier service.
*/
(function () {
var BACKFILL_MARKER = "lnm_21_102_dev";
function toInt(value, fallback) {
var parsed = parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}
function toBool(value) {
return value === "1" || value === "true" || value === true;
}
var dryRun = typeof DRY_RUN !== "undefined" ? toBool(DRY_RUN) : false;
var batchSize = typeof BATCH_SIZE !== "undefined" ? toInt(BATCH_SIZE, 500) : 500;
var database = db.getName ? db.getSiblingDB(db.getName()) : db;
if (!database) {
throw new Error("Unable to resolve database handle");
}
print("");
print("== LNM-21-102-DEV Backfill Rollback ==");
print("Database : " + database.getName());
print("Dry Run : " + dryRun);
print("Batch Size: " + batchSize);
print("");
// Step 1: Count and delete backfilled observations
var observationsCollection = database.getCollection("advisory_observations");
var observationsFilter = { backfill_marker: BACKFILL_MARKER };
var observationsCount = observationsCollection.countDocuments(observationsFilter);
print("Found " + observationsCount + " backfilled observations to remove.");
if (!dryRun && observationsCount > 0) {
var obsResult = observationsCollection.deleteMany(observationsFilter);
print("Deleted " + obsResult.deletedCount + " observations.");
}
// Step 2: Count and delete backfilled linksets
var linksetsCollection = database.getCollection("advisory_linksets");
var linksetsFilter = { backfill_marker: BACKFILL_MARKER };
var linksetsCount = linksetsCollection.countDocuments(linksetsFilter);
print("Found " + linksetsCount + " backfilled linksets to remove.");
if (!dryRun && linksetsCount > 0) {
var linkResult = linksetsCollection.deleteMany(linksetsFilter);
print("Deleted " + linkResult.deletedCount + " linksets.");
}
// Step 3: Clear tombstone markers from advisory_raw
var rawCollection = database.getCollection("advisory_raw");
var rawFilter = { backfill_marker: BACKFILL_MARKER };
var rawCount = rawCollection.countDocuments(rawFilter);
print("Found " + rawCount + " advisory_raw documents with tombstone markers to clear.");
if (!dryRun && rawCount > 0) {
var rawResult = rawCollection.updateMany(rawFilter, { $unset: { backfill_marker: "" } });
print("Cleared tombstone markers from " + rawResult.modifiedCount + " advisory_raw documents.");
}
// Step 4: Summary
print("");
print("== Rollback Summary ==");
if (dryRun) {
print("DRY RUN - No changes were made.");
print("Would delete " + observationsCount + " observations.");
print("Would delete " + linksetsCount + " linksets.");
print("Would clear " + rawCount + " tombstone markers.");
} else {
print("Observations deleted: " + observationsCount);
print("Linksets deleted : " + linksetsCount);
print("Tombstones cleared : " + rawCount);
}
print("");
print("Next steps:");
print("1. Delete the migration record:");
print(' db.schema_migrations.deleteOne({ _id: "20251127_lnm_legacy_backfill" })');
print("2. Restart the Concelier service.");
print("");
})();

View File

@@ -0,0 +1,60 @@
-- Rollback script for LNM-21-102-DEV legacy advisory backfill migration.
-- Removes backfilled observations and linksets by querying the backfill_marker field,
-- then clears the tombstone markers from advisory_raw.
--
-- Usage:
-- psql -d concelier -f ops/devops/tools/ops-scripts/rollback-lnm-backfill.sql
--
-- Environment variables:
-- DRY_RUN - if set to "1", only reports what would be deleted without making changes.
--
-- After running this script, delete the migration record:
-- DELETE FROM schema_migrations WHERE id = '20251127_lnm_legacy_backfill';
--
-- Then restart the Concelier service.
\echo ''
\echo '== LNM-21-102-DEV Backfill Rollback =='
\conninfo
-- Count backfilled observations
SELECT 'Found ' || COUNT(*) || ' backfilled observations to remove.' as status
FROM advisory_observations
WHERE backfill_marker = 'lnm_21_102_dev';
-- Count backfilled linksets
SELECT 'Found ' || COUNT(*) || ' backfilled linksets to remove.' as status
FROM advisory_linksets
WHERE backfill_marker = 'lnm_21_102_dev';
-- Count advisory_raw tombstone markers
SELECT 'Found ' || COUNT(*) || ' advisory_raw documents with tombstone markers to clear.' as status
FROM advisory_raw
WHERE backfill_marker = 'lnm_21_102_dev';
-- Only execute if not DRY_RUN
\if :{?DRY_RUN}
\echo 'DRY RUN mode - no changes made'
\echo 'Set DRY_RUN=0 or omit it to execute the rollback'
\else
-- Step 1: Delete backfilled observations
DELETE FROM advisory_observations WHERE backfill_marker = 'lnm_21_102_dev';
\echo 'Deleted observations'
-- Step 2: Delete backfilled linksets
DELETE FROM advisory_linksets WHERE backfill_marker = 'lnm_21_102_dev';
\echo 'Deleted linksets'
-- Step 3: Clear tombstone markers from advisory_raw
UPDATE advisory_raw SET backfill_marker = NULL WHERE backfill_marker = 'lnm_21_102_dev';
\echo 'Cleared tombstone markers'
\endif
\echo ''
\echo '== Rollback Summary =='
\echo ''
\echo 'Next steps:'
\echo '1. Delete the migration record:'
\echo ' DELETE FROM schema_migrations WHERE id = ''20251127_lnm_legacy_backfill'';'
\echo '2. Restart the Concelier service.'
\echo ''

Some files were not shown because too many files have changed in this diff Show More