The apikey plugin provides API key management and authentication for Authsome. It generates cryptographically secure API keys, supports key scoping and permissions, handles key rotation and revocation, and contributes an authentication strategy that evaluates API keys in the Authorization or X-API-Key header.
Setup01
import (
"github.com/xraph/authsome"
"github.com/xraph/authsome/plugins/apikey"
)
eng, err := authsome.NewEngine(
authsome.WithStore(store),
authsome.WithPlugin(apikey.New(apiKeyStore, apikey.Config{
PathPrefix: "/v1/auth/keys",
MaxKeysPerUser: 10,
DefaultExpiry: 90 * 24 * time.Hour,
})),
)Configuration02
| Option | Type | Default | Description |
PathPrefix | string | "/v1/auth/keys" | HTTP path prefix for API key management routes |
MaxKeysPerUser | int | 0 (unlimited) | Maximum number of active keys per user |
DefaultExpiry | time.Duration | 0 (never) | Default TTL for newly created keys |
Implemented interfaces03
| Interface | Purpose |
Plugin | Base plugin identity ("apikey") |
OnInit | Captures Chronicle, Relay, hooks, logger, and user resolver |
RouteProvider | Registers key creation, listing, and revocation endpoints |
StrategyProvider | Contributes the API key authentication strategy (priority 100) |
API key generation04
POST /v1/auth/keys
All key-management routes require an authenticated session.
{
"app_id": "aapp_01j9...",
"name": "CI/CD Pipeline",
"scopes": ["read:users", "write:users"]
}user_id is optional and defaults to the authenticated caller. Passing a
different user_id mints a key that authenticates as that user, so it requires
the manage/apikey permission and returns 403 otherwise.
Response:
{
"id": "akey_01j9...",
"key": "ask_7f3a2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f",
"key_prefix": "ask_7f3a2b1c",
"name": "CI/CD Pipeline",
"scopes": ["read:users", "write:users"],
"expires_at": "2025-01-30T10:00:00Z",
"created_at": "2024-11-01T10:00:00Z"
}The raw key is returned only once at creation time. It is SHA-256 hashed before storage. The key_prefix (first 12 characters) is stored in plaintext for lookup.
Key format05
API keys use the ask_ prefix followed by 64 hex characters:
ask_7f3a2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0fThe ask_ prefix allows the authentication strategy to identify API keys in the Authorization: Bearer header without ambiguity against session tokens.
Key scoping and permissions06
Keys can be scoped to specific permissions:
{
"scopes": ["read:users", "write:users", "read:organizations"]
}Scopes are stored on the key and can be checked by your application logic. The plugin does not enforce scope semantics -- it stores and retrieves them.
Listing keys07
GET /v1/auth/keys?app_id=aapp_01j9...
Optionally filter by user:
GET /v1/auth/keys?app_id=aapp_01j9...&user_id=ausr_01j9...
Response:
{
"keys": [
{
"id": "akey_01j9...",
"name": "CI/CD Pipeline",
"key_prefix": "ask_7f3a2b1c",
"scopes": ["read:users", "write:users"],
"expires_at": "2025-01-30T10:00:00Z",
"last_used_at": "2024-11-15T14:30:00Z",
"revoked": false,
"created_at": "2024-11-01T10:00:00Z"
}
],
"total": 1
}The raw key is never returned in list responses. Only the prefix is shown for identification.
Key revocation08
DELETE /v1/auth/keys/:keyId
Marks the key as revoked. Revoked keys are rejected during authentication. The key record is preserved for audit purposes.
Key rotation09
To rotate a key:
Create a new key with the same scopes
Update your application to use the new key
Revoke the old key
The MaxKeysPerUser configuration prevents unbounded key accumulation.
Authentication strategy10
The API key plugin contributes an authentication strategy with priority 100 (evaluated after session-based auth at priority 0):
// The strategy checks these headers in order:
// 1. Authorization: Bearer ask_...
// 2. X-API-Key: ask_...When a request includes an API key:
The strategy extracts the key from the header
Looks up the key by prefix in the API key store
Verifies the raw key against the stored hash
Checks that the key is not revoked or expired
Updates the
last_used_attimestamp (best-effort)Resolves the associated user
Creates a synthetic session for context propagation
The X-App-ID header or app_id query parameter is required for API key authentication to scope the key lookup.
API routes11
All routes below require an authenticated session. Callers are confined to
their own keys unless they hold the manage/apikey permission.
| Method | Path | Description |
POST | /v1/auth/keys | Create a new API key (defaults to the caller) |
GET | /v1/auth/keys | List your keys; app-wide listing requires manage/apikey |
DELETE | /v1/auth/keys/:keyId | Revoke one of your keys |
Observability12
The plugin emits events for:
apikey.created-- New API key generatedapikey.revoked-- API key revoked
Events are sent to Chronicle (audit), Relay (webhooks), and the global hook bus.