backend

package
v1.27.0 Latest Latest
Warning

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

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

Documentation

Overview

Package backend is the contract a third-party authentication backend implements — and nothing else.

It exists because of a measurement. The contract used to live in pkg/auth, so a provider that implements two methods imported a package that links 115 third-party packages: session stores, JWT, Redis, Prometheus, OpenTelemetry, the gRPC gateway. None of them are needed to answer "do these credentials belong to a real user", and every one of them was a dependency the author of a plugin inherited without asking.

This package links two packages from ONE module (the configuration decoder). That is the whole point, and it is a property worth protecting: an import added here is paid by everyone who writes a backend, so it needs the same scrutiny as a change to the interface itself. contracts.TestPluginContract_StaysLight is the forcing function.

The names remain available from pkg/auth as aliases, so nothing that already compiled stops compiling.

Index

Constants

This section is empty.

Variables

View Source
var ErrBackendUnavailable = errors.New("auth: backend unavailable")

ErrBackendUnavailable reports that a backend could not reach the system it authenticates against — the directory is down, the connection timed out. It is NOT a rejection: the chain records it and tries the next backend, which is what lets a local break-glass account work while the directory is unreachable.

View Source
var ErrInvalidCredentials = errors.New("auth: invalid credentials")

ErrInvalidCredentials reports that a backend recognised the request and rejected it: the user does not exist, or the password does not match.

It is deliberately ONE error for both cases. A backend that distinguishes them — a different error, or merely a faster answer — publishes a user enumerator, and that is a property of the whole chain rather than of one backend.

View Source
var ErrUserNotFound = errors.New("auth: user not found")

ErrUserNotFound is what a UserProvider returns when the username does not exist.

Functions

func Register

func Register(name string, factory Factory) error

Register makes an authentication backend selectable by name from configuration.

Call it from an init function in the package that implements the backend, then import that package for its side effects — the shape database/sql drivers use:

package ldap

func init() {
    backend.Register("ldap", New)
}

Registering a name that is already taken is an ERROR rather than a silent replacement: two packages claiming "ldap" would otherwise make the effective backend depend on import order, a bug that only ever appears in someone else's deployment.

func Registered

func Registered() []string

Registered returns every selectable backend name, sorted.

func Unregister

func Unregister(name string)

Unregister removes a registered backend.

It exists for tests that register a fake and must not leak it into the next one. Production code has no reason to call it, and calling it does not affect a chain that already holds the backend — the chain resolved its factories when it was built.

Types

type Backend

type Backend interface {
	// Name identifies the backend in logs and configuration.
	Name() string
	// Authenticate verifies credentials against this identity source.
	Authenticate(ctx context.Context, username, password string) (*User, error)
}

Backend authenticates a username and password against one identity source: the application's own user table, an LDAP directory, anything else someone registers.

Authenticate returns the authenticated user, or ErrInvalidCredentials when the backend is sure the answer is no, or ErrBackendUnavailable when it could not reach its source. Any other error is treated as unavailable — a backend that fails in an unexpected way must not be able to lock everyone out.

type Config

type Config struct {
	// Name is the registered name the chain selected this backend by.
	Name string

	// ProviderConfig is the raw `auth.<name>.*` subtree. Read it with Bind
	// rather than reaching into the map.
	ProviderConfig map[string]any
}

Config carries the `auth.<backend>.*` subtree that belongs to one registered authentication backend.

func (Config) Bind

func (c Config) Bind(dst any) error

Bind decodes the backend's own configuration subtree into dst, applying `default:` tags to fields the file left unset.

A key the destination struct does not declare is an ERROR, not a silently ignored line. Backend configuration is exactly where a typo would otherwise sit unnoticed until the day the setting mattered — and here that day is an outage of the login path.

type Factory

type Factory func(cfg Config) (Backend, error)

Factory builds a Backend from the configuration subtree the framework binds for it.

func Lookup

func Lookup(name string) (Factory, bool)

Lookup returns the factory registered under name.

type User

type User struct {
	ID          string
	Username    string
	Email       string
	Role        string
	IsSuperuser bool
}

User is the identity a backend returns. Plain fields on purpose: it crosses the boundary between the framework and code it does not own, so it carries no behaviour and no third-party type.

Directories

Path Synopsis
Package backendtest is a conformance suite for authentication backends.
Package backendtest is a conformance suite for authentication backends.

Jump to

Keyboard shortcuts

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