> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grantex.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Scopes

> Grantex scopes use the resource:action[:constraint] naming convention.

## Scope Format

Grantex defines a standard scope format:

```
resource:action[:constraint]
```

| Part | Required | Description |
| - | - | - |
| `resource` | Yes | The resource being accessed (e.g. `calendar`, `email`, `payments`) |
| `action` | Yes | The action being performed (e.g. `read`, `write`, `send`, `initiate`) |
| `constraint` | No | An optional constraint on the action (e.g. `max_500` for a payment cap) |

## Examples

| Scope | Meaning |
| - | - |
| `calendar:read` | Read calendar events |
| `calendar:write` | Create and modify events |
| `email:send` | Send emails on user's behalf |
| `payments:initiate:max_500` | Initiate payments up to \$500 |
| `files:read` | Read user files |
| `profile:read` | Read user profile |

## How Scopes Work

### At registration

When a developer registers an agent, they declare the full set of scopes the agent may ever need:

```typescript theme={null}
const agent = await grantex.agents.register({
  name: 'travel-booker',
  scopes: ['calendar:read', 'payments:initiate:max_500', 'email:send'],
});
```

### At authorization

When requesting user consent, the agent specifies which scopes it needs for this particular session. These must be a subset of the registered scopes:

```typescript theme={null}
const auth = await grantex.authorize({
  agentId: agent.id,
  userId: 'user_abc123',
  scopes: ['calendar:read', 'payments:initiate:max_500'],
});
```

### In the grant token

Approved scopes are embedded in the JWT's `scp` claim:

```json theme={null}
{
  "scp": ["calendar:read", "payments:initiate:max_500"]
}
```

### At verification

Services check the `scp` claim to decide whether to allow a request:

```typescript theme={null}
const grant = await verifyGrantToken(token, {
  jwksUri: 'https://api.grantex.dev/.well-known/jwks.json',
  requiredScopes: ['payments:initiate'],
});
// Throws if 'payments:initiate' is not in the token's scopes
```

## Scope Enforcement in Integrations

Protected framework integrations (LangChain, CrewAI, Vercel AI, etc.) first
verify the token signature and claims with the configured JWKS endpoint, then
enforce the verified `scp` claim. Current standalone verifiers may fetch JWKS on
each invocation; they do not merely trust an unverified decode.

```typescript theme={null}
// LangChain example
const tool = createGrantexTool({
  name: 'read_calendar',
  grantToken,
  requiredScope: 'calendar:read',  // checked only after JWKS verification
  func: async (input) => getCalendarEvents(input),
});
```

If the token doesn't include the required scope, the tool throws immediately — before your function runs.

## User Experience

Users see plain-language descriptions of scopes during the consent flow, not raw scope strings. Service providers define these descriptions when they register their scope definitions with Grantex.

## Scope Registry

For a complete list of standard scope definitions organized by domain (calendar, email, payments, files, and more), along with constraint patterns and custom scope guidelines, see the [Scope Registry](/concepts/scope-registry).

## Ownership

Grantex is owned by Orchestrum Technologies LLP. Inventor and owner: Sanjeev Kumar. Ownership contact: [sanjeev@orchestrum.in](mailto:sanjeev@orchestrum.in) or [mishra.sanjeev@gmail.com](mailto:mishra.sanjeev@gmail.com).

## Tool-qualified scopes

A scope may name one tool: `tool:<connector>:<permission>:<tool>` (an optional
`:capped:<N>` may follow either form; a `*` in the tool position is connector-wide,
like no tool segment). By default `enforce()` reads such a scope
as the connector permission, so `tool:acme_kyb:read:get_case` covers every read
tool on `acme_kyb`. With `toolQualifiedScopes: true` (`tool_qualified_scopes=True`
in Python) the tool segment is honoured: a tool's permission comes from the
connector-level scopes and the scopes naming that tool, and a connector whose
scopes all name other tools denies the call with `tool_not_granted` /
`tool_scope_missing`, `details.tool_scopes` listing the tools they name. The
option is off in this release and becomes the default in the next major.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.