Authsome
1.x
Docs/Authsome/Keysmith Bridge
Open

Reading4 min
Updated31 Jul 2026
Sourcev1/bridges/keysmith.mdx

The Keysmith bridge connects Authsome to the Keysmith API key management extension. When configured, all API key creation, validation, and revocation operations are delegated to Keysmith, which provides a richer feature set than Authsome's built-in API key store: rate limiting per key, scope enforcement, key rotation with grace periods, usage analytics, and multi-tenant isolation.

Interface01

The bridge.KeyManager interface is defined in github.com/xraph/authsome/bridge:

type KeyManager interface {
    CreateKey(ctx context.Context, input *CreateKeyInput) (*KeyResult, error)
    ValidateKey(ctx context.Context, rawKey string) (*ValidatedKey, error)
    RevokeKey(ctx context.Context, keyID string) error
}

type CreateKeyInput struct {
    Name        string            `json:"name"`
    Owner       string            `json:"owner"`        // User ID
    Environment string            `json:"environment,omitempty"`
    Scopes      []string          `json:"scopes,omitempty"`
    Metadata    map[string]string `json:"metadata,omitempty"`
}

type KeyResult struct {
    ID     string `json:"id"`
    RawKey string `json:"raw_key"` // Only returned on creation; store securely
}

type ValidatedKey struct {
    ID          string            `json:"id"`
    Name        string            `json:"name"`
    Owner       string            `json:"owner"`
    Environment string            `json:"environment,omitempty"`
    Scopes      []string          `json:"scopes,omitempty"`
    Metadata    map[string]string `json:"metadata,omitempty"`
}

Authsome provides a first-class WithKeysmith option that accepts the concrete *keysmith.Engine directly:

import (
    "github.com/xraph/authsome"
    "github.com/xraph/keysmith"
)

// Build the Keysmith engine.
keysmithEng, err := keysmith.New(
    keysmith.WithStore(keysmithStore),
    keysmith.WithRateLimit(keysmith.RateLimitConfig{
        RequestsPerMinute: 1000,
    }),
)
if err != nil {
    log.Fatal(err)
}

// Register with Authsome using the first-class option.
eng, err := authsome.New(
    authsome.WithStore(pgStore),
    authsome.WithKeysmith(keysmithEng),
)

Internally, WithKeysmith calls:

e.keysmith_ = keysmithEng
e.keyManager = keysmithadapter.New(keysmithEng)

Setup with the generic KeyManager interface03

import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/bridge/keysmithadapter"
)

eng, err := authsome.New(
    authsome.WithStore(pgStore),
    authsome.WithKeyManager(keysmithadapter.New(keysmithEng)),
)

Capabilities gained with Keysmith04

FeatureWithout KeysmithWith Keysmith
Key creationStored in authsome_api_keys tableManaged in Keysmith with full audit trail
Key validationDatabase lookup by prefixKeysmith's in-memory cache with rate limiting
Rate limitingNot availablePer-key rate limits (req/min, req/day)
Scope enforcementNot availableDeclarative scope validation
Key rotationManual revoke + createGrace period rotation (old key valid for X minutes)
Usage analyticsNot availablePer-key request counts, last-used timestamp
Multi-tenant isolationApp-level scopingFull tenant-scoped key namespacing

Scope enforcement05

When Keysmith is configured, API key validation includes scope checking. Create keys with explicit scopes:

result, err := eng.CreateAPIKey(ctx, &authsome.CreateAPIKeyRequest{
    Name:   "CI pipeline key",
    UserID: userID,
    Scopes: []string{"read:users", "read:sessions"},
})

Keysmith validates that the key's declared scopes match the required scopes for each operation. Requests from keys without the required scope are rejected with a 403 Forbidden.

Standalone development stub06

During development without Keysmith, API key operations return ErrKeyManagerNotAvailable:

import "github.com/xraph/authsome/bridge"

// Authsome uses NoopKeyManager internally when no KeyManager is set.
// You can also set it explicitly to be explicit:
eng, err := authsome.New(
    authsome.WithStore(memory.New()),
    authsome.WithKeyManager(bridge.NewNoopKeyManager()),
)

When NoopKeyManager is active, calls to create, validate, or revoke API keys return an error. If your application does not use API keys, this is fine — no action needed.