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 ¶
- Variables
- func DetectEnvironmentType(rawKey string) (environment.Type, bool)
- func EnvironmentKeyMarker(envType environment.Type) string
- func GenerateKey() (raw, hash, prefix string, err error)
- func GenerateKeyForEnvironment(envType environment.Type) (raw, hash, prefix string, err error)
- func GenerateKeyPair() (publicKey, secretKey, secretHash, publicPrefix, secretPrefix string, err error)
- func GenerateKeyPairForEnvironment(envType environment.Type) (publicKey, secretKey, secretHash, publicPrefix, secretPrefix string, err error)
- func HashKey(raw string) string
- func IsAPIKey(key string) bool
- func IsPublicKey(key string) bool
- func IsSecretKey(key string) bool
- func NeedsRehash(raw, hash string) bool
- func PublicKeyMarker(envType environment.Type) string
- func SetPepper(p []byte)
- func StripKeyMarker(rawKey string) string
- func VerifyKey(raw, hash string) bool
- type APIKey
- type KeysmithStore
- func (s *KeysmithStore) CreateAPIKey(ctx context.Context, ak *APIKey) error
- func (s *KeysmithStore) DeleteAPIKey(ctx context.Context, keyID id.APIKeyID) error
- func (s *KeysmithStore) FindByPrefix(ctx context.Context, prefix string) (*APIKey, error)
- func (s *KeysmithStore) FindByPublicKey(ctx context.Context, publicKey string) (*APIKey, error)
- func (s *KeysmithStore) GetAPIKey(ctx context.Context, keyID id.APIKeyID) (*APIKey, error)
- func (s *KeysmithStore) GetAPIKeyByPrefix(ctx context.Context, _ id.AppID, prefix string) (*APIKey, error)
- func (s *KeysmithStore) GetAPIKeyByPublicKey(ctx context.Context, appID id.AppID, publicKey string) (*APIKey, error)
- func (s *KeysmithStore) ListAPIKeysByApp(ctx context.Context, appID id.AppID) ([]*APIKey, error)
- func (s *KeysmithStore) ListAPIKeysByUser(ctx context.Context, appID id.AppID, userID id.UserID) ([]*APIKey, error)
- func (s *KeysmithStore) TouchAPIKey(ctx context.Context, keyID id.APIKeyID, at time.Time) error
- func (s *KeysmithStore) UpdateAPIKey(ctx context.Context, ak *APIKey) error
- type Store
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
HashKey returns the digest stored for a raw API key: HMAC-SHA256 under the pepper when one is set, plain SHA-256 otherwise.
func IsPublicKey ¶
IsPublicKey returns true if the key has a publishable key prefix (pk_*).
func IsSecretKey ¶
IsSecretKey returns true if the key has a secret key prefix (sk_* or ask_).
func NeedsRehash ¶
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 ¶
StripKeyMarker removes the environment/legacy marker prefix from a raw key, returning just the hex-encoded random part. Useful for prefix extraction.
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.
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 (*KeysmithStore) FindByPrefix ¶
func (*KeysmithStore) FindByPublicKey ¶
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) GetAPIKeyByPrefix ¶
func (*KeysmithStore) GetAPIKeyByPublicKey ¶
func (*KeysmithStore) ListAPIKeysByApp ¶
func (*KeysmithStore) ListAPIKeysByUser ¶
func (*KeysmithStore) TouchAPIKey ¶
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.