Skip to content
agovena.
agovena.
Get started
Community

Developer guides

Authentication and token abilities

Create scoped Sanctum tokens and understand customer ownership, session authentication, and IP restrictions.

On this page

Two authentication modes

Protected customer endpoints use auth:sanctum. A request can authenticate with a personal access token in Authorization: Bearer ..., or through a supported first-party session. Core enables Sanctum's stateful API middleware. Session-based writes still need the appropriate CSRF protection; bearer-token examples do not replace the browser login flow.

Token abilities and staff permissions are different systems. A token with orders.read reads the current customer's orders, not every merchant order. The /api/v1 surface is not an Admin CRUD API. Account resources return the customer ID, which must not be confused with the underlying user ID.

Sources: API routes, middleware setup, and AccountResource.

Create a named token

POST /api/v1/auth/tokens accepts JSON:

Field Validation Meaning
email Required email Existing account email
password Required string Account password
name Required string, maximum 80 characters Recognizable integration name
abilities Optional array, maximum 50 entries Explicit ability selection
abilities.* String from the supported ability catalog Unknown values fail validation

Omitting abilities grants ['*']. Supply an explicit least-privilege list. An empty array does not request the default; it creates a token without route abilities. Including * normalizes the selection to full access.

Illustrative token-request.json, not real credentials:

json
{
  "email": "[email protected]",
  "password": "<account-password>",
  "name": "Customer order reader",
  "abilities": ["account.read", "orders.read", "tokens.revoke"]
}
bash
curl --request POST 'https://shop.example.test/api/v1/auth/tokens' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-binary @token-request.json

The 201 response is not wrapped in data:

json
{
  "token": "<plain-text-token>",
  "token_type": "Bearer",
  "name": "Customer order reader"
}

Store the returned token securely. Do not commit the request file, response, or a populated shell history. The controller returns the plain-text token only on creation. There is no refresh-token exchange in this route set.

The controller lowercases the email for lookup, checks the password hash, and rejects anonymized users. Invalid credentials produce 422 validation_error, not 401. The endpoint validates email and password only: it does not accept a two-factor code, expires_at, or an IP allowlist. Do not assume the browser's privileged two-factor flow is applied here.

Source: TokenController.

Supported abilities

Ability Protected operations
account.read GET /me
account.update PATCH /me
addresses.read GET /addresses
addresses.create POST /addresses
addresses.update PATCH /addresses/{address}
addresses.delete DELETE /addresses/{address}
orders.read Order list and detail
orders.create POST /checkout
orders.pay POST /orders/{order}/pay
invoices.read Invoice list and detail
credit_notes.read Credit-note list and detail
tickets.read Support-ticket list and detail
subscriptions.read Subscription Module API
services.read Provisioning Module API
downloads.read Digital download list and file
digital_secrets.read Digital Delivery API, including readable delivered values
event_tickets.read Events ticket list and detail
tokens.revoke Delete the current personal token
* All supported abilities

The underscore in credit_notes.read, digital_secrets.read, and event_tickets.read is intentional. It does not match the hyphenated URL spelling.

EnsureApiTokenAbility checks abilities when a bearer token is present. It does not apply personal-token scopes to a session-only request. Missing scope produces 403 insufficient_scope with errors.required_ability. Unknown Module API route-name prefixes fail closed as unmapped_api_route; declaring an arbitrary new ability in a package does not add it to Core's catalog.

Use and revoke a token

With AGOVENA_TOKEN populated securely in your environment:

bash
curl 'https://shop.example.test/api/v1/me' \
  --header 'Accept: application/json' \
  --header "Authorization: Bearer $AGOVENA_TOKEN"

curl --request DELETE 'https://shop.example.test/api/v1/auth/tokens' \
  --header 'Accept: application/json' \
  --header "Authorization: Bearer $AGOVENA_TOKEN"

Revocation requires tokens.revoke or *. It returns 200 {"ok":true} and deletes only the current personal access token. It does not delete all tokens or implement a browser logout. With session authentication and no personal token, the controller still returns ok without deleting a token.

IP policy and rate limits

The Admin token editor supports per-token IP policies. An empty policy allows any IP. The password endpoint explicitly creates an empty policy; configure restrictions through the supported token management screen rather than sending an undocumented API field. A disallowed source address receives 403 ip_not_allowed.

Proxy trust affects the source address. Core accepts explicitly configured TRUSTED_PROXIES and does not accept wildcard trust. Check the deployment's proxy chain before relying on an allowlist.

Token creation is limited to five requests per minute per IP/email combination. An additional account-level guard records incorrect credentials and blocks after ten failed attempts within its 600-second window. Protected ordinary requests use 60 per minute per user or IP; checkout and payment initiation use 10. Public catalog requests use 120 per minute per IP.

Integration tests to retain

Cover successful bearer and session authentication separately. Test missing scope, an unknown ability, self-revocation without permission, another customer's object ID, blocked IPs, and omitted abilities. Do not log credential-bearing requests while testing errors.

The source checks are ApiTokenManagementTest, StorefrontApiTest, ApiTokenAbilities, and AppServiceProvider. Continue with the endpoint reference.

Search documentation

Search guides, commands and API endpoints

What are you looking for?

Documentation