Register informed-decision-sitting-requester as create-only.
Some checks failed
Authentication acceptance / acceptance (push) Failing after 1m7s
Authentication acceptance / provider-contract (push) Successful in 15s
Build and Publish Container Image / build-and-push (push) Successful in 40s

Pin tenant:platform, approval:create only, and the KeyCape env name.
Live secret custody remains railiance-platform attended apply.

Assistant: grok
Assistant-Session: 01a0a23b-3bf0-7341-b4e5-9dc05f72573a
This commit is contained in:
tegwick 2026-09-15 20:08:07 +02:00
parent f67d98ff63
commit 1620ce2edd
3 changed files with 76 additions and 0 deletions

View file

@ -117,3 +117,19 @@ clients:
roles:
- secrets-engine-requester
tokenLifetime: 15m
# Compact sitting presenter; actor is informed-decision, not secrets-engine.
- clientId: informed-decision-sitting-requester
displayName: Informed Decision compact-sitting approval requester
audience: approval-engine
allowedScopes:
- approval:create
grantTypes:
- client_credentials
clientType: confidential
secretRef: env:KEYCAPE_INFORMED_DECISION_SITTING_REQUESTER_CLIENT_SECRET
serviceSubject: informed-decision
tenant: tenant:platform
roles:
- informed-decision-sitting-requester
tokenLifetime: 15m

View file

@ -0,0 +1,19 @@
{
"clientId": "informed-decision-sitting-requester",
"displayName": "Informed Decision compact-sitting approval requester",
"audience": "approval-engine",
"allowedScopes": [
"approval:create"
],
"grantTypes": [
"client_credentials"
],
"clientType": "confidential",
"secretRef": "env:KEYCAPE_INFORMED_DECISION_SITTING_REQUESTER_CLIENT_SECRET",
"serviceSubject": "informed-decision",
"tenant": "tenant:platform",
"roles": [
"informed-decision-sitting-requester"
],
"tokenLifetime": "15m"
}

View file

@ -64,6 +64,8 @@ func TestServiceRegistrationTenantsAreExactPerDecision(t *testing.T) {
// new client carrying a tenant cannot arrive unnoticed, and it did its
// job when the approver registration first landed (KEY-WP-0013-T05).
"informed-decision-approver": "tenant:platform",
"secrets-engine-requester": "tenant:platform",
"informed-decision-sitting-requester": "tenant:platform",
}
seen := map[string]bool{}
for _, c := range cfg.Clients {
@ -156,6 +158,45 @@ func TestApproverRegistrationShapeIsExact(t *testing.T) {
}
}
func TestSittingRequesterRegistrationShapeIsExact(t *testing.T) {
cfg, err := config.Load("../../../config/service-clients.example.yaml")
if err != nil {
t.Fatal(err)
}
var client *config.ClientConfig
for i := range cfg.Clients {
if cfg.Clients[i].ClientID == "informed-decision-sitting-requester" {
client = &cfg.Clients[i]
}
}
if client == nil {
t.Fatal("the sitting-requester registration is absent")
}
if client.ClientType != "confidential" || len(client.GrantTypes) != 1 || client.GrantTypes[0] != "client_credentials" {
t.Errorf("client type %q grants %v; want confidential client_credentials", client.ClientType, client.GrantTypes)
}
if client.SecretRef != "env:KEYCAPE_INFORMED_DECISION_SITTING_REQUESTER_CLIENT_SECRET" {
t.Errorf("secretRef = %q", client.SecretRef)
}
if client.ServiceSubject != "informed-decision" {
t.Errorf("serviceSubject = %q, want informed-decision", client.ServiceSubject)
}
if client.Tenant != "tenant:platform" || client.Audience != "approval-engine" {
t.Errorf("tenant/audience = %q %q", client.Tenant, client.Audience)
}
if len(client.AllowedScopes) != 1 || client.AllowedScopes[0] != "approval:create" {
t.Fatalf("scopes = %v; want only approval:create", client.AllowedScopes)
}
for _, scope := range client.AllowedScopes {
if scope == "approval:consume" || scope == "approval:approve" || scope == "approval:read" {
t.Fatalf("excess sitting-requester scope %q", scope)
}
}
if len(client.RedirectURIs) != 0 {
t.Errorf("redirect URIs = %v; sitting-requester is not a browser client", client.RedirectURIs)
}
}
// writeTestKeyPEM writes a placeholder key file; ValidateConfig checks the path
// exists, not the key material.
func writeTestKeyPEM(t *testing.T) string {