Documentation
¶
Overview ¶
Package key defines the core API key entity and its lifecycle states.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CreateResult ¶
CreateResult is returned from key creation. The RawKey is shown exactly once.
type Environment ¶
type Environment string
Environment represents the key environment.
const ( // EnvLive is the production environment. EnvLive Environment = "live" // EnvTest is the testing environment. EnvTest Environment = "test" // EnvStaging is the staging environment. EnvStaging Environment = "staging" )
type Key ¶
type Key struct {
ID id.KeyID `json:"id" db:"id"`
TenantID string `json:"tenant_id" db:"tenant_id"`
AppID string `json:"app_id" db:"app_id"`
Name string `json:"name" db:"name"`
Description string `json:"description,omitempty" db:"description"`
Prefix string `json:"prefix" db:"prefix"`
Hint string `json:"hint" db:"hint"`
KeyHash string `json:"-" db:"key_hash"`
Environment Environment `json:"environment" db:"environment"`
State State `json:"state" db:"state"`
PolicyID *id.PolicyID `json:"policy_id,omitempty" db:"policy_id"`
Scopes []string `json:"scopes,omitempty" db:"-"`
Metadata map[string]any `json:"metadata,omitempty" db:"metadata"`
CreatedBy string `json:"created_by,omitempty" db:"created_by"`
ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"`
LastUsedAt *time.Time `json:"last_used_at,omitempty" db:"last_used_at"`
RotatedAt *time.Time `json:"rotated_at,omitempty" db:"rotated_at"`
RevokedAt *time.Time `json:"revoked_at,omitempty" db:"revoked_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
// Version counts the writes to the stored row. It starts at 0, and
// Store.Update, Store.UpdateState and Store.UpdateIfVersion each add
// one. Store.UpdateLastUsed does not. A caller that wants to be told
// when the key changed under it passes the version it read to
// Store.UpdateIfVersion.
Version int64 `json:"version" db:"version"`
}
Key is the core API key entity. The raw key value is never persisted; only the hash is stored. The raw key is returned exactly once at creation.
type ListFilter ¶
type ListFilter struct {
TenantID string `json:"tenant_id,omitempty"`
Environment Environment `json:"environment,omitempty"`
State State `json:"state,omitempty"`
PolicyID *id.PolicyID `json:"policy_id,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
}
ListFilter contains filters for listing keys.
type State ¶
type State string
State represents the lifecycle state of an API key.
const ( // StateActive indicates the key is valid and usable. StateActive State = "active" // StateRotated is never assigned by the engine: rotation keeps the key // active and tracks the previous hash's grace window in the rotation // record. The constant is kept for compatibility with stored data and // callers that still reference it. StateRotated State = "rotated" // StateExpired indicates the key has passed its expiration time. StateExpired State = "expired" // StateRevoked indicates the key has been permanently disabled. StateRevoked State = "revoked" // StateSuspended indicates the key is temporarily disabled. StateSuspended State = "suspended" )
type Store ¶
type Store interface {
Create(ctx context.Context, key *Key) error
Get(ctx context.Context, keyID id.KeyID) (*Key, error)
GetByHash(ctx context.Context, hash string) (*Key, error)
GetByPrefix(ctx context.Context, prefix, hint string) (*Key, error)
// Update writes the whole row whatever its stored version, and adds one
// to that version. It ignores key.Version and leaves it as it was. It is
// last-writer-wins on purpose: callers that write keys directly and never
// read a version keep working.
Update(ctx context.Context, key *Key) error
// UpdateIfVersion writes the whole row only when the stored version
// equals version, sets the stored version to version+1, and sets
// key.Version to it. A key stored at any other version is left alone and
// the call returns store.ErrKeyConflict. A missing key returns
// store.ErrKeyNotFound.
UpdateIfVersion(ctx context.Context, key *Key, version int64) error
// UpdateState sets the state and updated_at, and adds one to the stored
// version.
UpdateState(ctx context.Context, keyID id.KeyID, state State) error
// UpdateLastUsed sets last_used_at and leaves the version alone. It runs
// on every validation, so counting it would turn every version-checked
// write on a busy key into a conflict.
UpdateLastUsed(ctx context.Context, keyID id.KeyID, at time.Time) error
Delete(ctx context.Context, keyID id.KeyID) error
List(ctx context.Context, filter *ListFilter) ([]*Key, error)
Count(ctx context.Context, filter *ListFilter) (int64, error)
ListExpired(ctx context.Context, before time.Time) ([]*Key, error)
ListByPolicy(ctx context.Context, policyID id.PolicyID) ([]*Key, error)
DeleteByTenant(ctx context.Context, tenantID string) error
}
Store is the persistence interface for API keys.
Click to show internal directories.
Click to hide internal directories.