From 3222e991c10d19d1f3d4654b6bd2376e018252f4 Mon Sep 17 00:00:00 2001 From: antoinetoussaint-byte <312536060+antoinetoussaint-byte@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:55:28 -0400 Subject: [PATCH] fix(conformance): the staleness probe exposes a real team the fixture names "a callee refuses what does not verify" moved the organisation's authority by granting the installed solution to a team id the suite made up (callee-probe-N). A host that validates team ids, as Accounts does, refuses it as an invalid subject id, so the case failed on a fixture reason rather than on the behaviour it names. The fixture now names the team through its own path, as Lifecycle.Team already does: UnexposedTeam, a real team of the organisation that InstalledSolution is not yet exposed to. The case stays required; an empty UnexposedTeam fails as a missing fixture. The local fixtures name "auditors", a team no person carries, since Acme's wiki already reaches finance and engineering and an already-exposed team is an idempotent no-op that moves nothing (checked: with "finance" the probe fails as "not stale"). Co-Authored-By: Claude Opus 5.5 --- libraries/conformance/go/README.md | 5 +++++ libraries/conformance/go/conformance.go | 14 ++++++++++---- .../local/code/plugins/registry_test/live_test.go | 3 +++ .../plugins/registry_test/local_authority_test.go | 3 +++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libraries/conformance/go/README.md b/libraries/conformance/go/README.md index df030e98..9402a352 100644 --- a/libraries/conformance/go/README.md +++ b/libraries/conformance/go/README.md @@ -41,6 +41,11 @@ then resumes acknowledgement. `Lifecycle.Revoke` calls the host's existing uninstall path. These hooks arrange state; the assertions use the public interfaces. No synthetic issuer or parallel permission resolver is allowed. +`UnexposedTeam` is a real team of the organization that `InstalledSolution` is +not yet exposed to, created or found by the host's own fixture. The staleness +probe exposes the installation to it to move the organization's authority, so a +host that validates team ids sees an id it issued, never one the suite invents. + The authority interface returns an advisory decision, not a hop stamp. The hop transport additionally must preserve it while forwarding: the local hop's `TestPermissivePolicyUsesTheAuthorityAdvisoryIdentity` checks the decision and diff --git a/libraries/conformance/go/conformance.go b/libraries/conformance/go/conformance.go index b52d92e0..3fe89137 100644 --- a/libraries/conformance/go/conformance.go +++ b/libraries/conformance/go/conformance.go @@ -49,6 +49,12 @@ type Fixture struct { InstalledSolution string // an active installation the viewer is entitled to InstalledCredential string // workload credential of InstalledAudience, required for installation-owned Issue InstalledAudience string // the installed solution principal; distinct from the organisation-role module Audience + // UnexposedTeam is a real team of Organization that InstalledSolution is not + // yet exposed to, named as the host's own fixture creates or finds it. The + // staleness probe exposes InstalledSolution to it, which moves the + // organisation's authority; its members keep that role for the rest of the + // run, so a team with no members is the safe choice. + UnexposedTeam string // LocalAdvisory enables the local-only advisory Check contract. LocalAdvisory bool @@ -391,12 +397,12 @@ func Run(t *testing.T, conn grpc.ClientConnInterface, descriptors []byte, f Fixt _, err := c.call(ctx, "host.authority.v1.AuthorityService", "Check", map[string]any{"token": str(short, "token"), "audience": f.Audience}) refused(t, err, codes.Unauthenticated, "expired") }) - if f.InstalledSolution == "" { - t.Fatal("required conformance fixture missing: staleness needs an installation whose grant can move") + if f.InstalledSolution == "" || f.UnexposedTeam == "" { + t.Fatal("required conformance fixture missing: staleness needs an installation and a real team it is not yet exposed to") } admin := c.must(t, ctx, "host.session.v1.SessionService", "SignIn", map[string]any{"fixture_token": f.AdminToken}) - before := c.must(t, ctx, "host.authority.v1.AuthorityService", "Check", map[string]any{"token": token, "audience": f.Audience}) - c.must(t, as(ctx, admin), "host.installation.v1.InstallationService", "GrantToTeam", map[string]any{"organization_id": f.Organization, "installation_id": f.InstalledSolution, "team_id": "callee-probe-" + str(before, "authorization_revision")}) + c.must(t, ctx, "host.authority.v1.AuthorityService", "Check", map[string]any{"token": token, "audience": f.Audience}) + c.must(t, as(ctx, admin), "host.installation.v1.InstallationService", "GrantToTeam", map[string]any{"organization_id": f.Organization, "installation_id": f.InstalledSolution, "team_id": f.UnexposedTeam}) _, err := c.call(ctx, "host.authority.v1.AuthorityService", "Check", map[string]any{"token": token, "audience": f.Audience}) if status.Code(err) != codes.PermissionDenied { t.Fatalf("a token sealed before the organisation's authority moved is stale, refused as PermissionDenied: %v", err) diff --git a/modules/authority/services/local/code/plugins/registry_test/live_test.go b/modules/authority/services/local/code/plugins/registry_test/live_test.go index c2141e5d..d230c11f 100644 --- a/modules/authority/services/local/code/plugins/registry_test/live_test.go +++ b/modules/authority/services/local/code/plugins/registry_test/live_test.go @@ -38,5 +38,8 @@ func TestARunningLocalAuthorityPassesTheSuite(t *testing.T) { Audience: "records", ReadKind: "records.records", Elsewhere: "model", WorkloadModule: "org-directory", Binding: "records", BindingAudience: "records", InstalledSolution: state.InstallationID("acme", "wiki"), InstalledAudience: "wiki", InstalledCredential: os.Getenv("AUTHORITY_SOLUTION_WORKLOAD_CREDENTIAL"), + // Acme's wiki reaches finance and engineering; a local team is the id its + // members carry, so one no person carries is a real team with no members. + UnexposedTeam: "auditors", }) } diff --git a/modules/authority/services/local/code/plugins/registry_test/local_authority_test.go b/modules/authority/services/local/code/plugins/registry_test/local_authority_test.go index 75ecc7e3..3d30ee09 100644 --- a/modules/authority/services/local/code/plugins/registry_test/local_authority_test.go +++ b/modules/authority/services/local/code/plugins/registry_test/local_authority_test.go @@ -155,6 +155,9 @@ people: Audience: "records", ReadKind: "records.records", WorkloadModule: "org-directory", WorkloadCredential: k.Credential(t, "org-directory"), Binding: "records", BindingAudience: "records", Elsewhere: "model", InstalledSolution: state.InstallationID("acme", "wiki"), InstalledAudience: "wiki", InstalledCredential: k.Credential(t, "wiki"), + // Acme's wiki reaches finance and engineering; a local team is the id its + // members carry, so one no person carries is a real team with no members. + UnexposedTeam: "auditors", SolutionTools: &conformance.SolutionToolsCase{Token: "fixture-maya", Outsider: "fixture-remi", Module: "robin", Credential: k.Credential(t, "robin"), Binding: "tools", Audience: "proposals", Kind: "proposals.item", Action: "read", Method: "/tools.Solution/Read"}, // Deliveries are signed with the kit's release key and carried by the // module's own workload under the launcher.