docs(P00): v0.12 security-hardening phase 0 (specify/clarify/research/ideate/plan/grill)
---ci--- project: orca phase: 0 milestone: v0.12 status: specify ---/ci--- Threat-model review of entire surface incl OS (25 findings F1..F25). Adopts R-021 (no Orca credentials: human=OIDC, machine=mTLS/SPIFFE). Bundled Dex + WebAuthn (passkeys) as default password-free authenticator. Master key seal-to-OIDC + Shamir 3-of-5 recovery. 30 net-new requirements (REQ-119..REQ-148). 29 phases. Binding conditions C-29..C-38.
This commit is contained in:
@@ -399,3 +399,152 @@ tags: `v0.10.0`…`v0.10.21`.
|
||||
- Leader-elected Raft coordinator
|
||||
- External CA / Let's Encrypt / cert transparency
|
||||
- Online-only features (HSTS, OCSP stapling, telemetry)
|
||||
|
||||
## Milestone v0.12: Security Hardening (Zero-Trust Identity) — IN PROGRESS
|
||||
|
||||
**Scope**: comprehensive security hardening across the entire attack
|
||||
surface, **including the operating system itself**, plus adoption of a
|
||||
zero-trust identity model. The v0.12 threat-model review (Phase 0
|
||||
RESEARCH) surfaced 25 distinct findings (F1..F25) spanning injection,
|
||||
traversal, ACL, audit, crypto, OS scripts, emitters, sudoers, system
|
||||
users, file modes, daemon auth, backup, SQLite, install.sh, and
|
||||
migration. v0.12 closes all of them and adopts **R-021** (no Orca
|
||||
credentials) as the load-bearing architectural change: human identity is
|
||||
exclusively external (OIDC), machine identity is exclusively
|
||||
mTLS/SPIFFE, and no passwords/Orca-issued-tokens/CA-key-passphrases
|
||||
exist anywhere in the system.
|
||||
|
||||
The operator locked two architectural decisions: **(1) bundled Dex by
|
||||
default + BYO external IdP override** (D-239), and **(2) master key
|
||||
seal-to-OIDC + Shamir 3-of-5 recovery** (D-241). A third decision added
|
||||
**WebAuthn (passkeys) as the bundled password-free authenticator** for
|
||||
Dex (D-240) -- passkeys are public-key credentials (private key never
|
||||
leaves the authenticator), directly satisfying R-021.
|
||||
|
||||
**Milestone type**: feature (P04 OIDC+Dex and P05 WebAuthn ship `feat`
|
||||
phases; the rest are `fix`/`chore`/`test`/`docs`/`refactor`).
|
||||
|
||||
- [ ] Phase 0: Pre-execution (specify -> clarify -> research -> ideate -> plan -> grill) -- tag `v0.11.0`
|
||||
- [ ] Phase P01: Command injection fix (podman/wasm shellQuote) (REQ-119, F3) -- tag `v0.11.1`
|
||||
- [ ] Phase P02: Namespace path traversal fix (REQ-120, F4) -- tag `v0.11.2`
|
||||
- [ ] Phase P03: Txn apply path allowlist (REQ-121, F5) -- tag `v0.11.3`
|
||||
- [ ] Phase P04: OIDC client + bundled Dex (REQ-144; BYO-IdP override) -- tag `v0.11.4`
|
||||
- [ ] Phase P05: WebAuthn connector for Dex (REQ-148; passkeys, browser auth+register) -- tag `v0.11.5`
|
||||
- [ ] Phase P06: ACL rewrite to OIDC claims + enforcement (REQ-145, REQ-122, F1) -- tag `v0.11.6`
|
||||
- [ ] Phase P07: Remove all password/token paths (breaking; REQ-146, R-021, C-34) -- tag `v0.11.7`
|
||||
- [ ] Phase P08: Master key seal-to-OIDC + Shamir 3-of-5 (REQ-147, C-35) -- tag `v0.11.8`
|
||||
- [ ] Phase P09: Daemon auth hardening (REQ-123, REQ-124, F6, F24) -- tag `v0.11.9`
|
||||
- [ ] Phase P10: Audit log tamper-evidence (REQ-125, F2) -- tag `v0.11.10`
|
||||
- [ ] Phase P11: SVID chain validation (REQ-126, F9) -- tag `v0.11.11`
|
||||
- [ ] Phase P12: Backup symlink validation (REQ-127, F7) -- tag `v0.11.12`
|
||||
- [ ] Phase P13: step-ca /tmp hardening (REQ-128, F10) -- tag `v0.11.13`
|
||||
- [ ] Phase P14: Master key rotation (re-seal to OIDC; REQ-129, F12, C-30) -- tag `v0.11.14`
|
||||
- [ ] Phase P15: File-mode audit expansion (REQ-130, F13) -- tag `v0.11.15`
|
||||
- [ ] Phase P16: aggregate.sh JSON injection + drift-gate parse fix (REQ-131, F11, F18) -- tag `v0.11.16`
|
||||
- [ ] Phase P17: install.sh checksum+GPG verification (REQ-132, F14) -- tag `v0.11.17`
|
||||
- [ ] Phase P18: nftables ruleset hardening (REQ-133, F21) -- tag `v0.11.18`
|
||||
- [ ] Phase P19: sudoers hardening (REQ-134, F22) -- tag `v0.11.19`
|
||||
- [ ] Phase P20: System user consistency (REQ-135, F23) -- tag `v0.11.20`
|
||||
- [ ] Phase P21: SQLite file-mode + at-rest encryption (REQ-136, F8, C-31) -- tag `v0.11.21`
|
||||
- [ ] Phase P22: Migration safety + identity migration (REQ-137, F19, C-34) -- tag `v0.11.22`
|
||||
- [ ] Phase P23: Legacy CA/mTLS/daemon + step-ca password-provisioner deletion (REQ-138, F16; **gate C-29: P06/P08/P09/P11**) -- tag `v0.11.23`
|
||||
- [ ] Phase P24: known_hosts tightening + transport hardening (REQ-139, F15, F25) -- tag `v0.11.24`
|
||||
- [ ] Phase P25: Drift event authentication (REQ-140, F18) -- tag `v0.11.25`
|
||||
- [ ] Phase P26: Security integration test suite (REQ-141, C-33) -- tag `v0.11.26`
|
||||
- [ ] Phase P27: Zero-trust + OIDC + WebAuthn + threat-model docs (REQ-142) -- tag `v0.11.27`
|
||||
- [ ] Phase P28: Final review + ship + audit (milestone release) -- tag `v0.11.28` = **v0.12 milestone release**
|
||||
|
||||
**Milestone tag**: `v0.11.28` (final phase patch = milestone release per
|
||||
feature-milestone progressive-patch rule; no separate `v0.12.0` tag).
|
||||
Per-phase tags: `v0.11.0`..`v0.11.28` (29 tags). Tags run on the
|
||||
previous minor's patch line (v0.11.x) per branch-strategy.md. The
|
||||
milestone branch label uses the milestone number
|
||||
(`milestone/v0.12-security-hardening`); no separate minor tag.
|
||||
|
||||
The v1.0.0 production-ready tag stays deferred for post-v0.12 UAT
|
||||
(per v0.11 PRD; v0.12 is a minor feature milestone, not the v1.0 cut).
|
||||
|
||||
### Per-phase REQ coverage (v0.12)
|
||||
|
||||
- **P01** -- Command injection (REQ-119, F3)
|
||||
- **P02** -- Namespace path traversal (REQ-120, F4)
|
||||
- **P03** -- Txn apply path allowlist (REQ-121, F5)
|
||||
- **P04** -- OIDC client + bundled Dex (REQ-144; D-239, D-242, D-246)
|
||||
- **P05** -- WebAuthn connector (REQ-148; D-240, D-243, D-244, C-38)
|
||||
- **P06** -- ACL rewrite + enforcement (REQ-145, REQ-122, F1)
|
||||
- **P07** -- Remove password/token paths (REQ-146, R-021, C-34)
|
||||
- **P08** -- Master key seal-to-OIDC + Shamir (REQ-147, D-241, C-35)
|
||||
- **P09** -- Daemon auth (REQ-123, REQ-124, F6, F24)
|
||||
- **P10** -- Audit tamper-evidence (REQ-125, F2)
|
||||
- **P11** -- SVID chain validation (REQ-126, F9)
|
||||
- **P12** -- Backup symlink validation (REQ-127, F7)
|
||||
- **P13** -- step-ca /tmp hardening (REQ-128, F10)
|
||||
- **P14** -- Master key rotation (REQ-129, F12, C-30)
|
||||
- **P15** -- File-mode audit expansion (REQ-130, F13)
|
||||
- **P16** -- aggregate.sh JSON injection + drift-gate (REQ-131, F11, F18)
|
||||
- **P17** -- install.sh checksum+GPG (REQ-132, F14)
|
||||
- **P18** -- nftables ruleset hardening (REQ-133, F21)
|
||||
- **P19** -- sudoers hardening (REQ-134, F22)
|
||||
- **P20** -- System user consistency (REQ-135, F23)
|
||||
- **P21** -- SQLite file-mode + encryption (REQ-136, F8, C-31)
|
||||
- **P22** -- Migration safety + identity migration (REQ-137, F19, C-34)
|
||||
- **P23** -- Dual-write closure (REQ-138, F16; **gate C-29**)
|
||||
- **P24** -- known_hosts + transport hardening (REQ-139, F15, F25)
|
||||
- **P25** -- Drift event authentication (REQ-140, F18)
|
||||
- **P26** -- Security integration test suite (REQ-141, C-33)
|
||||
- **P27** -- Zero-trust + OIDC + WebAuthn + threat-model docs (REQ-142)
|
||||
- **P28** -- Final review + ship + audit (REQ-143)
|
||||
|
||||
### New load-bearing rule adopted in Phase 0
|
||||
|
||||
- **R-021** -- Orca never issues, stores, or accepts human-identity
|
||||
credentials. Human identity is exclusively external (OIDC). Machine
|
||||
identity is exclusively mTLS/SPIFFE. No passwords, no Orca-issued
|
||||
tokens, no CA-key passphrases.
|
||||
|
||||
### Binding conditions (for GRILL ratification; C-29..C-38)
|
||||
|
||||
- **C-29**: P23 (dual-write closure) gated on P06/P08/P09/P11 all shipped.
|
||||
- **C-30**: P14 (master key rotation) reversible; `--dry-run` mandatory; auto-rollback to old sealed key on any ns failure.
|
||||
- **C-31**: P21 (SQLite encryption): CGO-free fallback to file-mode 0600 + documented threat if SQLCipher needs CGO. No CGO.
|
||||
- **C-32**: **Human-gate**: leaked GITEA_TOKEN (F17) rotated + `.env` re-seeded before P28 ships. History-scrub best-effort, non-blocking. Escalation hook in `---ci---`.
|
||||
- **C-33**: P26 (security integration tests) in `.coreci.yml` `validate`, gates merges -- not opt-in.
|
||||
- **C-34**: P07 (password/token removal) breaking. `orca upgrade` (P22) refuses v0.11 clusters using `--password`/bare-tokens without `--accept-identity-migration`. No silent breakage.
|
||||
- **C-35**: P08 (Shamir recovery): 3-of-5 shards printed at seal time, operator stores offline. If IdP lost AND quorum unavailable -> cluster unrecoverable by design (documented residual risk). No backdoor.
|
||||
- **C-36**: OIDC client secret (confidential clients) at `ClusterDir()/oidc-client-secret` (0600), rotatable via `orca auth rotate-client-secret`, never committed. Public PKCE clients avoid even this.
|
||||
- **C-37**: P04 (bundled Dex): if WebAuthn proves infeasible, bundled Dex ships mTLS-client-cert-only; password-based upstreams require BYO external IdP. The "no Orca credentials" invariant holds regardless. *(Largely moot -- WebAuthn solves it.)*
|
||||
- **C-38**: P05 (WebAuthn): RP ID must match the cluster's Traefik-served domain; `orca auth init-idp` configures it. HTTPS secure context via Traefik (step-ca cert). P26 integration tests use the WebAuthn virtual-authenticator API -- no hardware key required in CI.
|
||||
|
||||
### Risk register (from grill + research, for ongoing monitoring)
|
||||
|
||||
- **P07 breaking change** (mitigation: C-34 migration gate)
|
||||
- **P08 master key seal is riskiest** (mitigation: `--dry-run`, atomic, auto-rollback, C-35 Shamir recovery)
|
||||
- **P21 SQLite encryption may need CGO** (mitigation: C-31 fallback to file-mode 0600)
|
||||
- **P23 dual-write closure high-impact** (mitigation: gate C-29; full test coverage before deletion)
|
||||
- **P05 WebAuthn connector is new ground** (mitigation: C-37 mTLS-client-cert fallback; virtual-authenticator tests in P26)
|
||||
- **Bundled Dex is a new systemd unit + Traefik route** (mitigation: `orca doctor oidc` health check)
|
||||
- **C-32 human gate could stall final ship** (mitigation: ship as `v0.11.28-rc1` if rotation pending)
|
||||
- **29 phases is large** (mitigation: grill may split/merge; operator accepted "more than 20 if warranted")
|
||||
|
||||
### Deferred to v1.x (out of scope for v0.12)
|
||||
|
||||
- HA step-ca (active/passive via systemd)
|
||||
- `sqlite-wal-shared` / `git` / `file+flock` state backends
|
||||
- OS keyring integration for master key (v0.12 uses OIDC seal instead)
|
||||
- Full cluster-rolling-upgrade orchestrator (v0.12 ships the thin `orca upgrade` wrapper only)
|
||||
- Live-migrate with storage replication (v0.12 ships drain+reschedule only)
|
||||
- Journald log shipping (optional centralized audit)
|
||||
- Network policy (`nftables` snippets beyond the ingress ruleset)
|
||||
- GPU / TPU constraints
|
||||
|
||||
### Deferred to v2.x (out of scope for v1.x)
|
||||
|
||||
- Full Nomad-HCL parser with no conversion round-trip
|
||||
- Nomad-API subset for migrating existing Nomad fleets
|
||||
- Nomad driver bridge
|
||||
- Helm-equivalent templating (probably never)
|
||||
- Service mesh beyond Traefik
|
||||
- CRDs / Operators / Plugin model
|
||||
- Leader-elected Raft coordinator
|
||||
- External CA / Let's Encrypt / cert transparency
|
||||
- Online-only features (HSTS, OCSP stapling, telemetry)
|
||||
|
||||
Reference in New Issue
Block a user