diff --git a/modules/keycloak/cmd/keycloak-provider/main.go b/modules/keycloak/cmd/keycloak-provider/main.go index f17d7c89..81b274bc 100644 --- a/modules/keycloak/cmd/keycloak-provider/main.go +++ b/modules/keycloak/cmd/keycloak-provider/main.go @@ -51,8 +51,8 @@ func main() { say("%v — the provisioner cannot run without it", err) } else if consumers := handedConsumersFile(os.Getenv, os.Stat); consumers != "" { // Handed to the provisioner (novox/hq ADR 0373): the provider helper answers the consumers its - // machine's client fills the file with; the grant directory is not read. Retirement is the - // harness's, never run, so its guards and its tools stand (issue 805). + // machine's client fills the file with, and the grant file still gives the consumers not moved + // (issue 937, 1332). Retirement is the harness's, never run, so its guards and its tools stand (issue 805). h = movedHarness(os.Getenv, provisioner{clients: OidcClients{KC: kc, Realm: realm}, guard: guard, announce: announce, log: logStderr}) run, p, bus, err := moved(consumers, h, issuer) if err != nil { @@ -96,10 +96,12 @@ func main() { } // movedHarness is the harness the moved path shares with the SDK's helper: what main wires together, pulled out so -// it can be built and inspected without starting the process (novox/hq issue 1332). +// it can be built and inspected without starting the process. Receives is MESH_RECEIVES, read exactly as the grant +// path reads it (novox/hq issue 937), so the grant file still gives every consumer not moved (novox/hq issue 1332). func movedHarness(getenv func(string) string, adapter harness.Adapter) *harness.Harness { return &harness.Harness{ Resource: ProvisionName, + Receives: getenv("MESH_RECEIVES"), Adapter: adapter, Log: logStderr, Announce: announce, diff --git a/modules/keycloak/cmd/keycloak-provider/moved.go b/modules/keycloak/cmd/keycloak-provider/moved.go index b3b6d1b1..12fec0a7 100644 --- a/modules/keycloak/cmd/keycloak-provider/moved.go +++ b/modules/keycloak/cmd/keycloak-provider/moved.go @@ -43,10 +43,16 @@ func valuesOf(e provider.Entry) map[string]any { // moved is keycloak handed to the provisioner: the SDK's moved path (harness.Moved) answering its consumers, and the // harness (never run) whose retirement and tools it shares. What differs from postgres is only this declaration // (issue 849). +// +// **A consumer not moved is still the grant file's** (issue 937, ADR 0349 clause 17, fixed here by issue 1332): +// only a moved consumer's plan names keycloak as its provider, so the controller still gives every other consumer +// through keycloak's grant file (MESH_RECEIVES) until R1 (issue 682) — mesh-mail-web, grafana and car-hunter among +// them. Each client it gives is made and checked by the harness's grant pass exactly as on the grant path; a client +// a plan names is the helper's alone. func moved(consumersFile string, h *harness.Harness, issuer string) (*harness.Moved, *provider.Provider, provider.Bus, error) { return harness.NewMoved(consumersFile, h, harness.MovedSpec{Module: "keycloak", Provision: ProvisionName, Offer: provider.Offer{Credential: provider.PerConsumer, Serves: servedValues(issuer)}, Login: func(e provider.Entry) string { return e.As }, Values: valuesOf, - Noun: "client id", Made: "client", Backend: "Keycloak", WithGrants: false}) + Noun: "client id", Made: "client", Backend: "Keycloak", WithGrants: true}) }