Repository navigation
feat(organization): manage service accounts and API tokens, and show everything a role allows - #1917
Open
DavidCockerill wants to merge 1 commit into
Open
DavidCockerill wants to merge 1 commit into
DavidCockerill wants to merge 1 commit into
Conversation
dawsontoth
approved these changes
Oct 12, 2026
This was referenced Oct 12, 2026
…everything a role allows Settings → Authentication gains an admin-only API access section: the organization's Allow API tokens switch (off until an admin turns it on), and service accounts with their tokens (create and revoke tokens, change an account's role, disable or enable it, delete it), for central manager's service accounts (HarperFast/central-manager#576). The role dialog shows everything a role allows in central manager's terms: organization update and delete, a View/Create/Update/Delete matrix for Roles and Clusters, cluster access (all or selected clusters, exactly as clusters.resources expresses it, anything else shown as custom), and an Advanced JSON tab that shares the form's value and is validated before it can be saved or left. The Roles list stays on the shared table, with a heading. Refs #1791 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DavidCockerill
force-pushed
the
david/576-org-api-tokens
branch
from
October 13, 2026 20:22
3f8c708 to
1b951d5
Compare
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.
⊙ Problem
Central Manager is adding service accounts and their API tokens (HarperFast/central-manager#576, in HarperFast/central-manager#943): non-human members of an organization, managed by its admins, whose revocable, expiring Bearer tokens a CI pipeline uses instead of a person's password. Admins need somewhere to create the accounts, mint and revoke their tokens, and turn tokens on for the organization. Service accounts act with one of the organization's roles, and the Roles dialog didn't show what a role can actually do. Refs #1791.
💡 Solution
Settings → Authentication is now two sections: OAuth providers, and a new API access section shown only to the organization's admins (the people Central Manager lets manage it):
The token never outlives its dialog: the create mutation keeps it out of the mutation cache, the dialog can't be closed or resubmitted while a request is in flight, and it mints at most one token. A token that still arrives unseen (after navigating away, say) is revoked at once with a warning toast. Cache upkeep lives on the mutation hooks, so a page that unmounts mid-request still leaves the lists current, and a revoked token or deleted account leaves the list at once even if the refresh after it fails.
Roles keeps the shared table and gains a heading. The role dialog now shows everything a role allows, in Central Manager's own terms:
clusters.resourcesentries: View, Update and Delete apply only to the chosen clusters, while Create stays organization-wide. A role whose per-cluster entries the form can't express exactly is shown as custom and left untouched.Screenshots
Taken on the local Fabric rig at this branch's head (1280×860).
Docs: this is a user-facing feature, so a companion page in HarperFast/documentation follows (service accounts, tokens and the switch). It isn't written yet; its tracking issue needs approval first.
⚖️ Alternatives
🔧 Changes
src/features/organization/settings/index.tsxsplits Authentication into sections and renderssrc/features/organization/settings/ApiAccessSettings.tsx(admins only), which holdssrc/features/organization/settings/ApiTokensSetting.tsx(the switch) and the service accounts.src/features/organization/settings/SettingsSection.tsxis the shared bordered section.src/features/organization/serviceAccounts/ServiceAccountsSection.tsx(the list, selection, row menu) andsrc/features/organization/serviceAccounts/components/ServiceAccountTokens.tsx(the token panel), withsrc/features/organization/serviceAccounts/components/RevokeApiTokenButton.tsx,src/features/organization/serviceAccounts/components/Timestamp.tsxandsrc/features/organization/serviceAccounts/lib/timeText.ts(dates and relative times, exact time on hover).src/features/organization/serviceAccounts/modals/CreateServiceAccountModal.tsx,src/features/organization/serviceAccounts/modals/ChangeServiceAccountRoleModal.tsx,src/features/organization/serviceAccounts/modals/CreateApiTokenModal.tsx.src/features/organization/serviceAccounts/queries/serviceAccounts.ts;src/features/organization/serviceAccounts/mutations/serviceAccounts.ts,src/features/organization/serviceAccounts/mutations/createOrganizationApiToken.tsandsrc/features/organization/serviceAccounts/mutations/revokeOrganizationApiToken.ts; the types insrc/integrations/api/api.patch.d.ts.useCanManageServiceAccountsinsrc/hooks/usePermissions.ts: a super user or an admin of the organization.src/features/organization/roles/rolePermissions.tsmaps Central Manager's role to the editor's value, the JSON, and cluster access;src/features/organization/roles/components/RolePermissionsEditor.tsxis the form and Advanced JSON;src/features/organization/roles/modals/AddOrganizationRoleModal.tsxandsrc/features/organization/roles/modals/EditOrganizationRoleModal.tsxuse it;src/features/organization/roles/index.tsxadds the heading;src/features/organization/mutations/OrganizationRoleFormSchema.tskeeps only the name schema the create form needs.src/components/SimpleBrowseDataTable.tsx(the border on the container). The breadcrumb fix this branch had is now stage's own (route parameters shown as their values).✅ Verification
pnpm test: 546 files, 5402 tests pass.tsc -b,oxlintanddprint checkare clean. Every review fix was mutation-checked: removing it fails its test.src/features/organization/serviceAccounts/__tests__/ServiceAccountsSection.test.tsx(list, selection, row menu, revoke and delete leaving the list even when the refresh fails, loaded lists surviving a failed refresh) withsrc/features/organization/serviceAccounts/__tests__/selectStub.tsx;src/features/organization/serviceAccounts/modals/CreateApiTokenModal.test.tsx(one token per dialog, reveal once, the unseen-token revoke);src/features/organization/serviceAccounts/modals/CreateServiceAccountModal.test.tsx(validation, one request for a double submit);src/features/organization/serviceAccounts/components/RevokeApiTokenButton.test.tsx;src/features/organization/serviceAccounts/mutations/serviceAccounts.test.tsandsrc/features/organization/serviceAccounts/mutations/createOrganizationApiToken.test.ts(cache upkeep after unmount, the token kept out of the mutation cache);src/features/organization/serviceAccounts/lib/timeText.test.ts;src/features/organization/settings/ApiAccessSettings.test.tsx(admins only) andsrc/features/organization/settings/ApiTokensSetting.test.tsx(the switch);src/features/organization/settings/index.test.tsx(stage's OAuth provider tests, with the API access section stubbed and the renamed Add OAuth provider button);src/hooks/usePermissions.test.ts(the admin gate);src/features/organization/roles/rolePermissions.test.ts(mapping, JSON round trip and validation, all/selected/custom cluster access including per-cluster instance delete);src/features/organization/roles/modals/AddOrganizationRoleModal.test.tsxandsrc/features/organization/roles/modals/EditOrganizationRoleModal.test.tsx(defaults, payloads, selected clusters, JSON blocking, read-only admin and own role, an edit kept on the role it opened, no name error before the field is visited);src/features/organization/roles/index.test.tsx(the list).🤖 Generated by Anthropic Claude (Opus 5.5) with Claude Code; posted via @DavidCockerill.
Related PRs: #1837 independent (merged; the roles list keeps its sort, filter and paging), #1832 independent (merged), #1862 independent (merged), #1887 independent (merged; its settings test stubs this branch's API access section), #1888 independent (merged; this branch adopts its length limits), #1897 independent (merged; this branch adopts its no-verdict toasts), #1780 independent, #1896 independent, #1875 independent, #1793 independent, #1882 independent (merged; its role-dialog changes are carried into this branch's rewrite), #1891 independent (merged; likewise), #1899 independent (merged), #1868 independent (merged), #1898 independent (merged)
Complexity: medium
Review-Coverage: authored=claude; ran=gemini,codex; adjudicated=domain; declined=cursor-grok,cursor-composer,cursor-kimi,cursor-muse; rounds=12; full=3 @ 1b951d5
Review-Attention: study ~20m (critical: OrganizationRoleFormSchema.ts; decisions: role-editor-snapshot, role-field-whitelist, unseen-token-revoke, api-access-admin-only, do-less-alternative) @ 1b951d5