From 50f3ea0545179fb4e5b64924f6450ad9a333b00e Mon Sep 17 00:00:00 2001 From: ndycode Date: Tue, 3 Mar 2026 22:16:25 +0800 Subject: [PATCH 1/7] feat: implement enterprise hardening baseline Add enterprise-grade hardening across runtime, CLI, storage, CI, and docs.\n\n- Add cross-process file locking for settings/quota persistence\n- Add at-rest secret encryption with rotation command and idempotency support\n- Add RBAC/ABAC-style command authorization, JSON redaction, and retention policies\n- Add background retry + dead-letter queue for async persistence failures\n- Add list JSON pagination standard and schemaVersion contract updates\n- Add CI security gates: secret scan, supply-chain/SCA/license checks, SBOM, required checks policy\n- Add operations and incident response runbooks\n- Add/extend tests for new security/reliability primitives and CLI behaviors\n\nValidated with:\n- npm run typecheck\n- npm run lint\n- npm run build && npm test\n- npm run coverage\n- npm run audit:ci\n- npm run license:check\n- npm run clean:repo:check Co-authored-by: Codex --- .github/settings.yml | 23 ++ .github/workflows/ci.yml | 69 +++- .github/workflows/secret-scan.yml | 28 ++ .github/workflows/supply-chain.yml | 78 +++++ README.md | 1 + docs/README.md | 1 + docs/configuration.md | 6 + docs/development/CONFIG_FIELDS.md | 10 + docs/development/TESTING.md | 9 +- docs/index.md | 3 +- docs/privacy.md | 29 ++ docs/reference/commands.md | 7 +- docs/reference/error-contracts.md | 7 + docs/reference/public-api.md | 18 + docs/reference/settings.md | 8 +- docs/reference/storage-paths.md | 1 + docs/runbooks/README.md | 12 + docs/runbooks/incident-response.md | 97 ++++++ docs/runbooks/operations.md | 85 +++++ index.ts | 82 ++++- lib/accounts.ts | 13 +- lib/authorization.ts | 42 +++ lib/background-jobs.ts | 115 ++++++ lib/codex-manager.ts | 537 +++++++++++++++++++++++++++-- lib/data-redaction.ts | 50 +++ lib/data-retention.ts | 122 +++++++ lib/file-lock.ts | 181 ++++++++++ lib/idempotency.ts | 125 +++++++ lib/index.ts | 7 + lib/quota-cache.ts | 52 +-- lib/secrets-crypto.ts | 101 ++++++ lib/storage.ts | 140 +++++++- lib/unified-settings.ts | 94 +++-- package.json | 2 + scripts/license-policy-check.js | 65 ++++ test/authorization.test.ts | 60 ++++ test/background-jobs.test.ts | 89 +++++ test/codex-manager-cli.test.ts | 127 +++++++ test/data-redaction.test.ts | 34 ++ test/data-retention.test.ts | 79 +++++ test/file-lock.test.ts | 60 ++++ test/idempotency.test.ts | 51 +++ test/quota-cache.test.ts | 5 +- test/secrets-crypto.test.ts | 62 ++++ 44 files changed, 2673 insertions(+), 114 deletions(-) create mode 100644 .github/settings.yml create mode 100644 .github/workflows/secret-scan.yml create mode 100644 .github/workflows/supply-chain.yml create mode 100644 docs/runbooks/README.md create mode 100644 docs/runbooks/incident-response.md create mode 100644 docs/runbooks/operations.md create mode 100644 lib/authorization.ts create mode 100644 lib/background-jobs.ts create mode 100644 lib/data-redaction.ts create mode 100644 lib/data-retention.ts create mode 100644 lib/file-lock.ts create mode 100644 lib/idempotency.ts create mode 100644 lib/secrets-crypto.ts create mode 100644 scripts/license-policy-check.js create mode 100644 test/authorization.test.ts create mode 100644 test/background-jobs.test.ts create mode 100644 test/data-redaction.test.ts create mode 100644 test/data-retention.test.ts create mode 100644 test/file-lock.test.ts create mode 100644 test/idempotency.test.ts create mode 100644 test/secrets-crypto.test.ts diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 000000000..c3a0d1243 --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,23 @@ +branches: + - name: main + protection: + required_pull_request_reviews: + required_approving_review_count: 1 + require_code_owner_reviews: false + dismiss_stale_reviews: true + required_status_checks: + strict: true + checks: + - context: "CI / Test on Node.js 20.x" + - context: "CI / Test on Node.js 22.x" + - context: "CI / Coverage Gate" + - context: "CI / Lint" + - context: "CI / Codex Compatibility Smoke" + - context: "CI / Cross-Platform Smoke (windows-latest)" + - context: "CI / Cross-Platform Smoke (macos-latest)" + - context: "CodeQL / Analyze" + - context: "Secret Scan / Gitleaks" + - context: "Supply Chain / Dependency Review" + - context: "Supply Chain / SCA and License Gate" + enforce_admins: true + restrictions: null diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3c4f0b99..8679f4494 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,12 +6,17 @@ on: pull_request: branches: [main] +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: name: Test on Node.js ${{ matrix.node-version }} runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: [20.x, 22.x] @@ -23,7 +28,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: 'npm' + cache: npm - name: Install dependencies run: npm ci @@ -44,15 +49,34 @@ jobs: - name: Run type check run: npm run typecheck - - name: Run tests with coverage - run: npm run coverage - - name: Build run: npm run build + - name: Run tests + run: npm test + + coverage-gate: + name: Coverage Gate + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Run tests with coverage threshold gate + run: npm run coverage + lint: name: Lint - runs-on: ubuntu-latest steps: @@ -63,7 +87,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20.x - cache: 'npm' + cache: npm - name: Install dependencies run: npm ci @@ -83,10 +107,41 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20.x - cache: 'npm' + cache: npm - name: Install dependencies run: npm ci - name: Run Codex compatibility tests run: npm run test -- test/codex.test.ts test/host-codex-prompt.test.ts test/request-transformer.test.ts test/fetch-helpers.test.ts + + cross-platform-smoke: + name: Cross-Platform Smoke (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Run smoke typecheck + run: npm run typecheck + + - name: Build + run: npm run build + + - name: Run smoke tests + run: npm run test -- test/runtime-paths.test.ts test/codex-bin-wrapper.test.ts diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml new file mode 100644 index 000000000..c5967419f --- /dev/null +++ b/.github/workflows/secret-scan.yml @@ -0,0 +1,28 @@ +name: Secret Scan + +on: + pull_request: + branches: [main] + push: + branches: [main] + schedule: + - cron: "0 5 * * 1" + +jobs: + gitleaks: + name: Gitleaks + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run gitleaks scanner + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/supply-chain.yml b/.github/workflows/supply-chain.yml new file mode 100644 index 000000000..b2d94a48e --- /dev/null +++ b/.github/workflows/supply-chain.yml @@ -0,0 +1,78 @@ +name: Supply Chain + +on: + pull_request: + branches: [main] + push: + branches: [main] + schedule: + - cron: "0 4 * * 1" + +jobs: + dependency-review: + name: Dependency Review + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Dependency review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + fail-on-scopes: runtime + deny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0 + + sca-and-license: + name: SCA and License Gate + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Run vulnerability policy gate + run: npm run audit:ci + + - name: Run license policy gate + run: npm run license:check + + sbom: + name: Generate SBOM + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Generate CycloneDX SBOM + run: npx --yes @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json --omit dev + + - name: Upload SBOM artifact + uses: actions/upload-artifact@v4 + with: + name: sbom-cyclonedx + path: sbom.cdx.json diff --git a/README.md b/README.md index e254c6a65..a3685af48 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ codex auth doctor --fix | `codex auth fix --dry-run` | Preview safe repairs | | `codex auth fix --live --model gpt-5-codex` | Run repairs with live probe model | | `codex auth doctor --fix` | Diagnose and apply safe fixes | +| `codex auth rotate-secrets --json` | Re-encrypt stored secrets and return rotation summary | --- diff --git a/docs/README.md b/docs/README.md index 2accdd99f..2cb64b5b4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -59,6 +59,7 @@ Canonical documentation map for `codex-multi-auth`. | [development/REPOSITORY_SCOPE.md](development/REPOSITORY_SCOPE.md) | Ownership map by repository path | | [development/TESTING.md](development/TESTING.md) | Validation gates and test matrix | | [development/TUI_PARITY_CHECKLIST.md](development/TUI_PARITY_CHECKLIST.md) | Dashboard UX parity checklist | +| [runbooks/README.md](runbooks/README.md) | Operations and incident response playbooks | | [benchmarks/code-edit-format-benchmark.md](benchmarks/code-edit-format-benchmark.md) | Benchmark methodology and outputs | --- diff --git a/docs/configuration.md b/docs/configuration.md index 172296c74..632abf0f7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -68,6 +68,9 @@ These are safe for most operators and frequently used in day-to-day workflows. | `CODEX_TUI_GLYPHS=ascii|unicode|auto` | Glyph mode selection | | `CODEX_AUTH_FETCH_TIMEOUT_MS=` | HTTP request timeout override | | `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS=` | Stream stall timeout override | +| `CODEX_AUTH_ENCRYPTION_KEY=` | Enable at-rest encryption for stored account secrets | +| `CODEX_AUTH_PREVIOUS_ENCRYPTION_KEY=` | Fallback key for staged secret rotation | +| `CODEX_AUTH_ROLE=admin|operator|viewer` | CLI authorization role baseline | --- @@ -81,6 +84,9 @@ Use these only when debugging, controlled benchmarking, or maintainer workflows. - `CODEX_CLI_ACCOUNTS_PATH` - `CODEX_CLI_AUTH_PATH` - refresh lease tuning variables (`CODEX_AUTH_REFRESH_LEASE*`) +- `CODEX_AUTH_BREAK_GLASS` +- `CODEX_AUTH_REDACT_JSON_OUTPUT` +- retention tuning variables (`CODEX_AUTH_RETENTION_*`) Full inventory: [development/CONFIG_FIELDS.md](development/CONFIG_FIELDS.md) diff --git a/docs/development/CONFIG_FIELDS.md b/docs/development/CONFIG_FIELDS.md index 9a3ee4cf3..190c79d48 100644 --- a/docs/development/CONFIG_FIELDS.md +++ b/docs/development/CONFIG_FIELDS.md @@ -195,6 +195,16 @@ Used only for host plugin mode through the host runtime config file. | `CODEX_TUI_GLYPHS` | TUI glyph mode | | `CODEX_AUTH_FETCH_TIMEOUT_MS` | Request timeout override | | `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` | Stream stall timeout override | +| `CODEX_AUTH_ENCRYPTION_KEY` | Primary key for at-rest secret encryption | +| `CODEX_AUTH_PREVIOUS_ENCRYPTION_KEY` | Previous key for staged secret rotation | +| `CODEX_AUTH_ROLE` | Authorization role baseline (`admin`, `operator`, `viewer`) | +| `CODEX_AUTH_BREAK_GLASS` | Emergency authorization bypass toggle | +| `CODEX_AUTH_REDACT_JSON_OUTPUT` | Redact sensitive values in JSON command output | +| `CODEX_AUTH_RETENTION_LOG_DAYS` | Log retention window | +| `CODEX_AUTH_RETENTION_CACHE_DAYS` | Cache retention window | +| `CODEX_AUTH_RETENTION_FLAGGED_DAYS` | Flagged-account file retention window | +| `CODEX_AUTH_RETENTION_QUOTA_CACHE_DAYS` | Quota cache retention window | +| `CODEX_AUTH_RETENTION_DLQ_DAYS` | Dead-letter queue retention window | | `CODEX_MULTI_AUTH_SYNC_CODEX_CLI` | Toggle Codex CLI state sync | | `CODEX_MULTI_AUTH_REAL_CODEX_BIN` | Force official Codex binary path | | `CODEX_MULTI_AUTH_BYPASS` | Bypass local auth handling | diff --git a/docs/development/TESTING.md b/docs/development/TESTING.md index 9292b9065..5b2953485 100644 --- a/docs/development/TESTING.md +++ b/docs/development/TESTING.md @@ -24,6 +24,8 @@ npm run typecheck npm run lint npm test npm run build +npm run audit:ci +npm run license:check ``` Optional: @@ -42,8 +44,11 @@ npm run bench:edit-formats:smoke 1. `npm run typecheck` 2. `npm run lint` 3. `npm test` -4. `npm run build` -5. run docs command checks for newly documented command paths +4. `npm run coverage` +5. `npm run build` +6. `npm run audit:ci` +7. `npm run license:check` +8. run docs command checks for newly documented command paths * * * diff --git a/docs/index.md b/docs/index.md index 9a59b2d86..ecc3dbf0a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -46,4 +46,5 @@ Legacy package/path guidance is documented in [upgrade.md](upgrade.md) and [refe - Command flags and hotkeys: [reference/commands.md](reference/commands.md) - Settings and overrides: [reference/settings.md](reference/settings.md) - Storage path matrix: [reference/storage-paths.md](reference/storage-paths.md) -- Full docs portal: [README.md](README.md) \ No newline at end of file +- Operations runbooks: [runbooks/README.md](runbooks/README.md) +- Full docs portal: [README.md](README.md) diff --git a/docs/privacy.md b/docs/privacy.md index 4fa153420..8c19e3845 100644 --- a/docs/privacy.md +++ b/docs/privacy.md @@ -20,6 +20,7 @@ | Accounts | `~/.codex/multi-auth/openai-codex-accounts.json` | Primary saved account pool | | Flagged accounts | `~/.codex/multi-auth/openai-codex-flagged-accounts.json` | Accounts with hard auth failures | | Quota cache | `~/.codex/multi-auth/quota-cache.json` | Cached quota snapshots | +| Background DLQ | `~/.codex/multi-auth/background-job-dlq.jsonl` | Failed background jobs after retry exhaustion | | Logs | `~/.codex/multi-auth/logs/codex-plugin/` | Optional diagnostics | | Prompt/cache files | `~/.codex/multi-auth/cache/` | Cached prompt/template metadata | | Codex CLI state | `~/.codex/accounts.json`, `~/.codex/auth.json` | Official Codex CLI files | @@ -48,6 +49,34 @@ Current external destinations: Raw body logs may contain sensitive payload text. Treat logs as sensitive data and rotate/delete as needed. +`CODEX_AUTH_REDACT_JSON_OUTPUT=1` redacts sensitive values from JSON command output for automation logs. + +--- + +## Secret Encryption and Rotation + +- Account refresh/access tokens can be encrypted at rest when `CODEX_AUTH_ENCRYPTION_KEY` is set. +- Key rotation supports staged migration with `CODEX_AUTH_PREVIOUS_ENCRYPTION_KEY`. +- Rotation command: + +```bash +codex auth rotate-secrets --json +``` + +Store encryption keys in a secret manager or CI secret store, not in repository files. + +--- + +## Retention + +Startup retention cleanup removes expired local artifacts based on: + +- `CODEX_AUTH_RETENTION_LOG_DAYS` +- `CODEX_AUTH_RETENTION_CACHE_DAYS` +- `CODEX_AUTH_RETENTION_FLAGGED_DAYS` +- `CODEX_AUTH_RETENTION_QUOTA_CACHE_DAYS` +- `CODEX_AUTH_RETENTION_DLQ_DAYS` + --- ## Data Cleanup diff --git a/docs/reference/commands.md b/docs/reference/commands.md index 43c877fae..26742ebed 100644 --- a/docs/reference/commands.md +++ b/docs/reference/commands.md @@ -38,6 +38,7 @@ Compatibility aliases are supported: | `codex auth report` | Generate full health report | | `codex auth fix` | Apply safe account storage fixes | | `codex auth doctor` | Run diagnostics and optional repairs | +| `codex auth rotate-secrets` | Re-encrypt account secrets using current encryption key | --- @@ -45,13 +46,16 @@ Compatibility aliases are supported: | Flag | Applies to | Meaning | | --- | --- | --- | -| `--json` | verify-flagged, forecast, report, fix, doctor | Print machine-readable output | +| `--json` | verify-flagged, forecast, report, fix, doctor, rotate-secrets | Print machine-readable output | | `--live` | forecast, report, fix | Use live probe before decisions/output | | `--dry-run` | verify-flagged, fix, doctor | Preview without writing storage | | `--model ` | forecast, report, fix | Specify model for live probe paths | | `--out ` | report | Write report output to file | | `--fix` | doctor | Apply safe repairs | | `--no-restore` | verify-flagged | Verify only; do not restore healthy flagged accounts | +| `--page-size ` | list, status (`--json`) | Page size for JSON list output (1-200) | +| `--cursor ` | list, status (`--json`) | Cursor token for JSON list pagination | +| `--idempotency-key ` | rotate-secrets | Safe retry key for automation | --- @@ -108,6 +112,7 @@ Repair and recovery: codex auth fix --dry-run codex auth fix --live --model gpt-5-codex codex auth doctor --fix +codex auth rotate-secrets --json ``` --- diff --git a/docs/reference/error-contracts.md b/docs/reference/error-contracts.md index 62694d4f6..2196f1a7c 100644 --- a/docs/reference/error-contracts.md +++ b/docs/reference/error-contracts.md @@ -31,17 +31,24 @@ Examples: The following commands support `--json` and produce pretty-printed JSON objects: +- `codex auth list --json` - `codex auth forecast --json` - `codex auth report --json` - `codex auth fix --json` - `codex auth doctor --json` - `codex auth verify-flagged --json` +- `codex auth rotate-secrets --json` Compatibility guarantees: - Output is valid JSON. - `command` field identifies the command family. +- `schemaVersion` is required for machine-consumable contracts. - Documented top-level sections remain stable unless a migration note is provided. +- Optional redaction mode (`CODEX_AUTH_REDACT_JSON_OUTPUT=1`) masks sensitive fields without changing schema shape. +- Paginated list output uses `pagination.{cursor,nextCursor,hasMore,pageSize}`. + +For `rotate-secrets`, automation may provide `--idempotency-key ` to avoid duplicate side effects on retried runs. --- diff --git a/docs/reference/public-api.md b/docs/reference/public-api.md index 865189ff9..d916a379c 100644 --- a/docs/reference/public-api.md +++ b/docs/reference/public-api.md @@ -63,6 +63,24 @@ Positional signatures are preserved for backward compatibility. --- +## API Standards Baseline + +Where this repository exposes machine-readable command output or future HTTP endpoints, use these defaults: + +- Versioning: + - include `schemaVersion` in JSON command output. + - increment schema version only when contract shape changes. +- Idempotency: + - mutating automation flows should support caller-provided idempotency keys. + - repeated requests with the same idempotency key should not duplicate side effects. +- Pagination: + - list-style payloads should prefer cursor-based pagination (`nextCursor`, `hasMore`) over offset-only paging. + - response envelopes should include stable paging metadata even for empty result sets. + +This project currently applies the versioning baseline to JSON command outputs and documents idempotency/pagination standards for future API expansion. + +--- + ## Semver Guidance - Breaking Tier A change: `MAJOR` diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 1466374b9..1d6d46ea7 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -128,6 +128,9 @@ Common operator overrides: - `CODEX_TUI_GLYPHS` - `CODEX_AUTH_FETCH_TIMEOUT_MS` - `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` +- `CODEX_AUTH_ENCRYPTION_KEY` +- `CODEX_AUTH_PREVIOUS_ENCRYPTION_KEY` +- `CODEX_AUTH_ROLE` --- @@ -141,6 +144,9 @@ Maintainer/debug-focused overrides include: - `CODEX_CLI_ACCOUNTS_PATH` - `CODEX_CLI_AUTH_PATH` - refresh lease controls (`CODEX_AUTH_REFRESH_LEASE*`) +- `CODEX_AUTH_BREAK_GLASS` +- `CODEX_AUTH_REDACT_JSON_OUTPUT` +- retention controls (`CODEX_AUTH_RETENTION_*`) Full inventory: [../development/CONFIG_FIELDS.md](../development/CONFIG_FIELDS.md) @@ -175,4 +181,4 @@ codex auth forecast --live - [commands.md](commands.md) - [storage-paths.md](storage-paths.md) -- [../configuration.md](../configuration.md) \ No newline at end of file +- [../configuration.md](../configuration.md) diff --git a/docs/reference/storage-paths.md b/docs/reference/storage-paths.md index bae76b844..ca409f884 100644 --- a/docs/reference/storage-paths.md +++ b/docs/reference/storage-paths.md @@ -26,6 +26,7 @@ Override root: | Accounts WAL | `~/.codex/multi-auth/openai-codex-accounts.json.wal` | | Flagged accounts | `~/.codex/multi-auth/openai-codex-flagged-accounts.json` | | Quota cache | `~/.codex/multi-auth/quota-cache.json` | +| Background job DLQ | `~/.codex/multi-auth/background-job-dlq.jsonl` | | Logs | `~/.codex/multi-auth/logs/codex-plugin/` | | Cache | `~/.codex/multi-auth/cache/` | | Codex CLI accounts | `~/.codex/accounts.json` | diff --git a/docs/runbooks/README.md b/docs/runbooks/README.md new file mode 100644 index 000000000..7b7d5302c --- /dev/null +++ b/docs/runbooks/README.md @@ -0,0 +1,12 @@ +# Runbooks + +Operational runbooks for `codex-multi-auth`. + +## Runbook Index + +- [operations.md](operations.md): routine operational checks, release gates, and maintenance tasks. +- [incident-response.md](incident-response.md): severity model, containment flow, and post-incident process. + +## Scope + +These runbooks cover plugin-owned local state under `~/.codex/multi-auth` (or `CODEX_MULTI_AUTH_DIR`) and repository-level CI/security controls. diff --git a/docs/runbooks/incident-response.md b/docs/runbooks/incident-response.md new file mode 100644 index 000000000..2ce2d0c72 --- /dev/null +++ b/docs/runbooks/incident-response.md @@ -0,0 +1,97 @@ +# Incident Response Playbook + +Incident response workflow for `codex-multi-auth`. + +--- + +## Severity Levels + +- `SEV-1`: active secret exposure, auth bypass, or broad production outage. +- `SEV-2`: major functionality degraded, high failure rate, or persistent data corruption risk. +- `SEV-3`: contained bug with workaround, no ongoing security impact. + +--- + +## Response Timeline + +### 1. Detect and Declare (0-15 min) + +1. Open an internal incident channel. +2. Assign incident commander and communications lead. +3. Record: + - first detection timestamp + - affected command flows + - impacted storage paths/environment variables + +### 2. Contain (15-60 min) + +1. For credential exposure: + - rotate affected OAuth/session credentials + - set new `CODEX_AUTH_ENCRYPTION_KEY` + - run `codex auth rotate-secrets` +2. For unauthorized command execution: + - downgrade role to `CODEX_AUTH_ROLE=viewer` where possible + - reserve `CODEX_AUTH_BREAK_GLASS=1` for explicit emergency changes +3. For filesystem instability: + - pause mutation commands (`login`, `switch`, `fix`) + - inspect lock files and dead-letter entries + +### 3. Eradicate and Recover (within 24h) + +1. Patch root cause and merge behind required CI checks. +2. Validate: + - `npm run typecheck` + - `npm run lint` + - `npm test` + - `npm run audit:ci` +3. Re-enable normal command paths and monitor audit logs. + +--- + +## Communication Template + +Use this internal status template: + +```text +Incident: +Severity: +Start Time: +Current Status: +Impact: +Mitigation: +Next Update: