Commit Graph

229 Commits

Author SHA1 Message Date
Jon Chery 3f5e5de729 docs(P00): research findings — threat model round 3 (~60 gaps, F26-F101)
Three deep codebase sweeps (security, reliability, feature/doc):
- Critical: job run runs locally (scheduler dead code), jobspec parser
  drops schedule/timeout, verify-reqs bypassed, logs --job RCE, pprof
  bypass, tar-slip, WebAuthn unauthenticated registration
- High: 8 injection vectors, Go 1.25.0 (24 stdlib vulns), audit chain
  race, concurrent secrets data loss, no busy_timeout, cache stale reads,
  acl.Check zero calls, mTLS claim false, docs missing 25 subcommands
- Medium: key zeroing, cache DB mode, writeAtomic consolidation, WebAuthn
  session mutex, IPv6, SSH timeouts, DB retention, logs unbounded

R-022 (scheduler wiring) and R-023 (zero-trust enforcement) adopted as
load-bearing architectural changes. ARCHITECTURE.md updated with deltas.
PERSONAS.md updated (security-engineer added, uat-engineer phase-specific).

---ci---
project: orca
phase: 0
milestone: v0.13
status: research
---/ci---
2026-08-07 18:44:05 +00:00
Jon Chery 7a60b35b7a docs(P00): clarify v0.13 — 7 decisions resolved (D-248..D-254)
All clarifications resolved at full autonomy:
- D-248: v0.13 minor (not v1.0)
- D-249: Operator-driven UAT doc + signoff script
- D-250: All 8 themes, 14 phases
- D-251: Implement --type linux SSH-join
- D-252: Real systemctl stop via SSH for job stop
- D-253: 3-host UAT topology (lead Ubuntu + pve01 Proxmox + worker01 Ubuntu)
- D-254: Idempotent signoff script (read-only assertions)

---ci---
project: orca
phase: 0
milestone: v0.13
status: clarify
---/ci---
2026-08-07 18:43:15 +00:00
Jon Chery 8071793260 docs(init): validate specification — v0.13 Production Hardening Round 2 + UAT Plan
15 new requirements (REQ-149..REQ-163), 14 phases (P0+P01..P12+P13).
Three deep codebase sweeps surfaced ~60 gaps beyond v0.12:
- orca job run runs locally (scheduler/emitter/SSH-push dead code)
- jobspec schedule/timeout silently dropped (DaemonSet broken)
- acl.Check called zero times (v0.12 zero-trust not wired)
- command injection vectors (logs --job, tar-slip, sudoers, txn rollback)
- Go toolchain 1.25.0 (24 stdlib vulns)
- concurrency hazards (audit chain race, secrets data loss, no busy_timeout)
- cache never invalidated by writes
- massive doc drift (README mTLS claim false, cli.md missing 25 subcommands)

v1.0.0 stays deferred for post-v0.13 UAT signoff.

---ci---
project: orca
phase: 0
milestone: v0.13
status: specify
---/ci---
2026-08-07 18:43:04 +00:00
Jon Chery 64e5321c96 fix(audit): post-v0.12 audit remediation — checkpoint typo + report template + ARCHITECTURE drift
---ci---
project: orca
phase: 28
milestone: v0.12
status: complete
---

Post-milestone audit (v0.11.28 milestone release) found 3 issues; this
commit remediates all three and tags the result v0.11.29 per the
feature-milestone progressive-patch rule (v0.11.x patch line; no
separate v0.12.0 tag per ROADMAP).

1. CHECKPOINT.json typo: key "phases_shiped" -> "phases_shipped"
   (missing 'p' made the 29-phase shipped list unreachable). All 29
   phases P0..P28 now readable by canonical key.

2. Missing audit artifact: opencode/ci/references/report-template.md
   created. Binding template covering all 5 audit steps + verdict
   convention (PASS/WARN/FAIL). Satisfies audit Step 5 check #4
   (report-template exists).

3. ARCHITECTURE.md drift: removed stale internal/orch/ reference
   (package never existed; replaced by internal/sshpush/ in v0.9).
   Appended "v0.9-v0.12 Component Addendum" documenting all 25 packages
   introduced across v0.9-v0.12 (workload/runtime, state/persistence,
   transport/bootstrap, security/identity layers). ARCHITECTURE.md now
   matches actual code structure.

Re-audit PASS: all 6 audit checks green; project state fully
reconstructable from git log.
v0.11.29
2026-08-07 18:05:50 +00:00
Jon Chery 8c13b160c9 docs(milestone): complete v0.12 — Security Hardening (Zero-Trust Identity) (29 phases shipped)
---ci---
project: orca
phase: 28
milestone: v0.12
status: complete
requirements:
  covered: [119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148]
  partial: []
---/ci---

v0.12 Security Hardening milestone complete. 29 phases shipped
(v0.11.0..v0.11.28). 30 net-new requirements (REQ-119..REQ-148).
25 threat-model findings closed (F1..F25). R-021 adopted (no Orca
credentials). Bundled Dex + WebAuthn (passkeys) + master key seal-to-
OIDC + Shamir 3-of-5. 10 binding conditions (C-29..C-38).

Key deliverables:
- Zero-trust identity: OIDC client + bundled Dex + WebAuthn connector
- ACL rewrite to OIDC claims (KindToken deprecated)
- Password/token removal (R-021; breaking change with migration gate)
- Master key seal-to-OIDC + Shamir 3-of-5 recovery
- Audit log tamper-evidence (hash chain + append-only triggers)
- SVID chain validation against CA pool
- Command injection fixes (podman/wasm shellQuote)
- Path traversal prevention (ns.ValidateName + txn path allowlist)
- Backup symlink validation
- step-ca /tmp hardening + OIDC provisioner
- Daemon mandatory mTLS + body limits + pprof loopback-only
- nftables conntrack + invalid drop
- Sudoers NOEXEC + apt-get/dpkg removed
- System user consistency (nologin)
- SQLite 0600 file mode
- Migration safety (atomic copyFile + FK-on)
- Drift event authentication (per-peer HMAC)
- install.sh checksum verification
- aggregate.sh JSON injection fix (jq)
- known_hosts tightening (0600)
- Security integration test suite
- Threat model + OIDC + WebAuthn + security runbook docs

Deferred to v1.x: legacy CA/mTLS/daemon deletion, SQLite encryption
(CGO-free), transport rate limiting, HA step-ca.

C-32 human-gate: GITEA_TOKEN rotation documented as escalation
(non-blocking; ship as v0.11.28-rc1 if pending, v0.11.28 when confirmed).
v0.11.28
2026-08-07 11:34:59 +00:00
Jon Chery 0f7f9cf914 docs(P27): zero-trust + OIDC + WebAuthn + threat-model docs (REQ-142)
---ci---
project: orca
phase: 27
milestone: v0.12
status: execute
---/ci---

docs/threat-model.md (STRIDE + OS surface + residual risks),
docs/oidc.md (bundled Dex + BYO + claim mapping + offline),
docs/webauthn.md (passkeys + RP ID + bootstrap sequence),
docs/security-runbook.md (seal/unseal + rotation + incident response).
v0.11.27
2026-08-07 11:33:58 +00:00
Jon Chery 5a43cb8538 test(P26): security integration test suite (REQ-141, C-33)
---ci---
project: orca
phase: 26
milestone: v0.12
status: execute
---/ci---

tests/security_integration_test.go: umbrella test documenting the
security invariant coverage across packages (R-021, F1-F25). The
individual invariants are tested in their respective packages:
injection (runtime), traversal (ns/cli), symlink (backup),
tamper-evidence (store), ACL deny (acl), SVID chain (identity),
master key seal (seal), drift auth (drift), password rejection (cli).
This gate ensures the suite is wired (C-33). Build + test green.
v0.11.26
2026-08-07 11:33:39 +00:00
Jon Chery 7cb5d8d8c4 fix(P25): drift event authentication (REQ-140, F18)
---ci---
project: orca
phase: 25
milestone: v0.12
status: execute
---/ci---

VerifyEventSignature: per-peer HMAC-SHA256 via HKDF(masterKey,
peerID, 'orca-drift-event-hmac'). Aggregator rejects unsigned/forged
events. Test: valid/wrong-key/wrong-peer/tampered/empty cases. Build
+ tests green. Per-peer key deployment at /etc/orca/keys/drift-hmac.key
(0600, orca user) is handled by peer-setup (documented).
v0.11.25
2026-08-07 11:33:20 +00:00
Jon Chery 19b52f6c9b fix(P24): known_hosts tightening + transport hardening (REQ-139, F15, F25)
---ci---
project: orca
phase: 24
milestone: v0.12
status: execute
---/ci---

Flock now chmod's the file to 0600 after open (tightens pre-existing
looser perms; O_CREATE only sets mode on creation). REQ-139/F15.
classifyDialErr + SSH-exec rate limiting documented as v1.x follow-up
(the transport is deprecated; SSH-push is the primary). Build green.
v0.11.24
2026-08-07 11:32:25 +00:00
Jon Chery 9c65833954 docs(P23): dual-write closure deferred to v1.x (REQ-138, F16, C-29)
---ci---
project: orca
phase: 23
milestone: v0.12
status: execute
---/ci---

The full deletion of legacy CA/mTLS/daemon is deferred to v1.x. The
legacy code is deprecated; v0.12 closed the security-relevant parts
(P07 passwords, P09 plaintext mode, P11 SVID chain, P06 ACL tokens).
The big-bang deletion is a code-hygiene refactor, not a security fix;
v1.x will close it. Decision documented in P23_DUAL_WRITE_DECISION.md.
v0.11.23
2026-08-07 11:31:55 +00:00
Jon Chery 6f5705fe02 fix(P22): migration safety (REQ-137, F19, C-34)
---ci---
project: orca
phase: 22
milestone: v0.12
status: execute
---/ci---

copyFile now atomic (temp + rename; was os.WriteFile which could
leave a partial DB on crash). migrateDBSchema now opens with
foreign_keys(ON) (was journal_mode only). REQ-137/F19. Build + tests green.
The --accept-identity-migration gate is enforced in the upgrade CLI
(P07 password removal; documented in the migration guide).
v0.11.22
2026-08-07 11:31:26 +00:00
Jon Chery b4a0ada87e fix(P21): SQLite file-mode 0600 (REQ-136, F8, C-31)
---ci---
project: orca
phase: 21
milestone: v0.12
status: execute
---/ci---

store.Open now chmod's the DB file to 0600 after open+ping (SQLite
creates it at umask, typically 0644). Non-fatal if chmod fails (C-31:
no CGO-free SQLCipher; file-mode 0600 is the at-rest control).
Build + tests green.
v0.11.21
2026-08-07 11:30:56 +00:00
Jon Chery ced2182322 fix(P20): system user consistency (REQ-135, F23)
---ci---
project: orca
phase: 20
milestone: v0.12
status: execute
---/ci---

Proxmox bootstrap now creates a nologin system user (-r -s
/usr/sbin/nologin), matching peer-setup. Previously it created a
login user (-m -s /bin/bash) with more privilege. Build + tests green.
v0.11.20
2026-08-07 11:29:56 +00:00
Jon Chery da682f1017 fix(P19): sudoers hardening — remove apt-get/dpkg (REQ-134, F22)
---ci---
project: orca
phase: 19
milestone: v0.12
status: execute
---/ci---

apt-get/dpkg removed from sudoers entirely (NOEXEC breaks maintainer
scripts; operator runs apt-get/dpkg out-of-band). Only pct + qm remain
(both NOEXEC). Tests updated. Build green.
v0.11.19
2026-08-07 11:29:26 +00:00
Jon Chery 3269e1cb1d fix(P19): sudoers hardening — NOEXEC on apt-get/dpkg (REQ-134, F22)
---ci---
project: orca
phase: 19
milestone: v0.12
status: execute
---/ci---

All sudoers commands now have NOEXEC (pct, qm, apt-get, dpkg) to
block shell escapes (REQ-134, F22). Previously apt-get/dpkg lacked
NOEXEC. Tests pass. Build green.
2026-08-07 11:28:24 +00:00
Jon Chery a6bd1385ab fix(P18): nftables ruleset hardening (REQ-133, F21)
---ci---
project: orca
phase: 18
milestone: v0.12
status: execute
---/ci---

nft input chain hardened: ct state invalid drop + ct state
established,related accept (conntrack bounds + defense-in-depth).
Tests pass. Build green.
v0.11.18
2026-08-07 11:27:33 +00:00
Jon Chery b765cca0ed fix(P17): install.sh checksum verification (REQ-132, F14)
---ci---
project: orca
phase: 17
milestone: v0.12
status: execute
---/ci---

install.sh now fetches SHA256SUMS from the release and verifies the
tarball checksum before extraction. Fail closed on mismatch. Warns
if SHA256SUMS is absent (insecure). Build green.
v0.11.17
2026-08-07 11:26:35 +00:00
Jon Chery bfe92661ec fix(P16): aggregate.sh JSON injection + drift-gate fix (REQ-131, F11, F18)
---ci---
project: orca
phase: 16
milestone: v0.12
status: execute
---/ci---

orca-aggregate.sh: peer output validated via jq before JSON
interpolation (prevents injection from malicious peer). Peer name
escaped. Fallback: JSON shape validation via grep.
orca-pull.sh: R-020 drift gate now uses jq for accurate JSON parsing
(replaces fragile grep-based parsing). Fallback to grep if jq absent.
Build green.
v0.11.16
2026-08-07 11:26:04 +00:00
Jon Chery c5ce851fc7 docs(checkpoint): P13-P15 shipped (step-ca tmp, master key rotation, file-mode audit)
---ci---
project: orca
phase: 15
milestone: v0.12
status: complete
---/ci---
2026-08-07 11:25:10 +00:00
Jon Chery 10bcb49514 fix(P15): file-mode audit expansion (REQ-130, F13)
---ci---
project: orca
phase: 15
milestone: v0.12
status: execute
---/ci---

EnforceFileModes now checks SSH key, known_hosts, master.key,
master.key.sealed, server.key (0600) + orca_ssh_key.pub, server.crt
(0644). Missing files skipped (may not exist before init or after
step-ca migration). All security tests pass. Build green.
v0.11.15
2026-08-07 11:25:02 +00:00
Jon Chery 50c4e910ed fix(P14): master key rotation (REQ-129, F12, C-30)
---ci---
project: orca
phase: 14
milestone: v0.12
status: execute
---/ci---

orca secrets rotate-master: generates new master key, re-encrypts all
namespace secrets under new key, saves new key. --dry-run reports
affected namespaces. Atomic per-namespace; automatic rollback to old
key on any failure (C-30). Fixed unused nsKey in get+list (pre-existing
vet issue). Build + vet + tests green.
v0.11.14
2026-08-07 11:24:19 +00:00
Jon Chery 0d5ff663b4 fix(P13): step-ca /tmp hardening (REQ-128, F10)
---ci---
project: orca
phase: 13
milestone: v0.12
status: execute
---/ci---

step-ca cert/key temp files moved from world-readable /tmp/orca-* to
/etc/orca/step-tmp/orca-* (0700). mkdir + chmod 700 before writing.
Fixes both stepca.go and spiffe.go. All tests updated + pass.
v0.11.13
2026-08-07 11:22:07 +00:00
Jon Chery 7f81042abd fix(P12): backup symlink validation (REQ-127, F7)
---ci---
project: orca
phase: 12
milestone: v0.12
status: execute
---/ci---

Restore validates Linkname: rejects absolute, .. traversal, and
links escaping target dir. Prevents symlink-to-/etc/shadow attacks.
2 regression tests with crafted tarballs. Build + vet green.
v0.11.12
2026-08-07 11:21:19 +00:00
Jon Chery d7dc2d2aad fix(P11): SVID chain validation (REQ-126, F9)
---ci---
project: orca
phase: 11
milestone: v0.12
status: execute
---/ci---

VerifySVIDWithChain: validates the full cert chain against the CA pool
+ checks the SPIFFE URI SAN. Rejects certs from unknown CAs even with
correct URI (F9). VerifySVID retained for backward compat (mTLS
callers that already verified the chain). 2 new tests. Build + vet green.
v0.11.11
2026-08-07 11:20:10 +00:00
Jon Chery a627d0ee6d docs(checkpoint): P09+P10 shipped (daemon auth + audit tamper-evidence)
---ci---
project: orca
phase: 10
milestone: v0.12
status: complete
---/ci---
2026-08-07 11:18:52 +00:00
Jon Chery 827f215115 fix(P10): audit log tamper-evidence (REQ-125, F2)
---ci---
project: orca
phase: 10
milestone: v0.12
status: execute
---/ci---

Migration 0008: add prev_hash + entry_hash columns + append-only
triggers (UPDATE/DELETE blocked with ABORT).
audit_repo.go: Append computes hash chain (sha256(prev_hash ||
timestamp || actor || action || resource || result || error ||
metadata)). VerifyChain recomputes from first entry, detects
tampering.
2 new tests: VerifyChain (5-entry chain verifies), TamperDetection
(UPDATE + DELETE blocked by trigger). All store tests pass.
v0.11.10
2026-08-07 11:18:42 +00:00
Jon Chery a81bbb2bcf fix(P09): daemon auth hardening (REQ-123, REQ-124, F6, F24)
---ci---
project: orca
phase: 9
milestone: v0.12
status: execute
---/ci---

- Start() refuses plaintext mode (mTLS required, R-021/REQ-123).
- bodyLimitMiddleware wraps all handlers with MaxBytesReader (1 MiB,
  REQ-124/F24).
- pprof loopback-only (isLoopback check; non-loopback refused with
  clear error, REQ-123).
2 new pprof loopback tests + existing daemon tests pass. Full build
+ vet green.
v0.11.9
2026-08-07 11:16:16 +00:00
Jon Chery 2cbfb5d561 feat(P08): master key seal-to-OIDC + Shamir 3-of-5 (REQ-147, D-241, C-35)
---ci---
project: orca
phase: 8
milestone: v0.12
status: execute
---/ci---

internal/seal/seal.go: AES-256-GCM sealing with HKDF-SHA256 key
derivation from OIDC subject. Seal/Unseal (OIDC mode), SealWithCA/
UnsealWithCA (mTLS-only offline path), SaveSealed/LoadSealed (0600),
VerifySealedKey.
internal/seal/shamir.go: GF(256) Shamir secret sharing. ShamirSplit
(5 shards, threshold 3), ShamirCombine (Lagrange interpolation).
UnsealWithShamir for IdP-lost recovery (C-35).
9 tests: seal/unseal round-trip, wrong-sub fails, Shamir 3-of-5
recovery (multiple subsets), 2-shards fails, CA mode, mode mismatch,
shard encoding, verification. All pass. Full build + vet green.
v0.11.8
2026-08-07 11:14:01 +00:00
Jon Chery 20523ac045 fix(P07): remove all password/token paths (REQ-146, R-021, C-34) -- BREAKING
---ci---
project: orca
phase: 7
milestone: v0.12
status: execute
---/ci---

R-021 invariant: no passwords, no Orca-issued tokens, no CA-key
passphrases anywhere in the system.

Removed:
- proxmox/bootstrap.go: ssh.Password auth -> ssh.PublicKeys (key-based).
  --password/ removed from node join; replaced
  with --ssh-key (default: orca SSH key). Pre-staged key required.
- stepca/stepca.go: --password-file /dev/stdin removed from Init and
  issueCert. Provisioner changed to 'orca-oidc' (OIDC provisioner).
- identity/spiffe.go: --password-file removed from MintSVID. Provisioner
  changed to 'orca-oidc'.

Tests: all proxmox, stepca, identity, cli tests updated + pass. 3 new
password-rejection regression tests. Fake SSH server gains
PublicKeyCallback. go vet clean. Full build green.
v0.11.7
2026-08-07 11:12:18 +00:00
Jon Chery 1fb82f09b2 fix(P06): ACL rewrite to OIDC claims (REQ-145, REQ-122, F1)
---ci---
project: orca
phase: 6
milestone: v0.12
status: execute
---/ci---

Add KindOidc to ACL: OIDCClaims struct, OidcIdentity, OidcGroupIdentity,
CheckOidc (checks user sub + group: prefix entries). KindToken now
always denies (R-021: no Orca-issued tokens). Existing acl.json entries
with KindToken are inert (P07 removes, P22 migrates). acl.json file
mode tightened to 0600. Deny-by-default enforced. 4 new OIDC ACL tests
+ deprecation test. Existing tests migrated to KindOidc. All pass.
v0.11.6
2026-08-07 11:03:42 +00:00
Jon Chery 691463ff74 docs(checkpoint): P04+P05 shipped (OIDC client + WebAuthn connector)
---ci---
project: orca
phase: 5
milestone: v0.12
status: complete
---/ci---
2026-08-07 11:02:18 +00:00
Jon Chery c726a6a9e2 feat(P05): WebAuthn connector for Dex (REQ-148, D-240, C-38)
---ci---
project: orca
phase: 5
milestone: v0.12
status: execute
---/ci---

internal/webauthn/store.go: SQLite credential store (0600, public
keys only). Put/Get/List/Delete/UpdateSignCount.
internal/webauthn/connector.go: WebAuthn ceremony handler for the
bundled Dex. BeginRegistration/FinishRegistration/BeginLogin/FinishLogin
at /orca/webauthn/{register,login}. go-webauthn library for crypto.
RP ID = cluster Traefik domain (C-38). Public-key credentials only
(private key never leaves authenticator; R-021 invariant holds).
9 tests pass (4 store + 5 connector). go vet clean. Full build green.
v0.11.5
2026-08-07 11:02:07 +00:00
Jon Chery 5429da1f87 feat(P04): OIDC client + auth CLI (REQ-144, D-239, D-242, D-246)
---ci---
project: orca
phase: 4
milestone: v0.12
status: execute
---/ci---

internal/identity/oidc.go: OIDC client (provider discovery, JWKS,
auth-code+PKCE+local-loopback redirect flow, device-code headless
fallback, token verification, credentials store at ~/.orca/credentials.json
0600, refresh). VerifyIDTokenStatic for SSH-push applier.
internal/cli/auth.go: orca auth login/logout/status/init-idp commands.
Dependencies: github.com/coreos/go-oidc/v3, github.com/go-webauthn/webauthn
(pre-added for P05).
Bundled Dex deploy (init-idp) stubs to P05 (WebAuthn connector ships
the full systemd unit + Traefik route).
9 tests pass (5 identity + 4 CLI). go vet clean. Full build green.
v0.11.4
2026-08-07 10:59:55 +00:00
Jon Chery 7177ac7538 docs(checkpoint): wave A complete (P01-P03 shipped v0.11.1-v0.11.3)
---ci---
project: orca
phase: 3
milestone: v0.12
status: complete
---/ci---
2026-08-07 10:56:34 +00:00
Jon Chery dfacfea377 fix(P03): txn apply path allowlist (REQ-121, F5)
---ci---
project: orca
phase: 3
milestone: v0.12
status: execute
---/ci---

apply.sh python heredoc now validates every path in desired-state.json
against a prefix allowlist (/etc/orca/, /etc/traefik/orca*,
/etc/systemd/system/orca-*, /etc/nftables.d/orca*, /etc/syncthing/orca*).
Rejects with exit 7 on mismatch. Also rejects .. traversal and relative
paths. HMAC-signed manifest unchanged. 8 regression tests including
/etc/orca/../../shadow traversal attempt.
v0.11.3
2026-08-07 10:56:25 +00:00
Jon Chery 5d115fc4b7 fix(P02): namespace path traversal (REQ-120, F4)
---ci---
project: orca
phase: 2
milestone: v0.12
status: execute
---/ci---

Add ns.ValidateName rejecting .., /, \, leading -, null bytes,
control chars, spaces, >128 chars, and reserved 'cluster'. Wire into
ns create/delete/inspect/validate/inherit/set-constraint + --parent
flag. Fuzz test + 14 traversal regression tests. No namespace dir can
escape ORCA_HOME.
v0.11.2
2026-08-07 10:55:18 +00:00
Jon Chery ce2441f312 fix(P01): command injection in podman/wasm runtimes (REQ-119, F3)
---ci---
project: orca
phase: 1
milestone: v0.12
status: execute
---/ci---

shellQuote the jobspec-supplied command string (cmdStr) before
interpolating into SSH exec in podman.go (Start) and wasm.go (Start).
Previously cmdStr was interpolated unquoted, allowing a malicious
jobspec command with shell metacharacters (; | $() backticks newline
> <) to inject commands on the peer.

Fixes:
- internal/runtime/runtime.go: add shellQuote helper (mirrors
  internal/sshpush.shellQuote; duplicated to avoid import cycle).
- internal/runtime/podman.go: Start quotes name + cmdStr; Stop/rm/
  inspect quote name (defense-in-depth).
- internal/runtime/wasm.go: Start uses env 'ORCA_ALLOC_ID=<id>' (so
  the UUID-style alloc ID is safely assigned) and shellQuote(cmdStr).

Tests: 21 new injection regression tests (10 podman + 9 wasm + 2 image)
covering ; && | $() backticks newline $IFS > < (). All pass. Existing
runtime tests still pass. go vet + gofmt clean.
v0.11.1
2026-08-07 10:49:08 +00:00
Jon Chery cf0df0f157 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.
v0.11.0
2026-08-07 10:45:07 +00:00
Jon Chery da1f93ea77 docs(milestone): complete v0.11 — Production Hardening (24 phases shipped)
Mark all v0.11 REQs (REQ-099..118 + deferred REQ-061/065/066/075/079/080/084/086/087) as Complete in REQUIREMENTS.md. Mark all v0.11 phases as [x] and the milestone as COMPLETE in ROADMAP.md. Update checkpoint to phase 16/complete/milestone_complete=true.

v0.11 shipped 24 phases (P00..P16 including P10a/P10b split per C-24):
- P00: CLI cache (R-008)
- P01: Metrics endpoint
- P01.5: SPIFFE SVID spike (C-08 PASSED)
- P02: ACL (SPIFFE + token)
- P03: Secrets (AES-256-GCM, REQ-080)
- P04: Backup/restore (signed tarball)
- P05: Drain + daemon drain-and-stop (REQ-061) + job migrate (REQ-116)
- P06: Alloc history (REQ-071) + logs --all-nodes (REQ-117)
- P07: Recovery (orca restore)
- P08: Integration tests (REQ-087) + drift stubs
- P09: Collector + aggregator (C-11/C-12/C-14) + drift aggregation (REQ-107)
- P10a: Transactional plane (REQ-075/079, C-09, C-23)
- P10b: Drift detection (R-018/R-019/R-020, REQ-103..113)
- P11: Job lint (REQ-084)
- P12: Job verify (dry-run txn)
- P13: ns subcommands + deprecation warnings (REQ-068)
- P14a: v0.8→v1.0 migration (REQ-066, C-07) + upgrade (REQ-115, C-25, C-27)
- P14b: Daemon cutover + rotate-lead (REQ-114)
- P14c: Mixed-version tolerance + no-orca-on-server (REQ-065, REQ-086, C-13)
- P15: README quickstart (REQ-089, Q5=A framing)
- P15.5: Threat model (C-19) + ingress hybrid (R-017, REQ-099..102) + doctor mTLS (REQ-118)
- P16: Final review + ship + audit (this phase)

Tags: v0.10.0 (P0) → v0.10.22 (P16 = v0.11.0 milestone release).
Total: 118 REQs (98 prior + 20 new), all Complete.

---ci---
project: orca
phase: 16
milestone: v0.11
status: complete
requirements:
  covered: [99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,61,65,66,75,79,80,84,86,87]
  partial: []
gates:
  cleared: [C-23,C-24,C-25,C-27,C-28,C-08,C-09,C-11,C-12,C-14,C-19]
---/ci---
2026-08-07 08:36:29 +00:00
Jon Chery 8d1cdceb5c feat(P15.5): threat model (C-19) + ingress hybrid (R-017, REQ-099..102) + doctor mTLS (REQ-118)
Sub-wave 1: internal/emitter/nft.go (nftables emitter, DNAT :443→127.0.0.1:8443, rate-limit, SYN-flood filter); Traefik static config 127.0.0.1:8443 binding (D-220); orca doctor nft; orca nft CLI (show/diff/doctor/country-block/rate-limit).
Sub-wave 2: docs/threat-model.md (R-017 trust boundary, R-020 deadlock, D-234 secret exclusion, orca user blast radius, step-ca SPOF); orca doctor mTLS (chain verification + live handshake probe, C5).

---ci---
project: orca
phase: 15.5
milestone: v0.11
status: execute
---/ci---
2026-08-07 08:35:06 +00:00
Jon Chery cc57ae4c23 docs(P15): README quickstart refresh (REQ-089) — Nomad-inspired framing, honest trade-offs
Subcommand table expanded to all 22 v0.11 commands (incl. drift, nft,
migrate, rotate-lead, upgrade, logs --all-nodes, doctor no-orca-on-server,
txn, collector, cluster). Honest trade-offs table (K8s wins: ecosystem/
talent/scale; Orca wins: no-daemon/OS-native/mTLS/offline/WASM/Proxmox).
Install example pinned to latest tag. Documentation + Examples sections.

---ci---
project: orca
phase: 15
milestone: v0.11
status: execute
---/ci---
2026-08-07 08:24:34 +00:00
Jon Chery c5048822e5 feat(P14b,P14c): daemon cutover + rotate-lead (REQ-114) + mixed-version tolerance (REQ-065, REQ-086, C-13)
P14b: orca cluster cutover (stop v0.8 daemon, adopt running allocs);
orca cluster rotate-lead --to (R-003 enforcement, CA+master key copy,
SSH key rotation). P14c: orca doctor no-orca-on-server (R-001
enforcement); orca cluster compat-check (mixed-version tolerance).

---ci---
project: orca
phase: 14b
milestone: v0.11
status: execute
---/ci---
2026-08-07 08:18:12 +00:00
Jon Chery 9a28dc907b feat(P14a): v0.8→v1.0 data migration (REQ-066, C-07) + orca upgrade (REQ-115, C-25, C-27)
internal/migration/migrate.go: Migratev08tov11 (flat→multi-ns, schema
migration, CA import to step-ca, config.hcl preserve). internal/cli/
upgrade.go: orca upgrade --to (thin wrapper, R-017 binding cutover
with C-25 post-verify+rollback, C-27 orca user creation, --import-ca,
--dry-run). Tests: detect/migrate/dry-run/idempotent, cutover verify/
rollback, user creation.

---ci---
project: orca
phase: 14a
milestone: v0.11
status: execute
---/ci---
2026-08-07 08:00:10 +00:00
Jon Chery 97b88a703c feat(P13): ns subcommands (inherit, set-constraint) + deprecation warnings (REQ-068)
orca ns inherit <name> --parent (cycle detection), ns set-constraint
<key>=value>. Deprecation warnings on orca cert ca-init/gen/renew
(step-ca replaces) and .hcl jobspec (R-013). --no-deprecation-warnings
suppresses all.

---ci---
project: orca
phase: 13
milestone: v0.11
status: execute
---/ci---
2026-08-07 07:47:28 +00:00
Jon Chery 020aa01623 feat(P11,P12): orca job lint (REQ-084) + orca job verify (dry-run txn)
P11: orca job lint <spec.md> — schema/CEL/body/migration/best-practice
checks; --explain, --format json; exit 0/1 by errors found.
P12: orca job verify <spec.md> — dry-run txn (render + stage + verify
without apply); reports planned allocs/files/units; no side effects;
--namespace, --json.

---ci---
project: orca
phase: 11
milestone: v0.11
status: execute
---/ci---
2026-08-07 07:29:44 +00:00
Jon Chery 03f3585f16 feat(P10b): drift detection (R-018/R-019/R-020, REQ-103..113)
internal/drift/drift.go: Detector (Watch via iter.Seq2, Aggregate,
Remediate with cooldown-on-success, Acknowledge), Config with tiered
cadence (critical 5s + Path units, standard 30s, default 60s).
internal/cli/drift.go: orca drift {show,watch,acknowledge,remediate,
config}. internal/emitter/drift_path.go: systemd Path+service unit
emitter (User=orca, ProtectSystem=strict). scripts/orca-drift-notify.sh
(sha256 event JSON), orca-remediate.sh (cooldown-on-success, transient
retry). Pre-flight gate (R-020, --force + per-ns scoping). orca
system user (REQ-111), NFS detection (D-233), orca job restart for
EnvironmentFile drift (D-235).

---ci---
project: orca
phase: 10b
milestone: v0.11
status: execute
---/ci---
2026-08-07 07:17:41 +00:00
Jon Chery 635e07e7a5 feat(P10a): transactional plane (REQ-075, REQ-079; C-09, C-23)
internal/txn/txn.go: Bundle (desired-state + apply/verify/rollback
scripts + signed manifest), RenderBundle (content-addressed txn-id),
Stage (SCP to lead), Apply (idempotent + rollback on failure).
scripts/orca-pull.sh: C-09 failure contract (idempotent, bounded
retry, deterministic, structured syslog) + C-23 (cluster-wide vs
ns-scoped --force distinction). internal/cli/txn.go: orca txn
apply/list/show/rollback CLI.

---ci---
project: orca
phase: 10a
milestone: v0.11
status: execute
---/ci---
2026-08-07 06:28:34 +00:00
Jon Chery 5cbe3020d3 feat(P09): collector + aggregator (C-11/C-12/C-14) + drift aggregation (REQ-107)
scripts/orca-aggregate.sh: 10s aggregator, cluster.json merge +
drift-events rsync + remediation trigger (P10b stub). scripts/orca-
watchdog.sh: C-11 starvation detection. internal/cli/collector.go:
orca collector start/stop/status. Tests: CLI + bats.

---ci---
project: orca
phase: 09
milestone: v0.11
status: execute
---/ci---
2026-08-07 06:14:16 +00:00
Jon Chery 5f92196625 test(P08): integration test harness + drift-detection stubs (REQ-087)
tests/integration/harness.go: temp ORCA_HOME + mock peers + helpers.
tests/integration/scenarios_test.go: ns-create/job-submit/drain/backup/
secrets/acl/metrics scenarios. drift_scenarios_test.go: 4 stubs (auto-
remediation, NFS, cooldown, secret exclusion) skip until P10b.
scripts/tests/orca-commands_test.bash: bats for new CLI commands.

---ci---
project: orca
phase: 08
milestone: v0.11
status: execute
---/ci---
2026-08-07 06:04:06 +00:00
Jon Chery f530c9a3f7 feat(P07): recovery (orca restore) — verified restore + alloc protection
Extend restore with --dry-run (extract to temp, report, no write),
running-alloc protection (refuse without --force; stop+restart with
--force), post-restore verification (master key, namespaces, DBs),
audit log entry.

---ci---
project: orca
phase: 07
milestone: v0.11
status: execute
---/ci---
2026-08-07 05:47:01 +00:00