Some checks failed
		
		
	
	Build Test Deploy / authority-container (push) Has been cancelled
				
			Build Test Deploy / docs (push) Has been cancelled
				
			Build Test Deploy / deploy (push) Has been cancelled
				
			Build Test Deploy / build-test (push) Has been cancelled
				
			Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
			
				
	
	
		
			202 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
| #  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: registry.stella-ops.org/stella-ops/stella-ops:<PINNED_TAG_OR_DIGEST>
 | ||
|     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:<DIGEST> \
 | ||
|   --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 %   |
 | ||
| 
 | ||
| ###  7.1 Feedser authorization audits
 | ||
| 
 | ||
| - Enable the Authority integration for Feedser (`authority.enabled=true`). Keep
 | ||
|   `authority.allowAnonymousFallback` set to `true` only during migration and plan
 | ||
|   to disable it before **2025-12-31 UTC** so the `/jobs*` surface always demands
 | ||
|   a bearer token.
 | ||
| - Store the Authority client secret using Docker/Kubernetes secrets and point
 | ||
|   `authority.clientSecretFile` at the mounted path; the value is read at startup
 | ||
|   and never logged.
 | ||
| - Watch the `Feedser.Authorization.Audit` logger. Each entry contains the HTTP
 | ||
|   status, subject, client ID, scopes, remote IP, and a boolean `bypass` flag
 | ||
|   showing whether a network bypass CIDR allowed the request. Configure your SIEM
 | ||
|   to alert when unauthenticated requests (`status=401`) appear with
 | ||
|   `bypass=true`, or when unexpected scopes invoke job triggers.
 | ||
| 
 | ||
| ##  8 Update & patch strategy
 | ||
| 
 | ||
| | Layer                | Cadence                                                  | Method                         |
 | ||
| | -------------------- | -------------------------------------------------------- | ------------------------------ |
 | ||
| | Backend & CLI images | Monthly or CVE‑driven docker pull + docker compose up -d |
 | ||
| | Trivy DB             | 24 h scheduler via Feedser (vulnerability ingest/merge/export service) | configurable via Feedser scheduler options |
 | ||
| | 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 <security@stella‑ops.org> (24 × 7).
 | ||
| 
 | ||
| 
 | ||
| ##  10 Pen‑testing & continuous assurance
 | ||
| 
 | ||
| | Control              | Frequency             | Tool/Runner                               |
 | ||
| |----------------------|-----------------------|-------------------------------------------|
 | ||
| | OWASP ZAP baseline   | Each merge to `main`  | GitHub Action `zap-baseline-scan`         |
 | ||
| | Dependency scanning  | Per pull request      | Trivy FS + Dependabot                     |
 | ||
| | External red‑team    | Annual or pre‑GA      | CREST‑accredited third‑party              |
 | ||
| 
 | ||
| ##  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.                                                                                                                  |
 |