# Security Runbook (v0.13)

This runbook documents the operational security procedures for orca's
zero-trust identity model (R-021): 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 v0.12 milestone shipped these capabilities; the v0.13
milestone wired them operationally (R-023).

## Master Key Seal/Unseal (REQ-147, P05)

The cluster master key (`ClusterDir()/master.key`, mode 0600) encrypts
all namespace `.env.secrets` via per-namespace HKDF-SHA256 sub-keys
(AES-256-GCM). The master key can be **sealed** (encrypted at rest) and
**unsealed** (unwrapped into memory for use).

### Seal

```bash
orca cluster seal
```

Encrypts the raw master key with a key derived from either:
- the OIDC ID token subject (if `orca auth login` has been run), or
- the cluster CA fingerprint (mTLS-only offline path, D-241).

The sealed blob is written to `ClusterDir()/master.key.sealed` (0600).
**Five Shamir shards (3-of-5 recovery)** are printed to stdout — store
them offline. The raw master key is then deleted from disk so the
cluster is sealed at rest.

### Unseal

```bash
orca cluster unseal
```

Reads the sealed blob and unwraps the master key using the OIDC ID
token subject or the cluster CA fingerprint. The unwrapped key is
written back to `ClusterDir()/master.key` (0600) and zeroed from
memory on process exit.

### Recovery (IdP lost)

```bash
orca cluster unseal --recovery
```

If the IdP is permanently lost, the operator is prompted for 3 of the
5 Shamir shards printed at seal time. With quorum, the master key is
reconstructed and written back to disk. If quorum is unavailable, the
cluster is unrecoverable by design (C-35: no backdoor).

## Master Key Rotation (REQ-129, C-30)

```bash
orca secrets rotate-master [--dry-run]
```

Generates a new master key, re-encrypts every namespace's
`.env.secrets` under the new key, and re-seals the master key to OIDC.
With `--dry-run`, reports affected namespaces without writing.

- **Atomic per-namespace**: each namespace is re-encrypted independently.
- **Automatic rollback**: on any namespace failure, the old sealed key
  is restored (C-30).
- **No passphrase** (R-021): the master key is sealed to OIDC, not to a
  human-typed passphrase.

## File-Mode Audit (REQ-033, REQ-130, F13)

```bash
orca doctor modes
```

Verifies file modes on security-sensitive files across `ORCA_HOME`:
- private keys / secrets: `0600`
- certs / public keys: `0644`

Exits 0 if all files have correct modes; exits 1 if any violation is
found. Missing files are not counted as violations.

Checks: SSH key, master key (sealed blob), server cert/key,
known_hosts, `acl.json`, OIDC client secret.

## Audit Log Tamper-Evidence (REQ-125, F2)

```bash
orca doctor audit
```

Verifies the audit log hash chain. Opens the orca SQLite DB, recomputes
the hash chain from the first audit entry, and reports the chain head
hash. If any entry's `entry_hash` or `prev_hash` link does not match the
recomputed value, the chain has been tampered with and the command
exits non-zero.

The audit log is append-only (SQLite trigger blocks
UPDATE/DELETE). Each entry's `actor` field carries the OIDC `sub` or
SPIFFE SVID. Run this after any suspected intrusion or as part of a
regular audit cadence.

## Sudoers Audit (REQ-134, F22)

```bash
orca doctor proxmox
```

Audits the `/etc/sudoers.d/orca` file against the expected allowlist:
- `pct` + `qm` with NOEXEC
- `apt-get` / `dpkg` excluded (or NOEXEC'd)
- `pvesh` EXCLUDED (AD-020: pvesh can bypass NOEXEC via the API execute
  endpoint)

## nft Audit (REQ-133, F21)

```bash
orca doctor nft
```

Audits the live nftables ingress ruleset against the on-disk
`/etc/nftables.d/orca.nft` hash (recorded at the latest applied txn).
Reports drift if the live ruleset does not match. Also verifies:
- table exists
- DNAT `:443 → 127.0.0.1:8443` and `:80 → 127.0.0.1:8080` present
- rate-limit meter present
- `/etc/nftables.d/orca.nft` parses

## Incident Response

1. **Revoke the compromised identity** (OIDC user/group or SPIFFE SVID).
2. **Rotate the master key** (`orca secrets rotate-master`).
3. **Review the audit log** (`orca doctor audit` verifies the hash
   chain; `orca audit list` shows entries).
4. **Check file modes** (`orca doctor modes` detects permission drift).
5. If the master key is compromised, **all historical secrets are
   compromised** (no forward secrecy — documented residual risk).
6. **Re-seal** the master key after rotation (`orca cluster seal`).

## OIDC Provider Health (P06)

```bash
orca doctor oidc
```

Checks the bundled Dex OIDC provider health. Verifies the Dex systemd
unit is running and the `/.well-known/openid-configuration` endpoint
responds. Run after `orca auth init-idp` or after a Dex config change.
