apikey

package
v1.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 28 Imported by: 0

README

apikey

Long-lived keys for machine-to-machine calls, scoped to a user and revocable one at a time.

Keys are hashed with SHA-256 before storage, so a database dump does not hand anyone working credentials. A short visible prefix is kept in the clear purely so lookup can find the right row without scanning every hash. The auth strategy checks both the Authorization header and X-API-Key, so callers can use whichever their HTTP client makes easy.

The plaintext key is returned exactly once, at creation.

Use it when

  • A service, a CI job or a CLI needs to call your API without a browser
  • You want per-integration credentials that can be revoked without touching anyone's password
  • You're building a public API and users need to generate their own keys

Skip it when

  • The caller is a browser with a logged-in human. Sessions are the right shape for that
  • You need short-lived, scoped, audience-bound tokens. That's oauth2provider with the client credentials grant
  • You have no way to rotate keys. A key that never expires is a credential you cannot take back once it leaks

Wiring

authsome.WithPlugin(apikey.New(apikey.Config{
    MaxKeysPerUser: 10,
    DefaultExpiry:  90 * 24 * time.Hour,
}))

Set DefaultExpiry. Keys that never expire are the ones still working three years after the person who made them left.

Config

Field Type Default What it does
PathPrefix string /v1/keys Where the management routes are mounted
MaxKeysPerUser int 0 Cap on active keys per user. 0 is unlimited
DefaultExpiry time.Duration 0 Default TTL for a new key. Zero means it never expires

Settings

Key Default
apikey.max_keys_per_user 0
apikey.default_expiry_seconds 0

Endpoints

Registered under PathPrefix, /v1/keys by default.

Method Path Purpose
POST `` Create a key. The plaintext is in this response and nowhere else
GET `` List the caller's keys, metadata only
DELETE /:keyId Revoke a key

Lifecycle hooks

None. It registers a StrategyProvider that authenticates requests carrying a key.

oauth2provider if you need real OAuth2 client credentials with scopes and expiry rather than a static secret.

Documentation

Overview

contract.go: Wires the apikey plugin into the forge-dashboard contract surface via plugin.ContractContributor.

Package apikey provides an API key authentication plugin for AuthSome.

The apikey plugin enables machine-to-machine authentication. API keys are created per-user, hashed with SHA-256, and identified by a visible prefix during lookup. The plugin registers HTTP routes for key lifecycle management and an authentication strategy that checks the Authorization or X-API-Key headers.

Index

Constants

This section is empty.

Variables

View Source
var (
	// SettingMaxKeysPerUser controls the maximum number of active API keys per user.
	SettingMaxKeysPerUser = settings.Define("apikey.max_keys_per_user", 0,
		settings.WithDisplayName("Max Keys Per User"),
		settings.WithDescription("Maximum number of active API keys per user (0 = unlimited)"),
		settings.WithCategory("API Keys"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithEnforceable(),
		settings.WithInputType(formconfig.FieldNumber),
		settings.WithUIValidation(formconfig.Validation{Min: intPtr(0), Max: intPtr(100)}),
		settings.WithHelpText("Set to 0 for unlimited keys. Default: 0"),
		settings.WithOrder(10),
	)

	// SettingDefaultExpirySeconds controls the default TTL for newly created keys.
	SettingDefaultExpirySeconds = settings.Define("apikey.default_expiry_seconds", 0,
		settings.WithDisplayName("Default Key Expiry (seconds)"),
		settings.WithDescription("Default TTL for newly created API keys in seconds (0 = no expiry)"),
		settings.WithCategory("API Keys"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithInputType(formconfig.FieldNumber),
		settings.WithUIValidation(formconfig.Validation{Min: intPtr(0)}),
		settings.WithHelpText("Set to 0 for keys that never expire. Default: 0"),
		settings.WithOrder(20),
	)
)

Functions

This section is empty.

Types

type Config

type Config struct {
	// PathPrefix is the HTTP path prefix for API key routes.
	// Defaults to "/v1/keys".
	PathPrefix string

	// MaxKeysPerUser limits the number of active API keys per user.
	// 0 means unlimited.
	MaxKeysPerUser int

	// DefaultExpiry sets the default TTL for newly created keys.
	// Zero means keys never expire.
	DefaultExpiry time.Duration
}

Config configures the API key plugin.

type CreateKeyRequest added in v1.9.0

type CreateKeyRequest struct {
	AppID string `json:"app_id"`
	// UserID names the key's owner. Optional — defaults to the authenticated
	// caller. Naming another user requires the manage/apikey permission.
	UserID string   `json:"user_id,omitempty"`
	Name   string   `json:"name"`
	Scopes []string `json:"scopes,omitempty"`
}

CreateKeyRequest is the request body for creating an API key.

type CreateKeyResponse added in v1.9.0

type CreateKeyResponse struct {
	ID              string   `json:"id"`
	Key             string   `json:"key"`
	KeyPrefix       string   `json:"key_prefix"`
	PublicKey       string   `json:"public_key"`
	PublicKeyPrefix string   `json:"public_key_prefix"`
	Name            string   `json:"name"`
	Scopes          []string `json:"scopes,omitempty"`
	ExpiresAt       *string  `json:"expires_at,omitempty"`
	CreatedAt       string   `json:"created_at"`
}

CreateKeyResponse is returned when a key is created.

type KeyListItem added in v1.9.0

type KeyListItem struct {
	ID              string   `json:"id"`
	Name            string   `json:"name"`
	KeyPrefix       string   `json:"key_prefix"`
	PublicKeyPrefix string   `json:"public_key_prefix,omitempty"`
	Scopes          []string `json:"scopes,omitempty"`
	ExpiresAt       *string  `json:"expires_at,omitempty"`
	LastUsedAt      *string  `json:"last_used_at,omitempty"`
	Revoked         bool     `json:"revoked"`
	CreatedAt       string   `json:"created_at"`
}

KeyListItem represents an API key in list responses (no raw key).

type ListKeysRequest added in v1.9.0

type ListKeysRequest struct {
	AppID  string `query:"app_id"`
	UserID string `query:"user_id,omitempty"`
}

ListKeysRequest contains query parameters for listing API keys.

type ListKeysResponse added in v1.9.0

type ListKeysResponse struct {
	Keys  []KeyListItem `json:"keys"`
	Total int           `json:"total"`
}

ListKeysResponse is the response for listing API keys.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin is the API key authentication plugin.

func New added in v1.9.0

func New(cfg ...Config) *Plugin

New creates a new API key plugin with the given configuration. The API key store is resolved automatically from the engine during OnInit.

func (*Plugin) DeclareSettings added in v1.9.0

func (p *Plugin) DeclareSettings(m *settings.Manager) error

DeclareSettings implements plugin.SettingsProvider.

func (*Plugin) Name added in v1.9.0

func (p *Plugin) Name() string

Name returns the plugin name.

func (*Plugin) OnInit added in v1.9.0

func (p *Plugin) OnInit(_ context.Context, engine plugin.Engine) error

OnInit captures bridge references from the engine.

func (*Plugin) RegisterContract added in v1.9.0

func (p *Plugin) RegisterContract(
	d *dispatcher.Dispatcher,
	reg contract.Registry,
	wreg contract.WardenRegistry,
	engine plugin.Engine,
) error

func (*Plugin) RegisterRoutes

func (p *Plugin) RegisterRoutes(router forge.Router) error

RegisterRoutes registers API key management routes on a forge.Router.

func (*Plugin) SetStore added in v1.9.0

func (p *Plugin) SetStore(s apikey.Store)

SetStore allows direct API key store injection for testing.

func (*Plugin) Strategy added in v1.9.0

func (p *Plugin) Strategy() strategy.Strategy

Strategy returns the API key authentication strategy.

func (*Plugin) StrategyPriority added in v1.9.0

func (p *Plugin) StrategyPriority() int

StrategyPriority returns the evaluation priority for the API key strategy. API key auth is evaluated after session-based auth (priority 100).

type PrincipalAuthGate added in v1.9.0

type PrincipalAuthGate interface {
	Authorize(ctx context.Context, a *principal.AuthAttempt) error
	Observe(ctx context.Context, a *principal.AuthAttempt, s *session.Session)
}

PrincipalAuthGate scores a machine caller and may deny it. The apikey plugin holds this rather than the engine so it does not import authsome.

Authorize runs the BeforePrincipalAuth chain; a returned error must abort the request. Observe runs after a session has been minted and never blocks authentication: errors from it are logged, not propagated.

type PrincipalResolver added in v1.9.0

type PrincipalResolver func(ctx context.Context, ref principal.Ref) (*principal.Principal, error)

PrincipalResolver resolves any caller, human or otherwise, by ref. Taken as a function rather than the whole engine so the strategy keeps its narrow dependency surface, matching UserResolver above.

type RevokeKeyRequest added in v1.9.0

type RevokeKeyRequest struct {
	KeyID string `path:"keyId"`
}

RevokeKeyRequest contains the path parameter for revoking an API key.

type UserResolver added in v1.9.0

type UserResolver func(ctx context.Context, userID string) (*user.User, error)

UserResolver resolves a user by ID string.

Directories

Path Synopsis
Package contract wires the apikey plugin's intent surface into the forge-dashboard contract registry.
Package contract wires the apikey plugin's intent surface into the forge-dashboard contract registry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL