# Content Addressable Storage (CAS) Infrastructure # Uses RustFS for S3-compatible immutable object storage # Aligned with best-in-class vulnerability scanner retention policies # # Usage: # docker compose -f docker-compose.cas.yaml up -d # docker compose -f docker-compose.cas.yaml -f docker-compose.dev.yaml up -d x-release-labels: &release-labels com.stellaops.release.version: "2025.10.0-edge" com.stellaops.release.channel: "edge" com.stellaops.profile: "cas" x-cas-config: &cas-config # Retention policies (aligned with Trivy/Grype/Anchore Enterprise) # - vulnerability-db: 7 days (matches Trivy default) # - sbom-artifacts: 365 days (audit compliance) # - scan-results: 90 days (SOC2/ISO27001 typical) # - evidence-bundles: indefinite (immutable, content-addressed) # - attestations: indefinite (in-toto/DSSE signed) CAS__RETENTION__VULNERABILITY_DB_DAYS: "7" CAS__RETENTION__SBOM_ARTIFACTS_DAYS: "365" CAS__RETENTION__SCAN_RESULTS_DAYS: "90" CAS__RETENTION__EVIDENCE_BUNDLES_DAYS: "0" # 0 = indefinite CAS__RETENTION__ATTESTATIONS_DAYS: "0" # 0 = indefinite CAS__RETENTION__TEMP_ARTIFACTS_DAYS: "1" networks: cas: driver: bridge volumes: rustfs-cas-data: driver: local driver_opts: type: none o: bind device: ${CAS_DATA_PATH:-/var/lib/stellaops/cas} rustfs-evidence-data: driver: local driver_opts: type: none o: bind device: ${CAS_EVIDENCE_PATH:-/var/lib/stellaops/evidence} rustfs-attestation-data: driver: local driver_opts: type: none o: bind device: ${CAS_ATTESTATION_PATH:-/var/lib/stellaops/attestations} services: # Primary CAS storage - runtime facts, signals, replay artifacts rustfs-cas: image: registry.stella-ops.org/stellaops/rustfs:2025.10.0-edge command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"] restart: unless-stopped environment: RUSTFS__LOG__LEVEL: "${RUSTFS_LOG_LEVEL:-info}" RUSTFS__STORAGE__PATH: /data RUSTFS__STORAGE__DEDUP: "true" RUSTFS__STORAGE__COMPRESSION: "${RUSTFS_COMPRESSION:-zstd}" RUSTFS__STORAGE__COMPRESSION_LEVEL: "${RUSTFS_COMPRESSION_LEVEL:-3}" # Bucket lifecycle (retention enforcement) RUSTFS__LIFECYCLE__ENABLED: "true" RUSTFS__LIFECYCLE__SCAN_INTERVAL_HOURS: "24" RUSTFS__LIFECYCLE__DEFAULT_RETENTION_DAYS: "90" # Access control RUSTFS__AUTH__ENABLED: "${RUSTFS_AUTH_ENABLED:-true}" RUSTFS__AUTH__API_KEY: "${RUSTFS_CAS_API_KEY:-cas-api-key-change-me}" RUSTFS__AUTH__READONLY_KEY: "${RUSTFS_CAS_READONLY_KEY:-cas-readonly-key-change-me}" # Service account configuration RUSTFS__ACCOUNTS__SCANNER__KEY: "${RUSTFS_SCANNER_KEY:-scanner-svc-key}" RUSTFS__ACCOUNTS__SCANNER__BUCKETS: "scanner-artifacts,surface-cache,runtime-facts" RUSTFS__ACCOUNTS__SCANNER__PERMISSIONS: "read,write" RUSTFS__ACCOUNTS__SIGNALS__KEY: "${RUSTFS_SIGNALS_KEY:-signals-svc-key}" RUSTFS__ACCOUNTS__SIGNALS__BUCKETS: "runtime-facts,signals-data,provenance-feed" RUSTFS__ACCOUNTS__SIGNALS__PERMISSIONS: "read,write" RUSTFS__ACCOUNTS__REPLAY__KEY: "${RUSTFS_REPLAY_KEY:-replay-svc-key}" RUSTFS__ACCOUNTS__REPLAY__BUCKETS: "replay-bundles,inputs-lock" RUSTFS__ACCOUNTS__REPLAY__PERMISSIONS: "read,write" RUSTFS__ACCOUNTS__READONLY__KEY: "${RUSTFS_READONLY_KEY:-readonly-svc-key}" RUSTFS__ACCOUNTS__READONLY__BUCKETS: "*" RUSTFS__ACCOUNTS__READONLY__PERMISSIONS: "read" <<: *cas-config volumes: - rustfs-cas-data:/data ports: - "${RUSTFS_CAS_PORT:-8180}:8080" networks: - cas labels: *release-labels healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s # Evidence storage - Merkle roots, hash chains, evidence bundles (immutable) rustfs-evidence: image: registry.stella-ops.org/stellaops/rustfs:2025.10.0-edge command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data", "--immutable"] restart: unless-stopped environment: RUSTFS__LOG__LEVEL: "${RUSTFS_LOG_LEVEL:-info}" RUSTFS__STORAGE__PATH: /data RUSTFS__STORAGE__DEDUP: "true" RUSTFS__STORAGE__COMPRESSION: "${RUSTFS_COMPRESSION:-zstd}" RUSTFS__STORAGE__IMMUTABLE: "true" # Write-once, never delete # Access control RUSTFS__AUTH__ENABLED: "true" RUSTFS__AUTH__API_KEY: "${RUSTFS_EVIDENCE_API_KEY:-evidence-api-key-change-me}" RUSTFS__AUTH__READONLY_KEY: "${RUSTFS_EVIDENCE_READONLY_KEY:-evidence-readonly-key-change-me}" # Service accounts RUSTFS__ACCOUNTS__LEDGER__KEY: "${RUSTFS_LEDGER_KEY:-ledger-svc-key}" RUSTFS__ACCOUNTS__LEDGER__BUCKETS: "evidence-bundles,merkle-roots,hash-chains" RUSTFS__ACCOUNTS__LEDGER__PERMISSIONS: "read,write" RUSTFS__ACCOUNTS__EXPORTER__KEY: "${RUSTFS_EXPORTER_KEY:-exporter-svc-key}" RUSTFS__ACCOUNTS__EXPORTER__BUCKETS: "evidence-bundles" RUSTFS__ACCOUNTS__EXPORTER__PERMISSIONS: "read" volumes: - rustfs-evidence-data:/data ports: - "${RUSTFS_EVIDENCE_PORT:-8181}:8080" networks: - cas labels: *release-labels healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s # Attestation storage - DSSE envelopes, in-toto attestations (immutable) rustfs-attestation: image: registry.stella-ops.org/stellaops/rustfs:2025.10.0-edge command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data", "--immutable"] restart: unless-stopped environment: RUSTFS__LOG__LEVEL: "${RUSTFS_LOG_LEVEL:-info}" RUSTFS__STORAGE__PATH: /data RUSTFS__STORAGE__DEDUP: "true" RUSTFS__STORAGE__COMPRESSION: "${RUSTFS_COMPRESSION:-zstd}" RUSTFS__STORAGE__IMMUTABLE: "true" # Write-once, never delete # Access control RUSTFS__AUTH__ENABLED: "true" RUSTFS__AUTH__API_KEY: "${RUSTFS_ATTESTATION_API_KEY:-attestation-api-key-change-me}" RUSTFS__AUTH__READONLY_KEY: "${RUSTFS_ATTESTATION_READONLY_KEY:-attestation-readonly-key-change-me}" # Service accounts RUSTFS__ACCOUNTS__ATTESTOR__KEY: "${RUSTFS_ATTESTOR_KEY:-attestor-svc-key}" RUSTFS__ACCOUNTS__ATTESTOR__BUCKETS: "attestations,dsse-envelopes,rekor-receipts" RUSTFS__ACCOUNTS__ATTESTOR__PERMISSIONS: "read,write" RUSTFS__ACCOUNTS__VERIFIER__KEY: "${RUSTFS_VERIFIER_KEY:-verifier-svc-key}" RUSTFS__ACCOUNTS__VERIFIER__BUCKETS: "attestations,dsse-envelopes,rekor-receipts" RUSTFS__ACCOUNTS__VERIFIER__PERMISSIONS: "read" volumes: - rustfs-attestation-data:/data ports: - "${RUSTFS_ATTESTATION_PORT:-8182}:8080" networks: - cas labels: *release-labels healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s # Lifecycle manager - enforces retention policies cas-lifecycle: image: registry.stella-ops.org/stellaops/cas-lifecycle:2025.10.0-edge restart: unless-stopped depends_on: rustfs-cas: condition: service_healthy environment: LIFECYCLE__CAS__ENDPOINT: "http://rustfs-cas:8080" LIFECYCLE__CAS__API_KEY: "${RUSTFS_CAS_API_KEY:-cas-api-key-change-me}" LIFECYCLE__SCHEDULE__CRON: "${LIFECYCLE_CRON:-0 3 * * *}" # 3 AM daily LIFECYCLE__POLICIES__VULNERABILITY_DB: "7d" LIFECYCLE__POLICIES__SBOM_ARTIFACTS: "365d" LIFECYCLE__POLICIES__SCAN_RESULTS: "90d" LIFECYCLE__POLICIES__TEMP_ARTIFACTS: "1d" LIFECYCLE__TELEMETRY__ENABLED: "${LIFECYCLE_TELEMETRY:-true}" LIFECYCLE__TELEMETRY__OTLP_ENDPOINT: "${OTLP_ENDPOINT:-}" networks: - cas labels: *release-labels