From 9084581461545e07d26fc29783c9fd79446e54c6 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 5 Oct 2026 16:12:48 +0200 Subject: [PATCH] Route inbound-library-imap-approle (ILIB-WP-0003-T05). Pointer-only catalog entry for the ops-mason-built AppRole inbound-library (plan inbound-library-imap-approle, built 2026-10-05) reading platform/workloads/inbound-library/imap, plus a pointer playbook. Routing coverage re-measured: unknown 20 -> 21. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 1170398@bnt-lap001 Assistant-Session: 622cd705-cb31-4322-ba08-dd42e44fa583 --- pep-stance.yaml | 4 +- registry/routing/catalog.yaml | 40 +++++++++++++++++++ tests/test_workload_join.py | 2 +- .../playbooks/inbound-library-imap-approle.md | 36 +++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 wiki/playbooks/inbound-library-imap-approle.md diff --git a/pep-stance.yaml b/pep-stance.yaml index 62eb0a5..fec6920 100644 --- a/pep-stance.yaml +++ b/pep-stance.yaml @@ -93,6 +93,8 @@ on_apply: # Signing targets are unchanged. Reported to gate-house per §13.1 — a figure in # a register that cannot detect its own staleness is only as good as the last # re-measure, and this one was stale by eight lanes before the test caught it. +# 2026-10-05: inbound-library-imap-approle added as an applicable lane without a +# published workload declaration, so routing unknown rose 20 -> 21; resolved unchanged. classification_coverage: measured: "2026-10-05" attribution: self-measured @@ -102,7 +104,7 @@ classification_coverage: not_applicable: 1 routing_lanes: resolved: 4 - unknown: 20 + unknown: 21 not_applicable: 16 verdict_caching: none diff --git a/registry/routing/catalog.yaml b/registry/routing/catalog.yaml index 8bacce2..9d441a8 100644 --- a/registry/routing/catalog.yaml +++ b/registry/routing/catalog.yaml @@ -1225,6 +1225,46 @@ entries: - "Optionally re-mint the OpenRouter key itself if it rotated independently." - "Verify AppRole login + field presence (length only); confirm default/other policies still deny sibling paths." + - id: inbound-library-imap-approle + title: inbound-library AppRole for non-interactive library@coulomb.social IMAP read + need_keywords: [inbound-library, approle, library@coulomb.social, mail, imap, unattended] + owner_repo: ops-mason + subsystem: OpenBao AppRole + inbound-library + warden_executes: false + wiki_ref: wiki/playbooks/inbound-library-imap-approle.md#worker-checklist + canon_ref: ops-mason/plans/inbound-library-imap-approle.md + reviewed: '2026-10-05' + status: active + delegation: + mode: interim + intended_owner: ops-mason + blocked_on: AppRole is a host-standing credential; no owner-fronted exec for the + library mailbox read + reviewed: '2026-10-05' + verified: unverified + risk: high + workload_ref: + applicability: applicable + unknown_reason: inbound-library has not published an authoritative workload identity + declaration. + auth_method: AppRole login role=inbound-library (role_id+secret_id in ~/.local/inbound-library/approle, + config/library.json credential.approle_dir) + path_template: platform/workloads/inbound-library/imap + fetch_command: 'bao write -field=token auth/approle/login role_id=$ROLE_ID secret_id=$SECRET_ID # + then bao kv get -field=IMAP_PASSWORD platform/workloads/inbound-library/imap' + exec_capable: false + lane: secret + rotation: + method: rotate + owner: ops-mason + automatable: false + steps: + - bao write -f auth/approle/role/inbound-library/secret-id -> new secret_id; deliver + mode-0600 to ~/.local/inbound-library/approle; shred old secret_id file. + - Optionally re-mint the IMAP password at IONOS and add it as a new version of + platform/workloads/inbound-library/imap (founder, attended). + - Verify via one inbound-library run-due (AppRole login + read-only scan); confirm + a default-policy token still gets deny on the data path. - id: coulomb-social-runtime-env title: coulomb.social runtime env Secret (SECRET_KEY, DATABASE_URL, USER_ENGINE_PROXY_SECRET) need_keywords: diff --git a/tests/test_workload_join.py b/tests/test_workload_join.py index a398251..40e97ae 100644 --- a/tests/test_workload_join.py +++ b/tests/test_workload_join.py @@ -13,7 +13,7 @@ def test_repo_catalog_uses_only_explicit_workload_references(): report = build(ROOT / "registry/routing/catalog.yaml", Path.home()) assert report["ok"] is True assert len(report["resolved"]) == 4 - assert len(report["unknown"]) == 20 + assert len(report["unknown"]) == 21 # 15 since 2026-09-21: the layer-declaration route is repository conformance # guidance, not a workload delivery lane, and the two NetKingdom SSO lanes # (c374d41) remain provider/control-plane credentials. Lanes added after diff --git a/wiki/playbooks/inbound-library-imap-approle.md b/wiki/playbooks/inbound-library-imap-approle.md new file mode 100644 index 0000000..11b30a4 --- /dev/null +++ b/wiki/playbooks/inbound-library-imap-approle.md @@ -0,0 +1,36 @@ +# inbound-library AppRole for the library@coulomb.social IMAP read +Date: 2026-10-05 +Catalog: `inbound-library-imap-approle` (status `active`, risk `high`) +Owner: `ops-mason` (`plans/inbound-library-imap-approle.md`, built 2026-10-05) · consumer: `inbound-library` +Demand: `inbound-library/workplans/ILIB-WP-0003` + +inbound-library's systemd user timer reads the dedicated mailbox +`library@coulomb.social` read-only every 15 minutes, with no operator present. +Each run logs in with this AppRole, reads the IMAP entry once, and revokes its +token. No copy of the password is kept on disk. + +## OpenBao pointers + +| Field | Value | +| --- | --- | +| Path | `platform/workloads/inbound-library/imap` (fields `IMAP_USERNAME`, `IMAP_PASSWORD`, `IMAP_HOST`, `IMAP_PORT`, `IMAP_TLS`, `IMAP_FOLDER`) | +| Policy | `workload-kv-read-inbound-library-imap` (read on that entry's data and metadata only) | +| AppRole | `inbound-library` — `token_ttl` 15m, `token_max_ttl` 30m, `token_num_uses` 4, `secret_id_ttl` 0 | +| Delivery | `~/.local/inbound-library/approle/{role_id,secret_id}` (0600) | +| Entry custody | `railiance-platform/docs/inbound-library-imap-custody.md` | + +## Worker checklist + +This lane is for the inbound-library process only. Coding agents do not read the +AppRole files or the KV entry. To check the lane, run the consumer and read its +report: + +```bash +systemctl --user start inbound-library.service +journalctl --user -u inbound-library.service -n 30 -o cat # intake.ok, never a secret +``` + +`credential_unavailable` means one of these: OpenBao is unreachable (the +`openbao-ui-railiance01` bridge forward), the AppRole files are missing, or the +read was denied. +For the procedure itself, see the ops-mason plan; this page only points to it.