auth

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package auth defines Console's API authentication seam: scopes, principals, the Authenticator interface, and a static bearer-token implementation.

See docs/design/auth.md. The package depends only on the standard library so that internal/core stays dependency-free and every consumer can import it. Tokens are never retained in plaintext: only SHA-256 digests are held, and no error or Principal ever contains any part of a token.

Index

Constants

View Source
const (
	// SessionIdleTimeout is how long a session survives without a request.
	SessionIdleTimeout = 12 * time.Hour
	// SessionMaxLifetime is the absolute lifetime of a session.
	SessionMaxLifetime = 7 * 24 * time.Hour
	// MaxSessions bounds the in-memory session table.
	MaxSessions = 10000
)

Session lifetimes (docs/design/auth.md section 4.4).

View Source
const (

	// MaxThrottleClients bounds the throttle table.
	MaxThrottleClients = 10000
)

Login throttle parameters.

View Source
const TokenPrefix = "csk_"

TokenPrefix is the recognisable prefix of generated tokens, so secret scanners can match them.

Variables

View Source
var ErrUnauthenticated = errors.New("auth: unauthenticated")

ErrUnauthenticated is returned when a request carries no valid credential.

Functions

func GenerateToken

func GenerateToken() (string, error)

GenerateToken returns a new token: 256 random bits, base64url (unpadded), with the "csk_" prefix.

Types

type Authenticator

type Authenticator interface {
	Authenticate(r *http.Request) (Principal, error)
}

Authenticator turns a request into a Principal or ErrUnauthenticated.

type DigestAuthenticator

type DigestAuthenticator interface {
	AuthenticateDigest(d [sha256.Size]byte) (Principal, error)
}

DigestAuthenticator re-resolves a principal from a token digest alone. The dashboard session store keeps only the digest of the token a user logged in with and uses this to confirm on every request that the token is still configured.

type Principal

type Principal struct {
	// Name is an audit label (scope-N plus a digest prefix), never the token.
	Name  string
	Scope Scope
}

Principal identifies an authenticated caller.

type Scope

type Scope int

Scope is a hierarchical permission level: Eval < Read < Write < Admin.

const (
	Eval Scope = iota + 1
	Read
	Write
	Admin
)

The defined scopes, in increasing order of privilege. The zero value is deliberately not a valid scope.

func (Scope) Allows

func (s Scope) Allows(required Scope) bool

Allows reports whether s satisfies the required scope. Scopes are hierarchical, so Admin allows everything. An invalid scope allows nothing.

func (Scope) String

func (s Scope) String() string

String returns the lowercase scope name ("eval", "read", "write", "admin").

func (Scope) Valid

func (s Scope) Valid() bool

Valid reports whether s is one of the defined scopes.

type Session

type Session struct {
	Principal Principal
	// Digest is SHA-256 of the login token; re-checked against the current
	// token set on every request so removing a token revokes its sessions.
	Digest [sha256.Size]byte
	// CSRF is the per-session synchronizer token (256 random bits,
	// base64url). It is delivered to templates and compared in constant time
	// on cookie-authenticated unsafe requests; it is never logged.
	CSRF    string
	Created time.Time
	Seen    time.Time
}

Session is a server-side dashboard login. It holds the digest of the token that was presented at login, never the token itself.

type SessionStore

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

SessionStore is an in-memory, bounded session table. A restart logs everyone out. It is safe for concurrent use.

func NewSessionStore

func NewSessionStore(now func() time.Time) *SessionStore

NewSessionStore returns an empty store. now may be nil (time.Now); tests inject a fake clock.

func (*SessionStore) Create

func (s *SessionStore) Create(p Principal, digest [sha256.Size]byte) (string, error)

Create stores a new session for p and returns its ID. When the table is full, expired sessions are purged first, then the least recently used one is evicted.

func (*SessionStore) Delete

func (s *SessionStore) Delete(id string)

Delete destroys the session (logout, or revocation).

func (*SessionStore) Get

func (s *SessionStore) Get(id string) (Session, bool)

Get returns a copy of the live session for id and refreshes its idle timer. Expired sessions are purged and reported as absent.

func (*SessionStore) Len

func (s *SessionStore) Len() int

Len reports the number of stored sessions, expired ones included until purged.

type Static

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

Static authenticates bearer tokens configured up front. It retains only SHA-256 digests of the tokens.

func NewStatic

func NewStatic(tokens map[Scope][]string) *Static

NewStatic builds a Static authenticator from per-scope token lists. Blank tokens are ignored. A token configured under several scopes resolves to the highest of them. Principal names are "<scope>-<N>-<hex>" where N is the 1-based position in that scope's list and hex is the first 6 hex characters of the token digest, e.g. "write-2-1a2b3c".

func (*Static) Authenticate

func (s *Static) Authenticate(r *http.Request) (Principal, error)

Authenticate extracts "Authorization: Bearer <token>" and matches it against the configured digests in constant time.

func (*Static) AuthenticateDigest

func (s *Static) AuthenticateDigest(d [sha256.Size]byte) (Principal, error)

AuthenticateDigest matches d against the configured digests in constant time.

type Throttle

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

Throttle applies exponential backoff to failed logins per client key (the remote address). It is in memory and bounded; it is safe for concurrent use.

func NewThrottle

func NewThrottle(now func() time.Time) *Throttle

NewThrottle returns an empty throttle. now may be nil (time.Now).

func (*Throttle) Check

func (t *Throttle) Check(key string) time.Duration

Check reports how long key must wait before trying again; zero means allowed.

func (*Throttle) Fail

func (t *Throttle) Fail(key string) time.Duration

Fail records a failed attempt and returns the resulting lockout duration (zero while within the free failures). Delay doubles per failure, capped.

func (*Throttle) Len

func (t *Throttle) Len() int

Len reports the number of tracked clients.

func (*Throttle) Success

func (t *Throttle) Success(key string)

Success forgets key.

Jump to

Keyboard shortcuts

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