feat: API token management in workspace settings#10624
Open
dnplkndll wants to merge 414 commits into
Open
Conversation
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
… into staging-new
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
This reverts commit 3d469f0.
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
370a096 to
cf87e38
Compare
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
…nto staging-new
…nto staging-new Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Add UI and backend support for creating, listing, and revoking API tokens scoped to workspaces. Includes owner-level workspace token visibility, OpenAPI documentation, Mongo/Postgres persistence, and i18n translations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com>
Embed apiTokenId in JWT extra field and add a per-token revocation cache (60s TTL) in the transactor REST handler. Revoked tokens are now rejected within ~60 seconds instead of remaining valid until JWT expiry. Adds checkApiTokenRevoked account service method for the transactor to query individual token revocation status. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com>
Add coarse-grained scope enforcement for API tokens. Tokens can now be created with scopes ['read:*'], ['read:*','write:*'], or ['read:*','write:*','delete:*']. Existing tokens without scopes retain full access (backward compatible). - DB: v26 migration adds scopes TEXT[] column to api_tokens - Types: add scopes field to ApiToken and ApiTokenInfo - Operations: createApiToken accepts/validates/persists scopes, embeds in JWT via extra.scopes - Enforcement: withSession checks scopes against method; tx handler additionally requires delete:* for TxRemoveDoc - Client: createApiToken signature accepts optional scopes param - UI: scope preset dropdown in create popup (default: Read Only), permissions column in token list with i18n labels - Also fixes 3 pre-existing TS2322/TS2345 errors in operations.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com>
- scopes.test.ts: 8 tests for hasScope() and getRequiredScope() logic - apiTokenScopes.test.ts: 7 tests for createApiToken scope validation (valid scopes, multiple scopes, no scopes backward compat, invalid format rejection, empty array rejection, domain-scope rejection) and listApiTokens scopes inclusion - Export hasScope/getRequiredScope from rpc.ts for testability Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com>
…tting - Restrict API token creation/revocation to AccountRole.User or higher (guests cannot use API tokens), per reviewer suggestion - Add 5 missing translation keys (ApiTokenPermissions, ApiTokenScopePreset, ApiTokenScopeReadOnly, ApiTokenScopeReadWrite, ApiTokenScopeFullAccess) to all non-en locale files to fix locale parity CI test - Fix prettier formatting in apiTokenScopes.test.ts - Rename local `extra` to `tokenExtra` in createApiToken to avoid shadowing the decoded token's `extra` field Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com>
- rpc.ts: use system service token for checkApiTokenRevoked so the revocation check is not coupled to the user's potentially-revoked bearer token; systemAccountUuid + service:'server' ensures account service always accepts the call - ApiDocsSection.svelte: derive transactor base URL from login.metadata.LoginEndpoint (set on auth) instead of window.location.origin, which is not necessarily the transactor host - ApiTokenCreatePopup.svelte: replace manual translate() calls and themeStore language watch with DropdownLabelsIntl + DropdownIntlItem[], which handle i18n automatically; error state is now IntlString - General.svelte: remove legacy GenerateApiToken button, handler, and ApiTokenPopup import in favour of the new ApiTokens settings panel Signed-off-by: Don Kendall <kendall@donkendall.com>
Signed-off-by: Don Kendall <kendall@donkendall.com>
Signed-off-by: Don Kendall <dkendall@ledoweb.com>
Signed-off-by: Don Kendall <dkendall@ledoweb.com>
e0e0743 to
a3a8019
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.
Summary
api_tokenstableread:*,write:*,delete:*with server-side enforcementcreateApiToken,listApiTokens,revokeApiTokenaccount service RPC methodsChanges
Backend (
server/account/):ApiTokentype withscopes?: string[]+apiTokenDB collectionapi_tokenstable; V26 migration:scopes TEXT[]columnAccountMethodsandgetMethods()createApiTokenvalidates scopes, embeds in JWTextra.scopes, persists to DBAccountClientinterface + implementation extended with optionalscopesparamScope Enforcement (
pods/server/src/rpc.ts):withSession()checksdecodedToken.extra.scopesagainst method requirementsread:*required for find-all, search, load-model, accountwrite:*required for tx (create/update), domain requests, ensure-persondelete:*additionally required forTxRemoveDoctransactionsFrontend (
plugins/setting-resources/):ApiTokens.svelte— workspace settings page with permissions column (i18n)ApiTokenCreatePopup.svelte— creation modal with scope preset dropdown (default: Read Only)WorkspaceSettingCategoryin the modelAlso:
operations.tsTest plan
Ref: #10622
🤖 Generated with Claude Code