Repository navigation
[6.x] Add a Tokens screen for Passport personal access tokens - #20155
Merged
Merged
Conversation
Users create personal access tokens with the scopes they choose, behind an elevated session, and revoke them along with the apps they've authorized. APIs offer scopes by registering a ScopeGroup with PersonalAccessTokens, which adds them to Passport::tokensCan(). The screen is hidden until a group offers the user at least one scope.
📚 Storybook previews@craftcms/ui — open Storybook No changed components detected in this Storybook. resources/js — open Storybook No changed components detected in this Storybook. |
riasvdv
approved these changes
Oct 29, 2026
Contributor
The Tokens, Passkeys, and Addresses screens repeated the page title as an h2. On Tokens, the empty status region took its own grid gap, pushing the table away from the intro text, and the empty table message had no padding. Amp-Thread-ID: https://ampcode.com/threads/T-01a187ab-db62-7282-912a-e7fb7691bea0 Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-5834f157-5515-4cdf-8d3d-71e4c0bfc685 Co-authored-by: Amp <amp@ampcode.com>
Member
Author
|
Good call, done. |
Scopes now sit in one field with a group per API. The Tokens table gains a Type column and an action menu with Edit and Revoke, and the edit modal shows only the scopes a token has, along with its expiration date. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-ae777030-d792-49ae-8853-87e83195c88f
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
Adds My Account → Tokens, the Craft 6 version of the Tokens screen in 5.12's authenticated GraphQL work (#20147). Users create Laravel Passport personal access tokens with the scopes they choose, and can revoke those tokens and the apps they've authorized.
HasApiTokens::createToken(), through the clientClientRepository::personalAccessClient()returns. If that client doesn't exist yet, it's created withcreatePersonalAccessGrantClient(). Passport has no per-token expiry, socreate()setsPassport::$personalAccessTokensExpireInfor the call and restores it afterward.PersonalAccessTokenFactorybuilds its authorization server, and reads the expiry, each time it's resolved, so other requests aren't affected.ScopeGroup(handle, label, scopes, and an optionaluserScopesclosure) withPersonalAccessTokens::registerScopeGroup(), followingUserPermissions::registerPermissionGroup(). Registered scopes are added toPassport::tokensCan()after boot. Existing Passport scopes are kept, and an application's own description wins (per.ai/rules/auth-mcp-providers.md).provider = 'craft'. That's the clientpersonalAccessClient('craft')finds here, so tokens created in 5.12 show up on this screen and keep working after an upgrade.Evidence
tests/Feature/Http/Controllers/User/PersonalAccessTokensControllerTest.php(9 tests):myaccount/tokensreturns 403.userScopesclosure limits the scopes offered.auth:craft-mcproute. They get the chosen 7- or 365-day expiry, Passport's default (1 year) is restored afterward, and both share onepersonal_accessclient.mcp:read) alone.Also run:
6.xhere too), and SQLite backup tests fail for lack of thesqlite3CLI.tests-adapter): 772 passed.vp lint/vp fmton the new page all pass.I also checked the screen in the workbench with a temporary
graphqlscope group: empty state, New token modal, validation errors, the created token, and revoking a token.Related issues