Expose a per-instance my/routes authorization manifest#5538
Open
WilliamBZA wants to merge 8 commits into
Open
Conversation
ramonsmits
reviewed
Jun 17, 2026
fab6197 to
8b27f70
Compare
The /api/my/permissions/all endpoint serializes PermissionsDescriptor whose Permissions property is IReadOnlySet<string>. System.Text.Json cannot deserialize into an interface, so the acceptance tests that read the response back threw NotSupportedException. Introduce a shared PermissionsResponse DTO with a concrete HashSet<string> and use it from both When_my_permissions_are_requested and When_role_based_authorization_is_disabled. The production API contract (IReadOnlySet) is unchanged.
1d5fc10 to
3218b8b
Compare
ramonsmits
added a commit
that referenced
this pull request
Jun 26, 2026
Alternative to #5538. Instead of leaking internal permission strings to ServicePulse, expose the concrete set of API routes the caller is allowed to reach, so the UI gates on a stable route contract rather than coupling to the permission catalogue. - Project the ASP.NET EndpointDataSource into a route⇒permission table and resolve per-request effective permissions, filtering the manifest to the routes the caller can reach. - Add the my/routes controller (served by every instance), route template normalization, and the manifest DTOs. - Remove the my/permissions endpoint, MeController, PermissionsResponse and the root-doc permission fields. - Add an admin role (read-all + manage config/admin-area resources, no message-triage write actions), sitting between reader and writer. - Acceptance, infrastructure and approval tests for the new surface, plus an anti-drift policy guard.
Instead of leaking internal permission strings to ServicePulse, expose the concrete set of API routes the caller is allowed to reach, so the UI gates on a stable route contract rather than coupling to the permission catalogue. - Project the ASP.NET EndpointDataSource into a route⇒permission table and resolve per-request effective permissions, filtering the manifest to the routes the caller can reach. - Add the my/routes controller (served by every instance), route template normalization, and the manifest DTOs. - Remove the my/permissions endpoint, MeController, PermissionsResponse and the root-doc permission fields. - Add an admin role (read-all + manage config/admin-area resources, no message-triage write actions), sitting between reader and writer. - Acceptance, infrastructure and approval tests for the new surface, plus an anti-drift policy guard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
GET /api/my/routes, served by every instance (Primary, Audit, Monitoring). It returns the concrete set of API routes the current token is allowed to call, as[{ "method", "urlTemplate" }]entries.This is the authorization contract between ServiceControl and clients (ServicePulse): each instance advertises only the routes it actually serves and the caller is actually permitted to reach. The client matches its outgoing requests against that set and never learns ServiceControl's internal
instance:resource:actionpermission vocabulary.Also in this PR
adminrole betweenreaderandwriter: read-all plus full management of config/admin-area resources (licensing, notifications, redirects, throughput, connections), but not the message-triage write actions (retry/edit/archive/restore). Roles are wildcard patterns expanded once into frozen sets for O(1), allocation-free per-request checks.