Repository navigation
feat(service-accounts): Add details page with token list, create and revoke - #130485
Draft
sentry-junior[bot] wants to merge 5 commits into
Draft
sentry-junior[bot] wants to merge 5 commits into
sentry-junior[bot] wants to merge 5 commits into
Conversation
sentry-junior
Bot
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 9, 2026 19:45
6d6b607 to
dbb4dab
Compare
sentry-junior
Bot
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 9, 2026 19:55
f06a4a8 to
3b52ff5
Compare
Contributor
|
No findings on the latest commit. |
skaasten
pushed a commit
that referenced
this pull request
Nov 10, 2026
#130483) Adds a new endpoint for listing service account tokens, gated by service account feature flag ------ Adds `GET /organizations/{org}/service-accounts/{id}/tokens/`. This is the first of the small token endpoint PRs, one per endpoint. It's stacked on #130456, which adds token generation: 1. **List tokens (this PR)** 2. Create a token: #130507 3. Revoke a token: #130508 The endpoint runs in control, is private, and is gated on `organizations:service-accounts` like the other service account endpoints. It needs `service_account:read`. It returns the account's active tokens, newest first: `id`, `name`, `scopes`, `tokenLastCharacters`, `dateCreated`, `dateLastUsed`, `dateExpires`. Revoked tokens aren't listed, and the response never includes a token's value. Pagination works the same way as the service account list. The account in the URL must be active and in the URL's org, otherwise it returns 404. Only a person signed in as themselves can call it. A service account gets 403 `user-required` (`requires_user`). The account lookup from the details endpoint moved into a shared `ServiceAccountScopedEndpointBase`. The details endpoint behaves the same. The new URL is added to `static/app/utils/api/knownSentryApiUrls.generated.ts`, so the frontend PR (#130485) can type-check against it. <!-- junior-request-attribution:start --> via @skaasten. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:slack%3AC0CA89MBDQB%3A1793911581.772709 --> -- [View Session](https://junior-prod.sentry.dev/conversations/slack%3AC0CA89MBDQB%3A1793911581.772709) [[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC0CA89MBDQB%3A1793911581.772709/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
sentry-junior
Bot
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 12, 2026 20:11
07a85cd to
1a9b971
Compare
…revoke Link each service account to a details page that shows its permissions and project access, lists its active tokens, and lets managers revoke them or create new ones. A new token is shown once in the same modal org auth tokens use, then the page returns to the details view. Co-Authored-By: Shaun Kaasten <900809+skaasten@users.noreply.github.com>
…n the token form Match the create service account form: pick token scopes with the searchable multi-select, limited to the account's own scopes, and read validation errors from the response's detail object as the token endpoints return them. Co-Authored-By: Shaun Kaasten <900809+skaasten@users.noreply.github.com>
master moved Confirm into the scraps package (#130251), and CI builds this stack merged with master.
Frontend half of the service account token endpoints in #130483, split out because frontend and backend deploy separately. It lands first: the patterns are harmless before the backend routes exist, and #130483's test_no_missing_urls passes once this is in. Co-Authored-By: shaun.kaasten <900809+skaasten@users.noreply.github.com>
The New Token form gets an Expiration select: 30 (default), 60 or 90 days, a custom date, or no expiration with a warning. The token list gets an Expires column, and expired tokens show an Expired tag.
skaasten
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 12, 2026 22:08
1a9b971 to
18d078d
Compare
sentry-junior
Bot
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 12, 2026 22:11
18d078d to
967e1ba
Compare
sentry-junior
Bot
force-pushed
the
feat/service-accounts-tokens-ui
branch
from
November 12, 2026 22:11
967e1ba to
18d078d
Compare
skaasten
added a commit
that referenced
this pull request
Nov 13, 2026
…ens (#130508) Adds `DELETE /organizations/{org}/service-accounts/{id}/tokens/{token_id}/`. This is the last of three small token endpoint PRs, one per endpoint: 1. List tokens: #130483 2. Create a token: #130507 3. **Revoke a token (this PR)** The endpoint needs `service_account:write`. It locks the token row, sets `date_deactivated` and saves it, so the token's outbox updates the replica in the org's cell. It returns 204. The token must belong to the account in the URL, and the account must be active and in the URL's org. Otherwise, or if the token is already revoked, it returns 404. It uses the same guards as create: only a person signed in as themselves can call it, and Seer agent tokens and impersonation sessions are refused. Each revoke writes a `SERVICE_ACCOUNT_TOKEN_REMOVE` (227) audit log entry. Its data holds the token name, scopes and account, never the token or its hash. The settings UI's Revoke button in #130485 calls this endpoint. **Tests:** the revoke test drains the token's outbox and checks that the cell's `ServiceAccountTokenReplica` gets the token's new `date_deactivated`. This works because #130265, the token replication handler, is merged. <!-- junior-request-attribution:start --> via @skaasten. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:slack%3AC0CA89MBDQB%3A1794494200.498819 --> -- [View Session](https://junior-prod.sentry.dev/conversations/slack%3AC0CA89MBDQB%3A1794494200.498819) [[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC0CA89MBDQB%3A1794494200.498819/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: Shaun Kaasten <900809+skaasten@users.noreply.github.com>
This branch was successfully deployed
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.
Stacks on #130140. Adds the service account details page and token management to Settings.
/settings/:orgId/service-accounts/:serviceAccountId/. The page loads the account from the existing detail endpoint and shows its permissions, project access and created date. Editing or deleting the account is out of scope here.sntrym_************abcd), a scopes summary, the created date, the last used date ("Never" when null), and the expiration date ("Never" when null, with an Expired tag once it has passed). Each row has a Revoke button with a confirm step. After a revoke, the list refetches..../tokens/new/. The form has a required name and the same searchable permission scope multi-select as the create service account form, limited to the account's own scopes and all selected by default.expiresAtas an ISO timestamp, ornullfor no expiration.displayNewTokenmodal (copy input plus a "won't be shown again" warning), and closing the modal returns to the details page. Field errors in the response'sdetailobject (name,scopes,expiresAt) show on their fields. A stringdetailshows as a toast.service_account:write. The tooltip matches the list page's create button.controlsiloUrlPatterns.tsso the frontend sends them to the control silo.Depends on the backend token endpoint PRs, one per endpoint and stacked on #130456: list #130483, create #130507 and revoke #130508. Without them, these pages work only against mocks. The two token URLs added to
knownSentryApiUrls.generated.tshere match those PRs' generated entries.The backend PRs add the same two
controlsiloUrlPatterns.tslines, list in #130483 and revoke in #130508, sotest_no_missing_urlspasses on them. Whichever side lands second gets an identical change.via @skaasten.
--
View Session [Sentry]