# rein-openweights AppRole for non-interactive OpenRouter key read Date: 2026-07-27 Catalog: `rein-openweights-openrouter-approle` (status `draft`, `resolvable: true` once the founder pastes the value) Owner: `ops-mason` (`plans/rein-openweights-openrouter-approle.md`) · consumer: `rein-openweights` glas-harness: `GLAS-WP-0002-T02` (the demand this lane unblocks) An OpenRouter API key so `rein-openweights` (the OpenRouter-driven rein in the glas-harness family) can authenticate to OpenBao **non-interactively** — no operator OIDC session, no human in the loop at run time — the same shape `agent-harness-binky-mail-approle` already uses for its own AppRole lane. Deliberately **not** a reuse of the existing `openrouter-llm-connect` lane: that lane's `auth_method` is interactive-caller-shaped and its policy is shared/high-risk across `activity-core`'s broader usage. This lane is narrowly scoped to exactly one path, one consumer — see `ops-mason/plans/rein-openweights-openrouter-approle.md` §2 for the full reuse-vs-new reasoning. --- ## OpenBao pointers | Field | Value | | --- | --- | | Mount | `reins` (new KV v2 engine, enabled 2026-07-27 — no existing mount fit without widening scope) | | Path | `reins/rein-openweights/openrouter` | | Field | `api_key` | | Policy | `workload-kv-read-rein-openweights-openrouter` (read-only, scoped to exactly this path) | | AppRole | `rein-openweights` | | `token_ttl` / `token_max_ttl` | `15m` / `30m` (matches `agent-harness-binky-mail`) | | `token_num_uses` | `8` (matches `agent-harness-binky-mail` — **not** OpenBao's own default of `0`/unlimited, see build note below) | | `secret_id_ttl` | `0` (no expiry, current build-phase posture — same choice `agent-harness-binky-mail` made) | | Risk | standard (single provider key, no data-store or infra access; bounded to this one path) | --- ## Worker checklist For `rein-openweights` itself, non-interactive: 1. AppRole login (no operator present): ```bash ROLE_ID=$(cat ~/.local/rein-openweights/approle/role_id) SECRET_ID=$(cat ~/.local/rein-openweights/approle/secret_id) TOKEN=$(bao write -field=token auth/approle/login role_id="$ROLE_ID" secret_id="$SECRET_ID") ``` 2. Fetch the field (matches `rein_openweights/credentials.py`'s own `resolve_openrouter_api_key()` — this is exactly what that code does): ```bash BAO_TOKEN="$TOKEN" bao kv get -field=api_key reins/rein-openweights/openrouter ``` `rein-openweights`'s own `REIN_OPENWEIGHTS_APPROLE_DIR` env var already defaults to the delivery path above; no code change needed to consume this lane once the value is provisioned. --- ## Founder provision (the one place the live value exists outside OpenBao) Not yet done — this is what keeps this entry `status: draft`. Once ready: ```bash # Through ops-warden's paste-once-provision desk (localhost web form), # never a terminal/chat/git paste of the real key. ``` Then re-verify field presence (length only, never the value), promote this catalog entry to `active`, and notify `glas-harness`/`rein-openweights` so `GLAS-WP-0002-T02`'s live verification can proceed. ## Rotation ```bash bao write -f auth/approle/role/rein-openweights/secret-id # new secret_id # deliver mode-0600 to REIN_OPENWEIGHTS_APPROLE_DIR; shred the old file ``` ## See also - `ops-mason/plans/rein-openweights-openrouter-approle.md` — full construction plan, all four phases - `ops-mason/INTENT.md` — the builder role this lane was provisioned through - `wiki/playbooks/agent-harness-secrets.md#lane-3-mail-approle` — the closest existing analog this lane's shape was mirrored from