# issue-core Ingestion API Key — OpenBao Custody Date: 2026-06-24 Workplan: WARDEN-WP-0012 T1 Catalog: `issue-core-ingestion-api-key` (draft until path ships) Pointer playbook for agents and operators wiring the **shared ingestion key** between `activity-core` IssueSink emission and `issue-core` REST ingestion. ops-warden does not vend this key — custody belongs to `railiance-platform` (OpenBao) and the consuming workloads. --- ## Owners | Concern | Owner repo | Authoritative doc | | --- | --- | --- | | OpenBao path, ESO delivery, rotation ceremony | `railiance-platform` | `docs/argocd-gitops.md` — OpenBao path convention | | Ingestion server (`POST /issues/`) | `issue-core` | `README.md` — REST Ingestion Server | | IssueSink consumer | `activity-core` | `docs/issue-core-emission-boundary.md` | | Emission pairing checklist | `ops-warden` | `wiki/playbooks/activity-core-issue-sink.md` | --- ## Do not ask ops-warden `ISSUE_CORE_API_KEY` is not an SSH certificate. Generic API-key routing: ```bash warden route show openbao-api-key --json warden route show activity-core-issue-sink --json ``` Never paste key values into Git, State Hub, workplans, logs, or agent chat. --- ## Canonical OpenBao path (expected) Coordinate with `railiance-platform` before writing secrets. Documented custody shape: ```text platform/workloads/issue-core/issue-core/issue-core-runtime ``` Expected properties (names only — no values): ```text ISSUE_CORE_API_KEY GITEA_BACKEND_TOKEN ``` The ExternalSecret manifest belongs in `issue-core` workload manifests (tenant repo owns runtime deployment). Platform owns mount policy and path provisioning. **Promotion gate:** catalog entry stays `status: draft` until this path exists in the live OpenBao cluster and an owner-repo ExternalSecret is merged. --- ## Worker checklist ### 1. Confirm path with platform owner - [ ] Path exists: `platform/workloads/issue-core/issue-core/issue-core-runtime` - [ ] KV policy allows `issue-core` service account read (workload-kv-read template) - [ ] `railiance-platform` workplan records the canonical path (no forked conventions) ### 2. External Secrets Operator pattern Prefer ESO for values that become Kubernetes Secrets consumed by Helm charts (`railiance-platform/docs/openbao.md`, `docs/argocd-gitops.md`): - [ ] `ExternalSecret` in `issue-core` namespace targets the path above - [ ] Secret keys map to `ISSUE_CORE_API_KEY` (and `GITEA_BACKEND_TOKEN` if used) - [ ] `activity-core` deployment receives the **same** key value via its own ExternalSecret (paired env vars — see activity-core-issue-sink playbook) - [ ] Do not use the OpenBao injector in the current deployment ### 3. Local dev (no OpenBao) Generate once and export on both processes — not for production: ```bash export ISSUE_CORE_API_KEY="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" ``` See `wiki/playbooks/activity-core-issue-sink.md#worker-checklist` for pairing steps. ### 4. Rotation - [ ] Generate new key in OpenBao (platform operator ceremony) - [ ] Update both `issue-core` and `activity-core` Secrets before revoking old value - [ ] Verify one live POST returns `201` with `issue_id` - [ ] Record rotation in platform audit log — not in git ### 5. Privileged read policy Break-glass and operator reads follow `railiance-platform/docs/openbao.md` — scoped tokens only, never root token for routine workload secret inspection. --- ## Owner-repo next actions | Repo | Action | | --- | --- | | `railiance-platform` | Provision KV path, policy, and document in OpenBao runbook | | `issue-core` | Merge ExternalSecret + Deployment env from synced Secret | | `activity-core` | Mirror `ISSUE_CORE_API_KEY` injection for REST sink mode | When the path ships, ops-warden promotes `issue-core-ingestion-api-key` to `status: active` with this `wiki_ref`. --- ## See also - `wiki/playbooks/activity-core-issue-sink.md` - `railiance-platform/docs/argocd-gitops.md` - `warden route show issue-core-ingestion-api-key --all --json`