Help us shape the future of Go! Take the 2026 Go Developer Survey

apikey

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package apikey defines the API key domain entity and its store interface. API keys enable machine-to-machine authentication, providing an alternative to session-based auth for programmatic access.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("apikey: not found")

ErrNotFound is returned when an API key cannot be found.

Functions

func DetectEnvironmentType

func DetectEnvironmentType(rawKey string) (environment.Type, bool)

DetectEnvironmentType determines the environment type from a raw API key by examining its prefix marker. Returns the detected type and true if recognized, or empty and false for unknown keys.

func EnvironmentKeyMarker

func EnvironmentKeyMarker(envType environment.Type) string

EnvironmentKeyMarker returns the key prefix marker for a given environment type.

func GenerateKey

func GenerateKey() (raw, hash, prefix string, err error)

GenerateKey creates a new API key, returning the raw key (shown to user once) and the hashed value (stored in the database).

func GenerateKeyForEnvironment

func GenerateKeyForEnvironment(envType environment.Type) (raw, hash, prefix string, err error)

GenerateKeyForEnvironment creates a new API key with an environment-specific prefix.

func GenerateKeyPair

func GenerateKeyPair() (publicKey, secretKey, secretHash, publicPrefix, secretPrefix string, err error)

GenerateKeyPair creates a Clerk-style key pair: a publishable key (pk_*) for frontend use and a secret key (sk_*) for server-side auth. The secret key is hashed; the public key is stored in plaintext.

func GenerateKeyPairForEnvironment

func GenerateKeyPairForEnvironment(envType environment.Type) (publicKey, secretKey, secretHash, publicPrefix, secretPrefix string, err error)

GenerateKeyPairForEnvironment creates an environment-aware key pair.

func HashKey

func HashKey(raw string) string

HashKey returns the digest stored for a raw API key: HMAC-SHA256 under the pepper when one is set, plain SHA-256 otherwise.

func IsAPIKey

func IsAPIKey(key string) bool

IsAPIKey returns true if the string looks like an API key (pk_*, sk_*, or ask_).

func IsPublicKey

func IsPublicKey(key string) bool

IsPublicKey returns true if the key has a publishable key prefix (pk_*).

func IsSecretKey

func IsSecretKey(key string) bool

IsSecretKey returns true if the key has a secret key prefix (sk_* or ask_).

func NeedsRehash

func NeedsRehash(raw, hash string) bool

NeedsRehash reports whether a stored hash that just verified raw was made without the pepper now in force, so the caller can store HashKey(raw) in its place.

func PublicKeyMarker

func PublicKeyMarker(envType environment.Type) string

PublicKeyMarker returns the public key prefix marker for a given environment type.

func SetPepper

func SetPepper(p []byte)

SetPepper installs the server-side secret mixed into every API key digest from now on. With a pepper set, HashKey is HMAC-SHA256 over the raw key, so a copy of the key table cannot be checked against a guessed or leaked key without the pepper too. Passing nil returns to plain SHA-256.

func StripKeyMarker

func StripKeyMarker(rawKey string) string

StripKeyMarker removes the environment/legacy marker prefix from a raw key, returning just the hex-encoded random part. Useful for prefix extraction.

func VerifyKey

func VerifyKey(raw, hash string) bool

VerifyKey checks whether the raw key matches the stored hash, accepting the peppered digest and, when a pepper is set, the digest a key was given before the pepper existed. Both comparisons are constant time and both run, so a legacy key costs the same as a current one.

Types

type APIKey

type APIKey struct {
	ID               id.APIKeyID         `json:"id"`
	AppID            id.AppID            `json:"app_id"`
	EnvID            id.EnvironmentID    `json:"env_id"`
	UserID           id.UserID           `json:"user_id"`
	ServiceAccountID id.ServiceAccountID `json:"service_account_id,omitempty"`
	Name             string              `json:"name"`
	KeyHash          string              `json:"-"`
	KeyPrefix        string              `json:"key_prefix"`
	PublicKey        string              `json:"public_key,omitempty"`
	PublicKeyPrefix  string              `json:"public_key_prefix,omitempty"`
	Scopes           []string            `json:"scopes,omitempty"`
	ExpiresAt        *time.Time          `json:"expires_at,omitempty"`
	LastUsedAt       *time.Time          `json:"last_used_at,omitempty"`
	Revoked          bool                `json:"revoked"`
	CreatedAt        time.Time           `json:"created_at"`
	UpdatedAt        time.Time           `json:"updated_at"`
}

APIKey represents an API key for programmatic access. Exactly one of UserID or ServiceAccountID should be non-nil; the other will be the zero ID.

func (*APIKey) IsExpired

func (k *APIKey) IsExpired() bool

IsExpired returns true if the API key has expired.

func (*APIKey) IsValid

func (k *APIKey) IsValid() bool

IsValid returns true if the API key is neither revoked nor expired.

type KeysmithStore

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

KeysmithStore implements apikey.Store by delegating to a Keysmith engine. When Keysmith is available as a first-class citizen, API key CRUD operations gain rate limiting, policy enforcement, key rotation with grace periods, scope management, usage tracking, and multi-tenant support.

func NewKeymithStore

func NewKeymithStore(eng *keysmith.Engine) *KeysmithStore

NewKeymithStore creates a new KeysmithStore backed by the given Keysmith engine.

func (*KeysmithStore) CreateAPIKey

func (s *KeysmithStore) CreateAPIKey(ctx context.Context, ak *APIKey) error

func (*KeysmithStore) DeleteAPIKey

func (s *KeysmithStore) DeleteAPIKey(ctx context.Context, keyID id.APIKeyID) error

func (*KeysmithStore) FindByPrefix

func (s *KeysmithStore) FindByPrefix(ctx context.Context, prefix string) (*APIKey, error)

func (*KeysmithStore) FindByPublicKey

func (s *KeysmithStore) FindByPublicKey(ctx context.Context, publicKey string) (*APIKey, error)

FindByPublicKey searches all keys across all tenants for a matching public key stored in Keysmith metadata. This is used to resolve a publishable key (pk_live_...) to an app without knowing the app ID upfront.

func (*KeysmithStore) GetAPIKey

func (s *KeysmithStore) GetAPIKey(ctx context.Context, keyID id.APIKeyID) (*APIKey, error)

func (*KeysmithStore) GetAPIKeyByPrefix

func (s *KeysmithStore) GetAPIKeyByPrefix(ctx context.Context, _ id.AppID, prefix string) (*APIKey, error)

func (*KeysmithStore) GetAPIKeyByPublicKey

func (s *KeysmithStore) GetAPIKeyByPublicKey(ctx context.Context, appID id.AppID, publicKey string) (*APIKey, error)

func (*KeysmithStore) ListAPIKeysByApp

func (s *KeysmithStore) ListAPIKeysByApp(ctx context.Context, appID id.AppID) ([]*APIKey, error)

func (*KeysmithStore) ListAPIKeysByUser

func (s *KeysmithStore) ListAPIKeysByUser(ctx context.Context, appID id.AppID, userID id.UserID) ([]*APIKey, error)

func (*KeysmithStore) TouchAPIKey

func (s *KeysmithStore) TouchAPIKey(ctx context.Context, keyID id.APIKeyID, at time.Time) error

TouchAPIKey implements Store through keysmith's single-column last-used update.

func (*KeysmithStore) UpdateAPIKey

func (s *KeysmithStore) UpdateAPIKey(ctx context.Context, ak *APIKey) error

type Store

type Store interface {
	// CreateAPIKey stores a new API key.
	CreateAPIKey(ctx context.Context, key *APIKey) error

	// GetAPIKey returns an API key by ID.
	GetAPIKey(ctx context.Context, keyID id.APIKeyID) (*APIKey, error)

	// GetAPIKeyByPrefix returns an API key by its prefix.
	// Used during authentication to look up the key.
	GetAPIKeyByPrefix(ctx context.Context, appID id.AppID, prefix string) (*APIKey, error)

	// FindByPrefix is the app-agnostic counterpart to GetAPIKeyByPrefix:
	// it resolves a key by prefix alone, used by the introspection endpoint
	// where the caller doesn't know the appID up-front.
	FindByPrefix(ctx context.Context, prefix string) (*APIKey, error)

	// GetAPIKeyByPublicKey returns an API key by its public key.
	GetAPIKeyByPublicKey(ctx context.Context, appID id.AppID, publicKey string) (*APIKey, error)

	// UpdateAPIKey updates an existing API key.
	UpdateAPIKey(ctx context.Context, key *APIKey) error

	// TouchAPIKey records that the key was used at the given instant with
	// a single-column write. The validation path calls it at most once a
	// minute per key, so a busy key costs one small write per minute
	// rather than a full-row rewrite per request.
	TouchAPIKey(ctx context.Context, keyID id.APIKeyID, at time.Time) error

	// DeleteAPIKey permanently deletes an API key.
	DeleteAPIKey(ctx context.Context, keyID id.APIKeyID) error

	// ListAPIKeysByApp lists all API keys for a given app.
	ListAPIKeysByApp(ctx context.Context, appID id.AppID) ([]*APIKey, error)

	// ListAPIKeysByUser lists all API keys for a given user within an app.
	ListAPIKeysByUser(ctx context.Context, appID id.AppID, userID id.UserID) ([]*APIKey, error)
}

Store is the persistence interface for API keys.

Jump to

Keyboard shortcuts

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