SIGNALS Documentation
API Reference

Ability Registry

Contract for registering API token abilities, their labels, and their grouped discovery metadata.

Overview

App\Services\Api\AbilityRegistry is catalogue and token-management UI infrastructure for personal-access-token abilities. Its metadata feeds the admin API-token interface; it does not enforce Sanctum endpoint authorization.

Core binds it as a singleton in AppServiceProvider and seeds it from CoreAbilityDefinitions::all(). The shipped catalogue is intentionally large, so this page documents the registration contract and discovery helpers rather than copying the full ability list.

Controllers enforce their explicit ability strings through the current Sanctum token. Registering metadata here makes an ability discoverable to token-management callers, but does not make an endpoint require that ability.

Public surface

Method Purpose
register() Register one ability definition by key
registerMany() Register multiple ability definitions atomically
get() Return one ability definition or null
all() Return the full keyed map of registered abilities
groups() Return grouped discovery metadata for the UI
labels() Return a flat key => label picker map
has() Check whether an ability key is registered

This metadata registry does not publish a separate registered-value interface. Its current framework contract is the typed public surface on this page plus the documented registration shape and runtime behavior below.

Accepted registration shape

Each ability is registered under a unique string key such as catalogue-items:read or webhooks:manage.

The accepted definition shape is:

[
    'label' => 'Read catalogue items & catalogue item groups',
    'description' => 'Read catalogue items & catalogue item groups', // optional
    'group' => 'catalogue-items', // optional
]

The array shape above is the PHPDoc and static-analysis contract: label is required, while group and description are optional strings. At runtime the registry only validates duplicate keys. It does not reject empty metadata strings, so empty label, group, or description values are stored unchanged. Callers remain responsible for supplying the documented types; missing required keys or incompatible values fail through ordinary PHP or downstream consumer behaviour rather than a registry validation exception.

If description is omitted, the registry stores the label again as the description. If group is omitted, the registry derives it from the part of the key before the first :.

Identity, collisions, and grouping

Ability identity is the registry key itself. Keys are unique.

  • register() throws InvalidArgumentException when the key is already present.
  • registerMany() performs the duplicate guard before mutating state, so a collision leaves the registry unchanged.

groups() sorts group buckets alphabetically by group key. Each bucket exposes a human-readable group label plus a keyed abilities map for UI discovery. Ability entries preserve registration order within each group; all() and labels() also preserve overall registration order.

Current core registrations and discovery guidance

Core seeds the registry from CoreAbilityDefinitions::all() inside AppServiceProvider.

Representative shipped abilities include:

Ability Group Current purpose
catalogue-items:read catalogue-items Read catalogue item and catalogue item group resources
catalogue-items:write catalogue-items Create and update catalogue item resources
settings:read settings Read settings through the API
settings:write settings Update settings through the API
webhooks:manage webhooks Manage outbound webhooks

Use the registry helpers instead of hard-coding the full catalogue:

  • labels() feeds the flat token ability picker in resources/views/livewire/admin/settings/api.blade.php
  • groups() feeds the grouped token-management UI
  • all() exposes the current keyed definitions when you need exact metadata

Lookup behavior

  • get($key) returns the normalized definition array or null
  • has($key) is the guard for optional lookups
  • all() returns the full associative map keyed by ability

The registry does not provide a throwing lookup method. Callers are expected to guard with has() or tolerate null.

Runtime consumption

The current framework uses this registry in the API token settings UI:

  • labels() provides the flat ability catalogue.
  • groups() provides grouped labels and options for creating and editing tokens.

API controllers separately enforce strings such as settings:read, settings:write, or webhooks:manage with Sanctum's current-token ability check. That authorization path does not resolve this registry.

Worked example

This is the current shipped registration shape for a core catalogue slice:

$registry->registerMany([
    'catalogue-items:read' => [
        'label' => 'Read catalogue items & catalogue item groups',
        'description' => 'Read catalogue items & catalogue item groups',
    ],
    'catalogue-items:write' => [
        'label' => 'Write catalogue items & catalogue item groups',
        'description' => 'Write catalogue items & catalogue item groups',
    ],
]);

With that registration in place:

  • get('catalogue-items:read') returns the normalized metadata array
  • labels()['catalogue-items:read'] returns Read catalogue items & catalogue item groups
  • groups()['catalogue-items']['abilities'] exposes both catalogue-items:read and catalogue-items:write