Correct platform infrastructure client tenant bindings
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e324-abce-7e51-bb2b-496f097afdb0
This commit is contained in:
parent
3b0446e0ef
commit
717a97408a
7 changed files with 47 additions and 16 deletions
|
|
@ -9,7 +9,7 @@ clients:
|
|||
clientType: "confidential"
|
||||
secretRef: "env:KEYCAPE_CODEX_RAILIANCE_PLATFORM_CLIENT_SECRET"
|
||||
serviceSubject: "service:codex:railiance-platform"
|
||||
tenant: "tenant:coulomb"
|
||||
tenant: "tenant:platform"
|
||||
roles: ["coding-agent"]
|
||||
tokenLifetime: "15m"
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ clients:
|
|||
clientType: "confidential"
|
||||
secretRef: "env:KEYCAPE_SECRETS_ENGINE_OPENBAO_CLIENT_SECRET"
|
||||
serviceSubject: "service:secrets-engine"
|
||||
tenant: "tenant:coulomb"
|
||||
tenant: "tenant:platform"
|
||||
roles: ["secrets-engine"]
|
||||
tokenLifetime: "15m"
|
||||
|
||||
|
|
|
|||
|
|
@ -84,3 +84,22 @@ break-glass providers and require their own authorization and evidence.
|
|||
Verification must inspect metadata and capabilities without reading a secret
|
||||
value. A coding-agent check must prove the `agent-high-risk-boundary` deny wins
|
||||
against any otherwise readable workload policy.
|
||||
|
||||
## Consumer/platform reconciliation — 2026-09-27
|
||||
|
||||
The operator clarified that platform infrastructure belongs to tenant zero,
|
||||
**`tenant:platform`**, including OpenBao and its platform service identities.
|
||||
Coulomb is a workload on the platform; `coulomb.social` is currently shared DNS,
|
||||
not a tenant assignment. The former matching `tenant:coulomb` declarations were
|
||||
wrong. `codex-railiance-platform` and `secrets-engine-openbao` now declare
|
||||
`tenant:platform`, coordinated with the platform role and consumer preflight.
|
||||
This source correction does not migrate live registrations or existing tokens.
|
||||
|
||||
Public discovery at `https://kc.coulomb.social/.well-known/openid-configuration`
|
||||
was rechecked: issuer `https://kc.coulomb.social`, JWKS `/jwks`, token endpoint
|
||||
`/token`, with `client_credentials` advertised. This establishes public endpoint
|
||||
metadata only, not that this confidential client is registered or provisioned.
|
||||
Platform's RPF-WP-0035-T02 now carries the exact proposed login-only role/config/
|
||||
policy. The remaining joint acceptance is protected client custody and actual
|
||||
registration, attended role provisioning, native signature/claim refusals and
|
||||
OpenBao self-revocation. KEY-WP-0009's provider-contract completion is unchanged.
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ never influenced by request parameters.
|
|||
|
||||
| Principal | Source of `tenant` | Value in the reviewed registrations |
|
||||
| --- | --- | --- |
|
||||
| Service (`client_credentials`) | The client's `tenant` field. Required by config validation — a `client_credentials` client without `serviceSubject` and `tenant` fails startup validation. | In `config/service-clients.example.yaml`: `tenant:platform` for `secrets-engine-approval` and `approval-engine-operator`; `tenant:coulomb` for `codex-railiance-platform` and `secrets-engine-openbao`. |
|
||||
| Human (`authorization_code`) | The directory user's tenant, falling back to the platform default when unset. | Directory value, else `tenant:coulomb`. |
|
||||
| Service (`client_credentials`) | The client's `tenant` field. Required by config validation — a `client_credentials` client without `serviceSubject` and `tenant` fails startup validation. | In `config/service-clients.example.yaml`: `tenant:platform` for the platform approval clients, `codex-railiance-platform` and `secrets-engine-openbao` (operator correction, 2026-09-27). |
|
||||
| Human (`authorization_code`) | The directory user's tenant, falling back to the legacy workload default when unset. | Directory value, else `tenant:coulomb`. |
|
||||
|
||||
`tenant`, `tenant_hint`, `audience` and `resource` request parameters cannot
|
||||
change the claim. `tenant_hint` on `/authorize` reaches registration/enrollment
|
||||
|
|
@ -47,7 +47,9 @@ The decision changed the `tenant` field on exactly two registrations,
|
|||
entries in `docs/approval-engine-provisioning-request.yaml`. Deliberately
|
||||
unchanged:
|
||||
|
||||
- `codex-railiance-platform` and `secrets-engine-openbao` keep `tenant:coulomb`.
|
||||
- Historical exception superseded 2026-09-27: `codex-railiance-platform` and
|
||||
`secrets-engine-openbao` belong to `tenant:platform`; see the OpenBao contract.
|
||||
Apply the issuer/role/consumer changes in a coordinated deployment window.
|
||||
- Human directory resolution keeps its `tenant:coulomb` default.
|
||||
- No cross-tenant grant is implied: a `tenant:platform` token conveys no reach
|
||||
into `tenant:coulomb` resources, and audiences, scopes, subjects, roles,
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ func TestServiceRegistrationTenantsAreExactPerDecision(t *testing.T) {
|
|||
want := map[string]string{
|
||||
"secrets-engine-approval": "tenant:platform",
|
||||
"approval-engine-operator": "tenant:platform",
|
||||
"codex-railiance-platform": "tenant:coulomb",
|
||||
"secrets-engine-openbao": "tenant:coulomb",
|
||||
"codex-railiance-platform": "tenant:platform",
|
||||
"secrets-engine-openbao": "tenant:platform",
|
||||
// The only browser client here, and the only registration-supplied
|
||||
// human tenant. Reviewed and added deliberately: this guard exists so a
|
||||
// new client carrying a tenant cannot arrive unnoticed, and it did its
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ func TestServiceClientExampleContracts(t *testing.T) {
|
|||
codingAgent := cfg.Clients[0]
|
||||
if codingAgent.ClientID != "codex-railiance-platform" ||
|
||||
codingAgent.ServiceSubject != "service:codex:railiance-platform" ||
|
||||
codingAgent.Tenant != "tenant:coulomb" ||
|
||||
codingAgent.Tenant != "tenant:platform" ||
|
||||
codingAgent.TokenLifetime != "15m" {
|
||||
t.Fatalf("coding-agent contract drifted: %+v", codingAgent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ func TestApprovalClientIssuesExactPlatformTenantAndRejectsAliases(t *testing.T)
|
|||
GrantTypes: []string{"client_credentials"},
|
||||
ClientType: "confidential",
|
||||
ClientSecret: "approval-test-secret",
|
||||
ServiceSubject: "service:secrets-engine",
|
||||
ServiceSubject: "service:coulomb-workload-test",
|
||||
Tenant: "tenant:platform",
|
||||
Roles: []string{"secrets-engine"},
|
||||
}
|
||||
|
|
@ -147,22 +147,22 @@ func TestApprovalClientIssuesExactPlatformTenantAndRejectsAliases(t *testing.T)
|
|||
}
|
||||
}
|
||||
|
||||
// The aligned decision grants no cross-tenant reach: the unrelated OpenBao
|
||||
// login client keeps tenant:coulomb.
|
||||
// Platform ownership does not elevate workload clients. Request parameters
|
||||
// cannot change a workload registration's tenant.
|
||||
func TestUnrelatedServiceClientKeepsCoulombTenant(t *testing.T) {
|
||||
h := serviceTokenHandler(t)
|
||||
h.ClientConfig["secrets-engine-openbao"] = &domain.Client{
|
||||
ClientID: "secrets-engine-openbao",
|
||||
h.ClientConfig["coulomb-workload-test"] = &domain.Client{
|
||||
ClientID: "coulomb-workload-test",
|
||||
AllowedScopes: []string{"openbao:login"},
|
||||
GrantTypes: []string{"client_credentials"},
|
||||
ClientType: "confidential",
|
||||
ClientSecret: "openbao-test-secret",
|
||||
ServiceSubject: "service:secrets-engine",
|
||||
ServiceSubject: "service:coulomb-workload-test",
|
||||
Tenant: "tenant:coulomb",
|
||||
Roles: []string{"secrets-engine"},
|
||||
}
|
||||
req := tokenRequest(url.Values{"grant_type": {"client_credentials"}, "scope": {"openbao:login"}, "tenant": {"tenant:platform"}})
|
||||
req.SetBasicAuth("secrets-engine-openbao", "openbao-test-secret")
|
||||
req.SetBasicAuth("coulomb-workload-test", "openbao-test-secret")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusOK {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ status: finished
|
|||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
created: "2026-08-23"
|
||||
updated: "2026-09-08"
|
||||
updated: "2026-09-27"
|
||||
depends_on:
|
||||
- NK-WP-0030
|
||||
- KEY-WP-0006
|
||||
|
|
@ -126,3 +126,13 @@ disablement and the claim set; secret custody, OpenBao roles/policies and token
|
|||
enforcement, privacyIDEA factor and token lifecycle, resource authorization and
|
||||
deployment remain with their named owners. C2a is not claimed. This closes the
|
||||
notification gap; it is still not evidence of live deployment or provider cutover.
|
||||
|
||||
### 2026-09-27 operator tenant-zero correction
|
||||
|
||||
OpenBao infrastructure identities belong to `tenant:platform`, not Coulomb.
|
||||
Corrected both static infrastructure registrations, matching source tests and
|
||||
the tenant/OpenBao contracts. Consumer preflight and platform role sources are
|
||||
updated together; no live registration or token migration is claimed. The
|
||||
provider contract remains complete; RPF-WP-0035-T02 and SECRETS-WP-0008-T06
|
||||
retain coordinated custody/deployment and native rejection/revocation proof.
|
||||
Human fallback and workload tenant grants are not elevated to platform.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue