diff --git a/workplans/ILIB-WP-0002-library-infrastructure.md b/workplans/ILIB-WP-0002-library-infrastructure.md index 1ec4f76..cb38050 100644 --- a/workplans/ILIB-WP-0002-library-infrastructure.md +++ b/workplans/ILIB-WP-0002-library-infrastructure.md @@ -158,7 +158,8 @@ Done 2026-10-05: `run-due` runs under a lock. The systemd units are in `ops/syst ```task id: ILIB-WP-0002-T07 -status: todo +status: wait +blocking_reason: "Needs the unattended OpenBao AppRole lane (ILIB-WP-0003)." priority: high state_hub_task_id: "1e2ab60c-86ef-5e1c-9b94-1f9f1b3182ba" ``` @@ -195,3 +196,7 @@ version 2. 2026-10-05: the founder reports that the entry was created and `IMAP_PASSWORD` was added. This is not yet verified natively. A live read-only scan is still needed for acceptance. + +2026-10-05: the founder rejected an env file as a credential cache. The live +credential now comes from an ops-mason AppRole lane, fetched on every run +(ILIB-WP-0003). This task completes with ILIB-WP-0003-T06. diff --git a/workplans/ILIB-WP-0003-openbao-approle-imap.md b/workplans/ILIB-WP-0003-openbao-approle-imap.md new file mode 100644 index 0000000..2f79445 --- /dev/null +++ b/workplans/ILIB-WP-0003-openbao-approle-imap.md @@ -0,0 +1,145 @@ +--- +id: ILIB-WP-0003 +type: workplan +title: "Read the library IMAP credential unattended from OpenBao" +domain: infotech +repo: inbound-library +status: active +flavor: implementation +owner: claude +topic_slug: custodian +created: "2026-10-05" +updated: "2026-10-05" +--- + +# Read the library IMAP credential unattended from OpenBao + +The timer must read `library@coulomb.social` without an operator and without a +copy of the password cached on disk. The ecosystem already has the pieces; this +workplan uses them and does not build new infrastructure. + +- **ops-mason** builds OpenBao AppRoles, policies and KV path structure from a + construction plan (`plans/.md`). The plan goes from draft to reviewed, then + to approved (by the founder, from its executive summary), then built, then + catalogued. The build refuses to run unless the approved spec digest matches + the execution inputs. AppRole credentials go to private, exclusive files, and + the build is written to ops-mason's own audit trail. `AppRoleKVSpec` already + generates this shape. +- **ops-warden** routes to the lane through a pointer-only catalog entry + (`registry/routing/catalog.yaml`). It never holds the value. +- Precedents: `rein-openweights-openrouter-approle` and + `agent-harness-binky-mail` (an unattended AppRole on the workstation), and + `rein-aharness/mailscan.py` (an AppRole login followed by an IMAP scan). + +Audit trail: the approved construction plan holds the decision and its reasoning, +and the approved digest binds that decision to what was built. ops-mason's build +evidence and audit log record the execution. The warden catalog commit records +the routing. The KV entry `platform/workloads/inbound-library/imap` itself was +created by `railiance-platform/scripts/inbound_library_imap_entry.py` +(docs/inbound-library-imap-custody.md). + +## Draft the ops-mason construction plan + +```task +id: ILIB-WP-0003-T01 +status: todo +priority: high +``` + +Write `ops-mason/plans/inbound-library-imap-approle.md`, with demand source +ILIB-WP-0002-T07 and `credential_type: openbao-approle-kv`. Proposed shape: +- policy `workload-kv-read-inbound-library-imap`, read only, on + `platform/data/workloads/inbound-library/imap`; +- AppRole `inbound-library`, following the precedent: `token_ttl` 15m, + `token_max_ttl` 30m, and an explicitly bounded `token_num_uses`; +- delivery to `~/.local/inbound-library/approle/` (`role_id`, `secret_id`); +- `secret_id_ttl` to be decided in review. + +Include the section 2 existing-structure survey (live `bao` policy, auth and +secrets lists, and the warden catalog), the phase 2 self-review, and the build +spec with its digest. + +Acceptance: the plan reaches status `reviewed` and its executive summary is +rendered. + +## Founder approval + +```task +id: ILIB-WP-0003-T02 +status: todo +priority: high +``` + +The founder decides from the executive summary. The plan then records +`approved_by`, `approved_at` and `approved_spec_sha256`. + +Acceptance: the plan is `approved`. The digest matches the build spec. + +## Build the lane + +```task +id: ILIB-WP-0003-T03 +status: todo +priority: high +``` + +Run the ops-mason AppRole builder from the approved plan, in an attended +platform-admin session. It creates the policy and the AppRole and delivers +`role_id` and `secret_id` to private files. Then record capabilities-safe +evidence: the lane token can read the path, a default-policy token is denied, +and no value is printed. Append section 6 with the build result. + +Acceptance: the plan is `built`, and the evidence is in ops-mason +`docs/evidence/`. + +## Fetch the credential on every run + +```task +id: ILIB-WP-0003-T04 +status: todo +priority: high +``` + +In `inbound_library`, add a standard-library OpenBao client: +- an AppRole login using the delivered files; +- one KV v2 read of `IMAP_USERNAME`, `IMAP_PASSWORD`, `IMAP_HOST`, `IMAP_PORT` + and `IMAP_FOLDER`; +- values held in memory for one run only, never logged, never written to disk. + +The bao address, the AppRole directory and the KV path go in +`config/library.json`. The environment variables remain only as an explicit +override for tests. When OpenBao is unreachable, `run-due` reports +`credential_unavailable`, and matching and notices still run. Remove the +`EnvironmentFile` from the service unit. + +Acceptance: the tests use a fake OpenBao (login, read, denied, unreachable). +No secret appears in any output. + +## Route the lane in ops-warden + +```task +id: ILIB-WP-0003-T05 +status: todo +priority: medium +``` + +ops-mason proposes a pointer-only catalog entry `inbound-library-imap-approle` +(`warden_executes: false`) and a playbook, modelled on +`rein-openweights-openrouter-approle`. + +Acceptance: `warden access` resolves the need to this lane. + +## Live verification + +```task +id: ILIB-WP-0003-T06 +status: todo +priority: high +``` + +Install the timer and trigger one run through systemd. The journal must show an +AppRole login and a read-only scan of `library@coulomb.social`, with no secret +in the output. This also completes ILIB-WP-0002-T07. + +Acceptance: one real mail is retained with provenance. No mailbox state changes, +and no credential file exists other than the AppRole delivery.