Skip to content

[Discussion] Support for Scoped API Tokens / Permission-Bound API Keys #49

@HashGateApp

Description

@HashGateApp

Background

Right now, API tokens are typically “all or nothing,” inheriting the full access of the underlying user. Adding scoped API tokens would allow tokens to be restricted to specific actions or resources, improving security for programmatic access and external integrations.

This thread aims to clarify:

  • how scopes should be represented,
  • how they interact with team-based permissions,
  • and how they should be stored and enforced.

User Stories

  • As a developer, I want to issue API tokens with specific scopes so my users can programmatically access only the parts of the API they need.
  • As an end user, I want to generate API tokens that are limited in capability and safe to expose to third-party integrations.
  • As an administrator, I want visibility into scopes, what they represent, and which tokens have which scopes.
  • As the system, I want a consistent way to enforce scopes at the middleware/policy/gate level, regardless of whether the actor is a user or a token.

Open Questions

1. How should we handle scenarios where a model that extends the Illuminate\Foundation\Auth\User type and is used as the authenticated source?

In some flows, the authenticated actor extends the Illuminate\Foundation\Auth\User model rather than the default App\Models\User model. This raises questions:

  • Should scope/permission evaluation always be normalized to the underlying Illuminate\Foundation\Auth\User model before evaluating team permissions?
  • Should scoped tokens be allowed to act as their own “team actor” (e.g., token -> team relationship) independent of a user?
  • How does this impact the evaluation chain in policies like:
    token scopes -> team membership -> team permissions -> resource ownership?

2. Where should scoped permissions be stored?

There are two main patterns to consider:

Option A: Store scopes directly on the issued token

Example: a JSON column on the token such as:

["teams.view", "teams.users.view", "charges.create"]

Option B: — Treat the token as a permissioned entity within the team

This approach creates a team association for the token model (e.g., TeamToken, HasTeam-like trait) and grants it permissions using the same mechanism used for users.

Things to consider

  • Should scopes be stored directly on the token, or modeled using the existing team permission system?
  • Do we need a unified Actor interface that both Users and Tokens implement?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions