Bind platform OpenBao service identity to tenant zero
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e324-abce-7e51-bb2b-496f097afdb0
This commit is contained in:
parent
cbe218b26a
commit
f0d82908e9
6 changed files with 35 additions and 17 deletions
|
|
@ -6,7 +6,7 @@ secrets-engine now implements the consumer half of KeyCape's accepted
|
|||
the non-cryptographic contract before any future OpenBao login:
|
||||
|
||||
- subject `service:secrets-engine`, audience/client `secrets-engine-openbao`;
|
||||
- service principal in `tenant:coulomb`, role `secrets-engine`;
|
||||
- service principal in `tenant:platform` (platform infrastructure, tenant zero), role `secrets-engine`;
|
||||
- exact `openbao:login` scope and KeyCape AAL1 client-secret assurance;
|
||||
- RS256 declaration, bounded issue/expiry timestamps, maximum 15-minute life,
|
||||
and renewal when no more than three minutes remain;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
> Superseded source finding, 2026-09-27: the operator confirmed that OpenBao
|
||||
> and its infrastructure service identities belong to `tenant:platform` (tenant
|
||||
> zero). Coulomb is a workload tenant. The former `service_auth.TENANT` value
|
||||
> discussed below is historical; source preflight now requires platform and
|
||||
> rejects Coulomb. Live migration remains SECRETS-WP-0008-T06. See the platform
|
||||
> owner's `docs/platform-tenant-essentials-review.md` for the cross-repo review.
|
||||
|
||||
# Tenant alignment
|
||||
|
||||
Answer to the `GLAS-WP-0015` production-dependency handoff question, which asked
|
||||
|
|
|
|||
|
|
@ -36,11 +36,9 @@ DIGEST_RE = re.compile(r"^sha256:[0-9a-f]{64}$")
|
|||
#: the vendored replay fixtures in ``tests/test_decision_replay.py`` instead of
|
||||
#: being left to a deployment to supply correctly.
|
||||
#:
|
||||
#: This is not the KeyCape JWT tenant. ``service_auth.TENANT`` is
|
||||
#: ``tenant:coulomb``, which is the exact value this package denies. Whether
|
||||
#: those name one tenant or two layers is an open owner question -- see
|
||||
#: ``docs/tenant-alignment.md`` -- and is deliberately not resolved by reusing
|
||||
#: one constant for both.
|
||||
#: Operator clarification, 2026-09-27: the platform infrastructure identity
|
||||
#: also belongs to tenant:platform. Keep audience-specific profile validation;
|
||||
#: matching tenant strings do not grant cross-audience or workload authority.
|
||||
REQUEST_TENANT = "tenant:platform"
|
||||
|
||||
SCHEMA_VERSION = "0.1"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""KeyCape service-JWT exchange shared by two separately validated profiles.
|
||||
|
||||
The OpenBao login profile and approval consumer profile have distinct clients,
|
||||
audiences, tenants and scopes. Provider selection never falls back to another
|
||||
audiences and scopes; both belong to tenant:platform. Provider selection never falls back to another
|
||||
identity. Token parsing is a claim preflight, not signature verification: the
|
||||
receiving OpenBao or approval-engine service verifies RS256 before accepting it.
|
||||
"""
|
||||
|
|
@ -24,7 +24,7 @@ from secrets_engine.openbao import read_strict_token_file
|
|||
CLIENT_ID = "secrets-engine-openbao"
|
||||
SUBJECT = "service:secrets-engine"
|
||||
PRINCIPAL_TYPE = "service"
|
||||
TENANT = "tenant:coulomb"
|
||||
TENANT = "tenant:platform"
|
||||
ROLE = "secrets-engine"
|
||||
SCOPE = "openbao:login"
|
||||
MAX_TOKEN_SECONDS = 15 * 60
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def _jwt(**overrides):
|
|||
"iat": now,
|
||||
"exp": now + 900,
|
||||
"principal_type": "service",
|
||||
"tenant": "tenant:coulomb",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": ["secrets-engine"],
|
||||
"groups": [],
|
||||
"scope": "openbao:login",
|
||||
|
|
@ -68,6 +68,7 @@ def test_preflight_accepts_exact_service_contract_and_renewal_window():
|
|||
({"iss": "https://attacker.test"}, "'iss'"),
|
||||
({"sub": "service:operator"}, "'sub'"),
|
||||
({"aud": "different"}, "'aud'"),
|
||||
({"tenant": "tenant:coulomb"}, "'tenant'"),
|
||||
({"tenant": "tenant:other"}, "'tenant'"),
|
||||
({"roles": ["admin"]}, "roles"),
|
||||
({"scope": "openbao:login admin"}, "scope"),
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ Acceptance:
|
|||
```task
|
||||
id: SECRETS-WP-0008-T06
|
||||
status: wait
|
||||
blocking_reason: "RPF-WP-0035-T02 still awaits exact service claims/tenant, credential custody and scoped attended JWT role provisioning with native login/negative/revocation proof. The historical env-auth acceptance is not service-JWT adoption."
|
||||
blocking_reason: "RPF-WP-0035-T02 awaits coordinated platform-tenant live registration, credential custody and scoped attended JWT role provisioning with native login/negative/revocation proof. The historical env-auth acceptance is not service-JWT adoption."
|
||||
priority: medium
|
||||
state_hub_task_id: "d7bc8bdc-a0f8-5058-a640-374ef9859148"
|
||||
```
|
||||
|
|
@ -354,12 +354,13 @@ Designed: role/audience `secrets-engine-openbao`, subject
|
|||
budget, login-only. KeyCape issuer `https://kc.coulomb.social` and its JWKS are
|
||||
now confirmed live, so the remaining blocker is this registration's issued
|
||||
claims, consumer readiness, an approved source and attended apply authority.
|
||||
**Open question for secrets-engine, not answered in the triage session:** the
|
||||
JWT design says `tenant:coulomb`, while the approval chain resolved to
|
||||
`tenant:platform` (decision `5ed3fb35`) and approval-engine compares tenant by
|
||||
exact string. Which tenant the OpenBao service identity carries is a design
|
||||
decision for an owner session; platform will correct its design before the
|
||||
role exists once told. A service login grants no lane mutation authority. Companion §7 / statute §3.4: an
|
||||
**Resolved by the operator, 2026-09-27:** OpenBao is platform infrastructure,
|
||||
belonging to tenant zero, `tenant:platform`. Coulomb is a workload tenant;
|
||||
its DNS domain does not own the platform. The former matching Coulomb claims
|
||||
were incorrect. KeyCape registrations, platform JWT roles and this consumer's
|
||||
strict preflight are corrected together in source. Live registration/custody,
|
||||
coordinated deployment and native refusal/revocation proof remain T06.
|
||||
A service login grants no lane mutation authority. Companion §7 / statute §3.4: an
|
||||
agent holds no long-lived credential of its own. Authority is per task,
|
||||
time-bounded, and attributable to the principal it acts for.
|
||||
|
||||
|
|
@ -511,6 +512,17 @@ refuses nested/identity-bearing version pins and names the accepted text and
|
|||
rulings on every run, including PASS. Declaration spellings are unchanged.
|
||||
|
||||
T06 remains wait: railiance-platform's RPF-WP-0035-T02 still records an
|
||||
unprovisioned, login-only JWT role, pending exact service claims/tenant and
|
||||
unprovisioned, login-only JWT role, pending platform-tenant live registration and
|
||||
custody/attended admission. The existing env-auth native receipt cannot prove
|
||||
steady-state service JWT login. This is the only remaining task in this workplan.
|
||||
|
||||
### 2026-09-27 platform essentials follow-up
|
||||
|
||||
Operator tenant-zero decision `be5287cb-d458-47bc-9183-2a40dd7ae04b` corrects
|
||||
OpenBao infrastructure identities to `tenant:platform`. Source changes are
|
||||
coordinated in KeyCape, railiance-platform and Secrets Engine. The platform
|
||||
owner records the bounded essentials review in
|
||||
`docs/platform-tenant-essentials-review.md`. T06 remains wait for coordinated
|
||||
live registration/custody, provisioning and native refusal/revocation evidence.
|
||||
No new task or workplan was created. Warden's npm no-rotation hold remains;
|
||||
factory records now consume the completed generic approval and companion returns.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue