auth

package
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ResourceTypeGateway = "gateway"
	ResourceTypeProject = "project"
)

Resource types understood by the default authorizer.

Variables

View Source
var (
	// ErrAPIKeysNotFound is returned if no api key file was found.
	ErrAPIKeysNotFound = errors.New("api key file not found")

	// ErrAPIKeysEmpty is returned if the provided api key file does not contain any keys.
	ErrAPIKeysEmpty = errors.New("api key file contains no keys")

	// ErrAPIKeysInvalid is returned when the api key file is malformed.
	ErrAPIKeysInvalid = errors.New("api key file is invalid")
)
View Source
var (
	// ErrPrincipalNotFound is returned when a token does not resolve to any
	// principal (unknown credential id or secret mismatch). Callers map this to
	// an unauthorized response.
	ErrPrincipalNotFound = errors.New("principal not found for token")

	// ErrLegacyTokenFormat is returned when a token uses the pre-principal format
	// (no embedded credential id). Such tokens are no longer supported; the
	// operator must regenerate them with `centian auth new-key`.
	ErrLegacyTokenFormat = errors.New("legacy token format is no longer supported; regenerate with `centian auth new-key`")
)
View Source
var ErrUnauthorized = errors.New("principal not authorized for resource")

ErrUnauthorized is returned by an Authorizer when a principal is not permitted to access a resource.

Functions

func DefaultAPIKeysPath

func DefaultAPIKeysPath() (string, error)

DefaultAPIKeysPath returns the default path to the API keys file (~/.centian/api_keys.json).

func DefaultPrincipalsDBPath added in v0.4.4

func DefaultPrincipalsDBPath() (string, error)

DefaultPrincipalsDBPath returns the default path to the principals SQLite database (~/.centian/principals.sqlite).

func WriteAPIKeyFile

func WriteAPIKeyFile(path string, file *APIKeyFile) error

WriteAPIKeyFile writes API keys to disk using secure permissions.

Types

type APIKeyEntry

type APIKeyEntry struct {
	ID          string   `json:"id"`
	Hash        string   `json:"hash"`
	PrincipalID string   `json:"principal_id,omitempty"`
	Name        string   `json:"name,omitempty"` // Human-friendly principal name (optional)
	CreatedAt   string   `json:"created_at"`
	Gateways    []string `json:"gateways,omitempty"`
	Projects    []string `json:"projects,omitempty"` // Allowed project slugs (empty = allow all, "*" = allow all)
}

APIKeyEntry represents a stored API key hash and metadata.

ID is the credential id embedded (public) in the token; Hash is the bcrypt of the token's secret portion only. PrincipalID is the stable principal identity this credential resolves to and must be persisted (never regenerated on load) so downstream pool reuse and OAuth bindings stay stable across restarts.

func NewAPIKeyEntry

func NewAPIKeyEntry(gen GeneratedKey) (APIKeyEntry, error)

NewAPIKeyEntry builds a stored entry from generated key material. The secret (not the whole token) is bcrypt-hashed, and a fresh persisted principal id is assigned so the credential resolves to a stable principal across restarts.

func (*APIKeyEntry) AllowsGateway added in v0.0.5

func (e *APIKeyEntry) AllowsGateway(gateway string) bool

AllowsGateway checks whether this key is allowed to access the given gateway. Empty list or "*" means allow-all (see allowMatch).

func (*APIKeyEntry) AllowsProject added in v0.3.3

func (e *APIKeyEntry) AllowsProject(project string) bool

AllowsProject checks whether this key is allowed to access the given project. Empty list or "*" means allow-all (see allowMatch).

type APIKeyFile

type APIKeyFile struct {
	Keys []APIKeyEntry `json:"keys"`
}

APIKeyFile stores hashed API keys on disk.

func AppendAPIKey

func AppendAPIKey(path string, entry *APIKeyEntry) (*APIKeyFile, error)

AppendAPIKey appends an entry to the API key file, creating it if needed.

func ReadAPIKeyFile

func ReadAPIKeyFile(path string) (*APIKeyFile, error)

ReadAPIKeyFile loads API key data from disk without validating contents.

type APIKeyStore deprecated

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

APIKeyStore stores API keys loaded from disk for quick validation.

Deprecated: superseded by the FilePrincipalProvider. Retained until the proxy is fully migrated to PrincipalProvider, then removed.

func LoadAPIKeys

func LoadAPIKeys(path string) (*APIKeyStore, error)

LoadAPIKeys loads API keys from a JSON file.

func LoadDefaultAPIKeys

func LoadDefaultAPIKeys() (*APIKeyStore, error)

LoadDefaultAPIKeys loads API keys from the default path.

func (*APIKeyStore) Count

func (s *APIKeyStore) Count() int

Count returns the number of unique API keys in the store.

func (*APIKeyStore) Lookup added in v0.0.4

func (s *APIKeyStore) Lookup(key string) (*APIKeyEntry, bool)

Lookup returns the matching API key entry for the provided token. It resolves the credential id embedded in the token to a single entry (O(1)) and verifies the secret with one bcrypt comparison.

func (*APIKeyStore) Path

func (s *APIKeyStore) Path() string

Path returns the file path the keys were loaded from.

func (*APIKeyStore) Validate

func (s *APIKeyStore) Validate(key string) bool

Validate returns true if the provided API key exists in the store.

type Action added in v0.4.4

type Action string

Action identifies the kind of operation being authorized. A single access action suffices for the current scope; the resource type distinguishes gateways from projects.

const ActionAccess Action = "access"

ActionAccess is the only action modelled today (access a resource).

type Authorizer added in v0.4.4

type Authorizer interface {
	Authorize(ctx context.Context, p *Principal, action Action, resource Resource) error
}

Authorizer decides whether a principal may perform an action on a resource.

type BackendType added in v0.4.4

type BackendType string

BackendType identifies a principal storage backend.

const (
	// BackendSQLite stores principals in a dedicated SQLite database.
	BackendSQLite BackendType = "sqlite"
	// BackendFile stores api-key principals in the legacy api_keys.json file.
	BackendFile BackendType = "file"
	// DefaultBackendType is used when no backend type is configured.
	DefaultBackendType = BackendSQLite
)

type CreateAPIKeyParams added in v0.4.4

type CreateAPIKeyParams struct {
	Name     string   // Human-friendly principal name (optional)
	Gateways []string // Allowed gateways (empty = allow all)
	Projects []string // Allowed project slugs (empty = allow all)
}

CreateAPIKeyParams describes a new api key to mint.

type CreatedAPIKey added in v0.4.4

type CreatedAPIKey struct {
	Token        string
	PrincipalID  string
	CredentialID string
	BackendType  BackendType
	Store        string
}

CreatedAPIKey is the result of minting a new api key. Token is shown once.

func CreateAPIKey added in v0.4.4

func CreateAPIKey(ctx context.Context, backendType, store string, params CreateAPIKeyParams) (CreatedAPIKey, error)

CreateAPIKey mints a new api key and persists it through the configured backend, resolving empty type/store to defaults (sqlite at the default principals db). The returned Token must be shown to the user immediately; it cannot be recovered.

type DirectGrantAuthorizer added in v0.4.4

type DirectGrantAuthorizer struct{}

DirectGrantAuthorizer authorizes using the principal's inline direct grants (the Gateways/Projects allowlists). It is stateless and safe for concurrent use.

func (DirectGrantAuthorizer) Authorize added in v0.4.4

func (DirectGrantAuthorizer) Authorize(_ context.Context, p *Principal, _ Action, resource Resource) error

Authorize permits access when the principal's relevant grant list allows the resource id. Roles are not consulted (none exist yet).

type FilePrincipalProvider added in v0.4.4

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

FilePrincipalProvider is the file-based PrincipalProvider. It reads the same ~/.centian/api_keys.json store and resolves tokens to principals using an in-memory credential-id index (O(1) lookup + a single bcrypt verify).

func DefaultFilePrincipalProvider added in v0.4.4

func DefaultFilePrincipalProvider() (*FilePrincipalProvider, error)

DefaultFilePrincipalProvider creates a provider backed by the default key file.

func NewFilePrincipalProvider added in v0.4.4

func NewFilePrincipalProvider(path string) *FilePrincipalProvider

NewFilePrincipalProvider creates a provider backed by the given key file path.

func (*FilePrincipalProvider) Close added in v0.4.4

func (p *FilePrincipalProvider) Close() error

Close releases provider resources. The file provider holds none.

func (*FilePrincipalProvider) Count added in v0.4.4

func (p *FilePrincipalProvider) Count() int

Count returns the number of indexed credentials (for startup logging).

func (*FilePrincipalProvider) GetPrincipal added in v0.4.4

func (p *FilePrincipalProvider) GetPrincipal(_ context.Context, token string) (*Principal, error)

GetPrincipal resolves a token to its principal. Unknown credential ids or secret mismatches return ErrPrincipalNotFound; pre-principal tokens return ErrLegacyTokenFormat.

func (*FilePrincipalProvider) ListPrincipals added in v0.4.4

func (p *FilePrincipalProvider) ListPrincipals(_ context.Context) ([]Principal, error)

ListPrincipals returns the distinct principals across indexed credentials.

func (*FilePrincipalProvider) Path added in v0.4.4

func (p *FilePrincipalProvider) Path() string

Path returns the key file path the provider reads from.

func (*FilePrincipalProvider) Setup added in v0.4.4

Setup reads and indexes the key file. It mirrors the historical load semantics: a missing file yields ErrAPIKeysNotFound and an empty file yields ErrAPIKeysEmpty, so callers can surface the same guidance as before.

type GeneratedKey added in v0.4.4

type GeneratedKey struct {
	Token  string
	CredID string
	Secret string
}

GeneratedKey holds the material produced when minting a new API key. Only the Token is shown to the user (once); CredID and Secret are used to build the stored entry (the credential id is public, the secret is bcrypt-hashed).

func GenerateAPIKey

func GenerateAPIKey() (GeneratedKey, error)

GenerateAPIKey mints a new API key token of the form "sk-<credId>.<secret>".

type Principal added in v0.4.4

type Principal struct {
	ID           string
	DisplayName  string
	CredentialID string
	Gateways     []string
	Projects     []string
}

Principal is the resolved actor for an authenticated request.

ID is a stable, persisted identifier (identifiers.KindPrincipal, "pr_..."). It must remain stable across restarts for the same credential because it becomes the downstream pool identity key and the OAuth binding principal id; a fresh id per load would silently orphan persisted OAuth downstream bindings.

Gateways and Projects are direct grants (an inline allowlist) carried straight from the credential. Empty list means allow-all; a "*" entry also means allow-all. Roles are intentionally not modelled yet; they are an additive follow-up behind the Authorizer seam.

func (*Principal) Clone added in v0.4.4

func (p *Principal) Clone() *Principal

Clone returns a deep copy safe to store per-session without aliasing the provider's cached grants.

type PrincipalProvider added in v0.4.4

type PrincipalProvider interface {
	Setup(ctx context.Context) error
	GetPrincipal(ctx context.Context, token string) (*Principal, error)
	// ListPrincipals returns the known principals (id + display name) for labeling
	// purposes. Secrets are never included and order is unspecified.
	ListPrincipals(ctx context.Context) ([]Principal, error)
	Close() error
}

PrincipalProvider resolves authentication tokens to principals.

Setup is called once at startup to initialize the backend (e.g. read and index the key file, open a DB connection). GetPrincipal resolves one token per request and must be safe for concurrent use after Setup. Close releases any resources held by the provider.

func NewPrincipalProvider added in v0.4.4

func NewPrincipalProvider(backendType, store string) (PrincipalProvider, error)

NewPrincipalProvider builds a PrincipalProvider for the configured backend, resolving empty type/store to defaults (sqlite at the default principals db).

type PrincipalSchemaMigrationRequiredError added in v0.4.4

type PrincipalSchemaMigrationRequiredError struct {
	StoredVersion   int
	ExpectedVersion int
}

PrincipalSchemaMigrationRequiredError reports that an existing principals store was written by a newer schema than this binary understands.

func (*PrincipalSchemaMigrationRequiredError) Error added in v0.4.4

type Resource added in v0.4.4

type Resource struct {
	Type string
	ID   string
}

Resource identifies the target of an authorization decision.

func GatewayResource added in v0.4.4

func GatewayResource(name string) Resource

GatewayResource builds a gateway-scoped resource.

func ProjectResource added in v0.4.4

func ProjectResource(slug string) Resource

ProjectResource builds a project-scoped resource.

type SQLPrincipalProvider added in v0.4.4

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

SQLPrincipalProvider is the SQL-backed PrincipalProvider. It resolves tokens to principals via an indexed (primary-key) credential lookup plus one bcrypt verify, querying live so revoked credentials take effect without a restart.

func NewSQLPrincipalProvider added in v0.4.4

func NewSQLPrincipalProvider(path string) *SQLPrincipalProvider

NewSQLPrincipalProvider creates a provider backed by the sqlite file at path.

func (*SQLPrincipalProvider) Close added in v0.4.4

func (p *SQLPrincipalProvider) Close() error

Close releases the database handle.

func (*SQLPrincipalProvider) Count added in v0.4.4

func (p *SQLPrincipalProvider) Count() int

Count returns the number of stored principals (best-effort, for startup logging).

func (*SQLPrincipalProvider) GetPrincipal added in v0.4.4

func (p *SQLPrincipalProvider) GetPrincipal(ctx context.Context, token string) (*Principal, error)

GetPrincipal resolves a token to its principal. Unknown credentials or secret mismatches return ErrPrincipalNotFound; pre-principal tokens return ErrLegacyTokenFormat.

func (*SQLPrincipalProvider) ListPrincipals added in v0.4.4

func (p *SQLPrincipalProvider) ListPrincipals(ctx context.Context) ([]Principal, error)

ListPrincipals returns all stored principals (id + display name) for labeling.

func (*SQLPrincipalProvider) Path added in v0.4.4

func (p *SQLPrincipalProvider) Path() string

Path returns the sqlite file path the provider reads from.

func (*SQLPrincipalProvider) Setup added in v0.4.4

Setup opens the database and bootstraps/migrates the schema. An empty store is valid (a fresh install has no principals yet), so Setup does not error on zero rows; callers may warn based on Count.

Jump to

Keyboard shortcuts

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