Skip to content

[UX] Fine-grained PATs

Background

Personal Access Tokens (PATs) in GitLab is currently grant overly broad permissions, preventing organizations from following the Principle of Least Privilege (PoLP). To address this:

  • We will enable users to create and manage PATs with granular permissions and resource-specific scope (targeting only the required repositories, projects, or resources).

Organizations with existing broad-access PATs will need a smooth path to transition to these new, appropriately scoped tokens without disrupting their workflows.

Problem overview

Current state of PATs, problem areas and success metrics from &18177 -

  • Overly Broad Permissions: PATs currently operate with coarse-grained scopes like read_api or api that grant extensive access across GitLab's entire feature set, violating the principle of least privilege.
  • Large Blast Radius: When a PAT is compromised, attackers gain access to all resources the user can access across all groups and projects they're a member of, potentially exposing sensitive data and operations across an entire organization.
  • Limited Resource Specificity: Users cannot create tokens that are restricted to specific projects, groups, or resource types, forcing them to choose between functionality and security.
  • Namespace-Wide Access: PATs automatically inherit access to all groups and projects the user belongs to, with no mechanism to restrict token access to only necessary resources.

Success metrics

  • Adoption: 50% of new PATs use fine-grained permissions model within 6 months of GA
  • Developer Experience: 85% satisfaction score in post-launch feedback

UX evaluation

  • View journey mapping here
User definition
  • System administrators: decides on policies that shape the system, balances security with developer productivity, respond and react to security incidents
  • Solo developers: working on personal or small projects, limited collaboration
  • Open source contributor: contributes to multiple projects across multiple organizations
  • Freelance developer: works with multiple clients and often granted with temporary access
  • DevOps or Platform Engineer: manages pipelines, scales infrastructure for teams and will use service accounts to automate workflows
  • Enterprise User: assumes stricter more regulated industry with strict token use policy
Core jobs
  • As a user, I want to create a Personal Access Token (PATs) with the least permissions I need to do my job in a given resource. What user wants to accomplish with PATs:
    • Authenticate programmatically: access API, authenticate pipelines
    • Maintain Git access: I need to clone/push to repositories while 2FA is enabled
    • Integrate external/third part tools: I need Jira/Jenkins/tool to access our GitLab projects
  • As a user, I want to create a PAT for specific service accounts to manage automated workflows, with the least permission it needs for its workflow.
  • As an admin, I want to define and enforce my company's policies for PAT use.
User journey stages for PATs
  • Need/recognition
  • Set governance
  • Create PATs
  • Use PATs
  • Maintain PATs
  • Continuous governance controls

Design and Exploration

Exploration

Below is a summary of the low fidelity exploration completed for this work to help with refining requirements, leveraged Claude for quick prototyping (Figjam board). Feedback collected from AuthZ team, SSCS PDM and @pmartinsgl.

Flow Exploration Team feedback & decisions
Admin sets access token settings on instance or top level group
  • Explored token settings for use, prefix, expiration date, limiting use to fine grained access.
  • Ideas for Post GA: Token approval for specific groups and projects
  • Discussed opportunities for location of setting for fine-grained tokens, currently in Self Managed > Admin > General Settings > Account and limit and SaaS > General Settings > Permissions and visibility
  • Discussed if moving setting under credential inventory matches user's mental model, caveat is that this is only available in Self Managed, Ultimate

Claude Prototype and expand to view image

Decisions:

  • With fine-grained permissions, users will have the option between 2 types. This setting can be made available to Admins
  • Ability for administrators to view and audit fine-grained PATs
User creates a token
  • Primary exploration here is what namespaces can be selected by user: personal projects, groups and projects they're a member of and all projects
  • And, how to help user identify appropriate resources (expect 300+): accordion style with functional groupings, templates from commonly used patterns system suggested or based on their namespace, include a search bar, and allowing user to enter API scopes with text
  • Explored how to help users rectify their token creation errors, ideas discussed: should the system generate tests for token configurations, types of error messaging, ability to edit permissions or duplicate token permissions.

Claude Prototype and expand to view image

PATs - Flow and Journey (1).png

Feedback:

  • Confusion between "scopes" vs "permissions" terminology
  • Template or Duo suggested permission based on the namespace or description could be one approach
  • Text-based scope entry considers power users and allows for easier integration with infrastructure tools
  • How will PATs UX change with service account implementation?

Questions & Decisions:

  • Will there be a limit on the number of tokens created? For now, no.
  • Can users create tokens using the permission from existing tokens? Yes, user can duplicate the permissions and scope of an existing token.
  • Explore permission grouping based on sets (internal discussion below)

We finalized 3 permission models to test:

Model Iterface Details
Permission set

Screenshot 2025-09-03 at 10.08.10 AM.png

Designs

Figma Prototype (accessible only to GitLab team members)

  • User can scope to the following group and project options (Only personal projects, All groups and projects user is a member of, Only selected groups and projects)
  • Selecting a group respects inheritance
  • Permissions are grouped into categories
  • User can select categories that includes all permissions
  • User can opt for None/Read/Read and Write
Fully granular permissions (Have it your way)

Screenshot 2025-09-03 at 11.28.28 AM.png

Designs

Figma Prototype (accessible only to GitLab team members)

  • User can scope to the following group and project options (Only personal projects, All groups and projects user is a member of, Only selected groups and projects)
  • Selecting a group respects inheritance
  • Resources are categorized but user pick and choose from a fine-grained list which permissions to include
  • User can select Create/Read/Update/Delete or Full access
Multiple scopes

Screenshot 2025-09-03 at 11.28.47 AM.png

Designs

Figma Prototype (accessible only to GitLab team members)

User can add multiple scopes, using the following:

  • User can scope to the following group and project options (Only personal projects, All groups and projects user is a member of, Only selected groups and projects)
  • Selecting a group respects inheritance
  • Resources are categorized but user pick and choose from a fine-grained list which permissions to include
  • User can select Create/Read/Update/Delete or Full access

🕵🏻 Solution Validation

We tested the 3 permission models with 13 internal and external customers:

  • Security (30% of users interviewed): Prioritize granular control, willing to accept complexity
  • General developers (46% of users interviewed): Prioritize workflow efficiency, risk with abandoning complex tools
  • Internal customer facing team members (10% of users interviewed): Dual customer/internal perspective, recognize customer's need with granular control

Which resulted in the following insights:

  • All users recognized strong value with granular permissions for Personal Access Tokens, with security personas particularly looking forward to added flexibility and meeting compliance use case.
  • Users rated permission sets highly for ease of use and confidence, while fine-grained permissions were valued more for their precise control capabilities.
  • User preferences split predictably by experience level: permission sets scored higher for ease of use among general users, while security professionals preferred fine-grained controls for compliance needs.
  • Templates, AI guidance, and search functionality are essential for bridging the complexity gap and ensuring successful adoption across different user segments with varying expertise levels.

Additional learnings:

  • Users struggled with the naming variations in fine-grained permission list
  • Users have a test and iterate workflow for permissions, indicating the need for easy token modification or preview capabilities. The inability to edit tokens after creation is a risk and will force users toward over permissioning as a safety net.
  • Users want to learn within the application rather than referencing external help. Information modals directly correlate with user confidence and should be considered essential, not optional UI elements.

📖 Dig into findings here: https://gitlab.com/gitlab-org/ux-research/-/issues/3590+

The team made a decision: Move forward with fine-grained permission model, design solution for easing complexity (via templates or some other solution in GA).

🖌️ User flow and designs

Please note that the SSOT for designs are in the 🖌️ Figma file for Granular PATs

Flow and designs Details

View fine-grained personal access token in User > Personal Access Token

🖌️ Figma link to section

Group 28.png

Specifications/Hand off details:

Nav changes

  • Rename “Access tokens” to “Personal access tokens”

Add ability to generate fine-grained token

  • User will have the ability to generate

    Group 5.png

  • Use dropdown button

  • Show simple action list with title and description

  • In GA, show badge next to fine-grained token as “Recommended”

  • In Beta, show badge next to fine-grained token as “Beta”

Table updates

  • Both fine-grained and legacy token types will be organized under the same table
  • Personal Access Token list table will only show:
  • Name (user-generated)
    • Interaction: Click to open drawer
      • Truncate to 40 characters, show ellipse
    • Description (User generated)
    • Max 80 characters, show ellipse
      • Empty: No description provided, use subtle text
    • Status
  • Status
  • Show expiration date, add badge if token is “expiring” and “expired”
    • Show last used date, user can hover on tooltip to show the date, time and timezone.
    • Date format based on user preference

User view token detail in drawer

  • For both legacy and fine-grained personal access token, drawer on the right side of screen will show token detail

Fine grained token drawer detail:

  • Drawer header: Details for [token name]
    • Available action based on token status:
    • Rotate (Default primary)
      • Revoke (Danger secondary)
      • Duplicate (Default primary)
    • If token is expired or expiring, show alert component:
    • Information alert: token expired
      • Warning alert: token expiring
    • Token background:
    • Name
      • Description
      • Expiration date
      • Last used
      • IP usage
    • Token scope
    • Group and project access
      • Group and project permissions
      • User permissions
      • Instance permissions
    • Token system information
    • Token type
      • Created date

Legacy token drawer:

  • Drawer header: Details for [token name]
    • Available action based on token status:
    • Rotate (Default primary)
      • Revoke (Danger secondary)
    • If token is expired or expiring, show alert component:
    • Information alert: token expired
      • Warning alert: token expiring
    • Token background:
    • Name
      • Description
      • Expiration date
      • Last used
      • IP usage
    • Token scope
    • Token system information
    • Token type
      • Created date

Generate fine-grained personal access token

🖌️ Figma link to section

Generate fine-grained PAT.png

When user clicks “Generate fine-grained token”

  • Show generate fine-grained token in new page
  • Update breadcrumb navigation to reflect current path
  • Pattern: Home > Personal Access Tokens > Generate Fine-grained Token
    • Make previous breadcrumb items clickable for navigation

Generate fine-grained PAT form


Section 1: Token details

  • Name
  • Description (required)
  • Max character limit: 500 characters
    • Minimum height: 3 rows
  • Expiration date, default to 365 days
  • Date picker component
    • Min value: Current date + 1 day
    • Show help text if expiration maximum is defined by administrator in settings


Section 2: Define scope - Section header

  • Add description: “Scopes set the permissions granted to your token. Add only the minimum permissions needed for your token. Learn more [here].”
  • Documentation link tbd


Tab navigation for resources

  • Resources for the main boundaries are defined by tabs: Group and project, User, Instance
  • Default active tab: "Groups and Projects"
  • Instance tab: This will only be shown to an admin user

--> Under groups and project tab content
User can define group and project access

  • Radio button group with three options:
  • "Personal projects only"
    • "All groups and projects I'm a member of"
    • “Only specific groups or projects that I'm a member of”
  • Selecting specific groups and projects" reveals additional controls for namespace entry.


--> Under all tab content
Resource and permissions Layout

  • Two-column horizontal layout
  • Left column: "Resources" (30% width)
  • Right column: "Permissions" (70% width)
  • Responsive: Stack vertically on mobile screens


Resources Selector: User can select group and project resources

  • Checklist of available resource types
  • Resources organized by category with expand/collapse
  • Each resource has information icon for description popover triggered by clicking information icon next to resource name
    • Content: Resource description and what access it provides
    • Positioning: Above of icon
    • Close: Click outside popover or clicking another icon
  • Select all/none toggle at category level
  • Visual hierarchy: Category headers bold, resources indented


Permissions Definition (Right Column): User can define permissions

  • When user selects resource, show the resource on the right column.
  • Add category
    • Add resource name
    • Add description of resource (limit to 2 lines)
    • Use ellipse and tooltip hover if the text reaches 2 lines
  • Use CRUD component
  • Empty state text: “No resources selected. Search to start adding resources”
  • Dropdown per selected resource type
  • Dropdown options: Read, Write (or other CRUD combinations or verb)
    • Default selection: Select permission


--> Button specifications

  • Primary: "Generate token" (blue, enabled only when form is valid)
  • Secondary: "Cancel" (outlined, returns to token list)
  • Button spacing: 8px between buttons
  • Loading state: Show spinner and disable during token generation
  • Sticky form actions at bottom of viewport on scroll

Form validation


Real-time validation

  • Specific project and group access: must be valid namespace
  • Error states: Red border, error icon, error message below field

Validation at submission

  • Name: Required, 1-255 characters, alphanumeric + hyphens/underscores only
  • Description: Required, 1-500 characters
  • Expiration: Required, must be future date, within admin limits
  • Group and project access, required
  • Permissions: At least one resource must be selected with permissions defined

Loading and success states

  • Disable all form inputs during generation
  • Show loading spinner on "Generate token" button

Success state

  • Redirect to token detail view after successful generation
    • Show success alert with token entry in list
    • Token value displayed prominently with copy-to-clipboard functionality
  • Validation errors
  • Show error alert at top of form when no permissions are defined
    • Show validation under each dropdown "Permission must be selected"
  • System errors: how error alert at top of form
    • Preserve user input when possible
    • Clear error message when user begins correcting the issue

Mobile Responsive Behavior

  • Resource/permission columns stack vertically

Email notification system

  • Automatic email sent to user after token revocation
  • Email subject: "A fine-grained personal access token has been created"
  • Email content includes token name and GitLab branding and footer

Manage fine-grained personal access token

Token revocation

  • Modal triggered from "Revoke" button in token drawer or table actions
  • Modal header: "Revoke [token type]?"
  • Modal content - warning message: " Are you sure you want to revoke the token [token type]? This action cannot be undone. Any tools that rely on this token will no longer have access to GitLab."
  • Modal actions:
  • Primary button: "Revoke" (danger styling - red background)
    • Secondary button: "Cancel" (outlined styling)
    • Button spacing: 16px between buttons

Revocation confirmation states

  • Loading state during revocation, disable both modal buttons
    • Show spinner on "Revoke" button
    • Prevent modal dismissal during processing
  • Success confirmation - close modal immediately after successful revocation
    • Show success toast notification: "[Token name] revoked successfully."
    • Update token status in table and drawer to "Revoked"

Token list updates after revocation

  • Personal Access Token table updates:
  • Revoked token remains in table with updated status
    • Status column shows "Revoked" badge (gray background)
    • Remove expiration date
    • Token name becomes non-clickable (no drawer interaction)
    • Sort revoked tokens to bottom of table
  • Token counter updates - decrease active token count in page header

Email notification system

  • Automatic email sent to user after token revocation
  • Email subject: "Your fine-grained personal access token has been revoked"
  • Email content includes: token name that was revoked

Error handling for failed revocation

  • Show error alert within table
    • Error message: "Token revocation unsuccessful. Please try again."
    • Allow alert dismissal via X button

Manage fine-grained personal access token:

Token rotation modal

  • Modal triggered from "Rotate" button in token drawer or table actions
  • Modal header: "Rotate [token type]?"
  • Modal content - warning message: "Are you sure you want to rotate the token Test-token? This action cannot be undone. Any tools that rely on this token will no longer have access to GitLab."
  • Modal actions: Primary button: "Rotate" (confirm styling - blue background), Secondary button: "Cancel" (outlined styling), Button spacing: 16px between buttons

Rotation confirmation states

  • Loading state during rotation, disable both modal buttons:
    • Show spinner on "Rotate" button
    • Prevent modal dismissal during processing
  • Success confirmation: close modal immediately after successful rotation

Token list updates after rotate

  • Personal Access Token table updates:
  • Rotated token remains in table with updated “Last used:”


Email notification system

  • Automatic email sent to user after token rotation
  • Email subject: "Your fine-grained personal access token has been rotated"
  • Email content includes: token name that was rotated

Error handling for failed rotation

  • Show error alert on top of page: Error message: “Token rotation unsuccessful. Please try again."
    • Allow alert dismissal via X button

Manage fine-grained personal access token:

Token duplication modal

  • Modal triggered from "Duplicate" button in token drawer or table actions
  • Modal header: "Duplicate 'test-token'?"
  • Display original token name in quotes
  • Modal content:
  • Information message: "Duplicating a token routes you to a form to generate a new token with the same permissions and settings as the original. Once in the form, you can add the new token name, description and update permissions"
    • Note: "Once generated, the original token will remain unchanged and both tokens will work independently."
  • Modal actions: Primary button: "Duplicate and update token details" (blue background), Secondary button: "Cancel" (outlined styling), Button spacing: 16px between buttons

Generate fine-grained token form (pre-populated)

  • Navigate to generate fine-grained token page after modal confirmation
  • Breadcrumb navigation: Home > Personal Access Tokens > Generate Fine-grained Token
  • Form pre-population from original token with name field: "[Original token name] - Copy" (editable)
    • Description field: Empty
    • Expiration date: Default to 365 days from current date (not original expiration)

Define scope section

  • Group and project access:
  • Pre-fill original token's access level selection
    • If "Specific groups and projects" was selected, pre-populate with same namespaces
    • Selected items appear as removable tags in namespace selector
  • Resources selector - Pre-check all resource types that were selected in original token
  • Permissions definition - Auto-populate permission dropdowns with same CRUD settings as original
    • Maintain same permission levels (Read, Write, etc.)

Form validation and generation

  • Form validation rules: Same as original token generation
  • Name: Required, unique (auto-append number if duplicate exists)
    • Description: Required, 1-500 characters
    • Expiration: Required, must be future date, within admin limits
    • Permissions: At least one resource must be selected with permissions defined
  • Generation process: show loading spinner on "Generate token" button. Disable all form inputs during generation

Success state and confirmation

  • Redirect to table view after successful generation
  • Success messaging - show success alert
    • Display new token value prominently with copy-to-clipboard functionality
    • Show alert: "Make sure you save your token - you won’t be able to access it again"
  • Token list updates
  • Add new token to Personal Access Token table
    • Sort new token to top of list (most recent)
    • Update token counter in page header

Original token preservation

  • Original token status: Remains unchanged and active
  • Original token permissions remain intact
    • Original expiration date unchanged
    • Original usage statistics preserved

Error handling

  • Show error alert at top of page
    • Error message: "Unable to create duplicate token. Please try again."
  • Permission conflicts - If original token had permissions that are no longer available, show warning
    • Allow user to modify and review permissions before generation

Admin can view access and permissions under scope in credential inventory

Group 25.png

Self Managed --> Credential Manager

  • Under scope for fine-grained token:
  • Permissions: [permission]_[resource]
    • Access: Group A, Group B, Project C

For SaaS --> Credential Manager

  • Under scope for fine-grained token on Enterprise Users:
  • Permissions: [permission]_[resource]
    • Access: Group A, Group B, Project C

Next steps


Resources
UX project plan

Note: This work is interlocked for FY26Q4

  • Finalize scope (MR for beta/ga breakdown: https://gitlab.com/gitlab-com/content-sites/internal-handbook/-/merge_requests/7366)
  • Define user, use cases, journey
  • Map out user flows
  • Generate low-fidelity mocks for team feedback: Jul 25, 2025
  • Align on validation areas: Aug 1, 2025
    • Permission sets and advanced mode
    • Adoption risk and migration risk
  • High fidelity mocks and usertesting plan Aug 15, 2025
  • Validation from Aug 29, 2025 to Sep 19, 2025
  • Share validation summary Sep 22, 2025 with product decision on Sep 23, 2025
  • Handoff by %18.5
Edited by Ilonah Pelaez