#  17 · Security Hardening Guide — **Stella Ops** *(v2.0 — 12 Jul 2025)* > **Audience** — Site‑reliability and platform teams deploying **the open‑source Core** in production or restricted networks. --- ##  0 Table of Contents 1. Threat model (summary) 2. Host‑OS baseline 3. Container & runtime hardening 4. Network‑plane guidance 5. Secrets & key management 6. Image, SBOM & plug‑in supply‑chain controls 7. Logging, monitoring & audit 8. Update & patch strategy 9. Incident‑response workflow 10. Pen‑testing & continuous assurance 11. Contacts & vulnerability disclosure 12. Change log --- ##  1 Threat model (summary) | Asset | Threats | Mitigations | | -------------------- | --------------------- | ---------------------------------------------------------------------- | | SBOMs & scan results | Disclosure, tamper | TLS‑in‑transit, read‑only Redis volume, RBAC, Cosign‑verified plug‑ins | | Backend container | RCE, code‑injection | Distroless image, non‑root UID, read‑only FS, seccomp + `CAP_DROP:ALL` | | Update artefacts | Supply‑chain attack | Cosign‑signed images & SBOMs, enforced by admission controller | | Admin credentials | Phishing, brute force | OAuth 2.0 with 12‑h token TTL, optional mTLS | --- ##  2 Host‑OS baseline checklist | Item | Recommended setting | | ------------- | --------------------------------------------------------- | | OS | Ubuntu 22.04 LTS (kernel ≥ 5.15) or Alma 9 | | Patches | `unattended‑upgrades` or vendor‑equivalent enabled | | Filesystem | `noexec,nosuid` on `/tmp`, `/var/tmp` | | Docker Engine | v24.*, API socket root‑owned (`0660`) | | Auditd | Watch `/etc/docker`, `/usr/bin/docker*` and Compose files | | Time sync | `chrony` or `systemd‑timesyncd` | --- ##  3 Container & runtime hardening ###  3.1 Docker Compose reference (`compose-core.yml`) ```yaml services: backend: image: ghcr.io/stellaops/backend:1.5.0 user: "101:101" # non‑root read_only: true security_opt: - "no-new-privileges:true" - "seccomp:./seccomp-backend.json" cap_drop: [ALL] tmpfs: - /tmp:size=64m,exec,nosymlink environment: - ASPNETCORE_URLS=https://+:8080 - TLSPROVIDER=OpenSslGost depends_on: [redis] networks: [core-net] healthcheck: test: ["CMD", "wget", "-qO-", "https://localhost:8080/health"] interval: 30s timeout: 5s retries: 5 redis: image: redis:7.2-alpine command: ["redis-server", "--requirepass", "${REDIS_PASS}", "--rename-command", "FLUSHALL", ""] user: "redis" read_only: true cap_drop: [ALL] tmpfs: - /data networks: [core-net] networks: core-net: driver: bridge ``` No dedicated “Redis” or “Mongo” sub‑nets are declared; the single bridge network suffices for the default stack. ###  3.2 Kubernetes deployment highlights Use a separate NetworkPolicy that only allows egress from backend to Redis :6379. securityContext: runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation: false, drop all capabilities. PodDisruptionBudget of minAvailable: 1. Optionally add CosignVerified=true label enforced by an admission controller (e.g. Kyverno or Connaisseur). ##  4 Network‑plane guidance | Plane | Recommendation | | ------------------ | -------------------------------------------------------------------------- | | North‑south | Terminate TLS 1.2+ (OpenSSL‑GOST default). Use LetsEncrypt or internal CA. | | East‑west | Compose bridge or K8s ClusterIP only; no public Redis/Mongo ports. | | Ingress controller | Limit methods to GET, POST, PATCH (no TRACE). | | Rate‑limits | 40 rps default; tune ScannerPool.Workers and ingress limit‑req to match. | ##  5 Secrets & key management | Secret | Storage | Rotation | | --------------------------------- | ---------------------------------- | ----------------------------- | | **Client‑JWT (offline)** | `/var/lib/stella/tokens/client.jwt` (root : 600) | **30 days** – provided by each OUK | | REDIS_PASS | Docker/K8s secret | 90 days | | OAuth signing key | /keys/jwt.pem (read‑only mount) | 180 days | | Cosign public key | /keys/cosign.pub baked into image; | change on every major release | | Trivy DB mirror token (if remote) | Secret + read‑only | 30 days | Never bake secrets into images; always inject at runtime. > **Operational tip:** schedule a cron reminding ops 5 days before > `client.jwt` expiry. The backend also emits a Prometheus metric > `stella_quota_token_days_remaining`. ##  6 Image, SBOM & plug‑in supply‑chain controls * Images — Pull by digest not latest; verify: ```bash cosign verify ghcr.io/stellaops/backend@sha256: \ --key https://stella-ops.org/keys/cosign.pub ``` * SBOM — Each release ships an SPDX file; store alongside images for audit. * Third‑party plug‑ins — Place in /plugins/; backend will: * Validate Cosign signature. * Check [StellaPluginVersion("major.minor")]. * Refuse to start if Security.DisablePluginUnsigned=false (default). ##  7 Logging, monitoring & audit | Control | Implementation | | ------------ | ----------------------------------------------------------------- | | Log format | Serilog JSON; ship via Fluent‑Bit to ELK or Loki | | Metrics | Prometheus /metrics endpoint; default Grafana dashboard in infra/ | | Audit events | Redis stream audit; export daily to SIEM | | Alert rules | Feed age  ≥ 48 h, P95 wall‑time > 5 s, Redis used memory > 75 % | ##  8 Update & patch strategy | Layer | Cadence | Method | | -------------------- | -------------------------------------------------------- | ------------------------------ | | Backend & CLI images | Monthly or CVE‑driven docker pull + docker compose up -d | | Trivy DB | 24 h cron via FeedMerger | configurable (FeedMerger.Cron) | | Docker Engine | vendor LTS | distro package manager | | Host OS | security repos enabled | unattended‑upgrades | ##  9 Incident‑response workflow * Detect — PagerDuty alert from Prometheus or SIEM. * Contain — Stop affected Backend container; isolate Redis RDB snapshot. * Eradicate — Pull verified images, redeploy, rotate secrets. * Recover — Restore RDB, replay SBOMs if history lost. * Review — Post‑mortem within 72 h; create follow‑up issues. * Escalate P1 incidents to (24 × 7). ##  10 Pen‑testing & continuous assurance | Control | Frequency | Tool | |-------------------|-------------------| | OWASP | ZAP baseline | Each merge to main GitHub Action zap-baseline-scan | | Dependency scanning | Pull request | Trivy FS + GitHub Dependabot | | External red‑team | Annual or before GA | 3rd‑party CREST‑accredited vendor | ##  11 Vulnerability disclosure & contact * Preferred channel: security@stella‑ops.org (GPG key on website). * Coordinated disclosure reward: public credit and swag (no monetary bounty at this time). ##  12 Change log | Version | Date | Notes | | ------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------- | | v2.0 | 2025‑07‑12 | Full overhaul: host‑OS baseline, supply‑chain signing, removal of unnecessary sub‑nets, role‑based contact e‑mail, K8s guidance. | | v1.1 | 2025‑07‑09 | Minor fence fixes. | | v1.0 | 2025‑07‑09 | Original draft. |