auth

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package auth provides authentication and authorization for the stash server.

It supports two authentication methods:

  • Session-based authentication for web UI (username/password login)
  • Token-based authentication for API (X-Auth-Token header or Authorization: Bearer)

Token types:

  • Named tokens with specific ACL permissions
  • Public token (token="*") allowing unauthenticated access with limited permissions

Authorization uses prefix-based ACL where permissions are granted per key prefix with access levels: read (r), write (w), or read-write (rw). Wildcards (*) match any key, and longest prefix match wins. Secrets paths require explicit grant.

Configuration is loaded from a YAML file with optional hot-reload support. Sessions are stored persistently and survive server restarts.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractToken

func ExtractToken(r *http.Request) string

ExtractToken extracts API token from request headers. Checks X-Auth-Token header first, then Authorization: Bearer header. Returns the token string (may be empty if not found).

func MaskToken

func MaskToken(token string) string

MaskToken returns a masked version of token for safe logging (shows first 4 chars).

Types

type Config

type Config struct {
	Users  []UserConfig  `yaml:"users,omitempty" json:"users,omitempty" jsonschema:"description=users for web UI auth"`
	Tokens []TokenConfig `yaml:"tokens,omitempty" json:"tokens,omitempty" jsonschema:"description=API tokens"`
}

Config represents the auth configuration file (stash-auth.yml).

func LoadConfig

func LoadConfig(path string, validator ConfigValidator) (*Config, error)

LoadConfig reads and parses the auth YAML file. If validator is provided, the config is validated against the schema.

type ConfigValidator

type ConfigValidator func(data []byte) error

ConfigValidator validates auth configuration data against a schema.

type PermissionConfig

type PermissionConfig struct {
	Prefix string `yaml:"prefix" json:"prefix" jsonschema:"required"`
	Access string `yaml:"access" json:"access" jsonschema:"required,enum=r,enum=read,enum=w,enum=write,enum=rw,enum=readwrite,enum=read-write"`
}

PermissionConfig represents a prefix-permission pair in the config file.

type Service

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

Service handles authentication and authorization.

func New

func New(authFile string, loginTTL time.Duration, hotReload bool, sessionStore SessionStore, validator ConfigValidator) (*Service, error)

New creates a new Service instance from configuration file. Returns nil if authFile is empty (authentication disabled). sessionStore is required for persistent session storage. hotReload enables watching the config file for changes.

func (*Service) Activate

func (s *Service) Activate(ctx context.Context) error

Activate starts auth background tasks: file watcher (if hot-reload enabled) and session cleanup. Should be called once after New(), typically from main.go.

func (*Service) CheckUserPermission

func (s *Service) CheckUserPermission(username, key string, needWrite bool) bool

CheckUserPermission checks if a user has the required permission for a key. Returns true when auth is disabled (permissive by default).

func (*Service) CreateSession

func (s *Service) CreateSession(ctx context.Context, username string) (string, error)

CreateSession generates a new session token for the given username.

func (*Service) Enabled

func (s *Service) Enabled() bool

Enabled returns true if authentication is enabled.

func (*Service) FilterKeysForRequest

func (s *Service) FilterKeysForRequest(r *http.Request, keys []string) []string

FilterKeysForRequest filters keys based on the request's authentication. Determines actor type (token, session user, or public) and filters accordingly. Returns all keys when auth is disabled.

func (*Service) FilterUserKeys

func (s *Service) FilterUserKeys(username string, keys []string) []string

FilterUserKeys filters keys based on user's read permissions. Returns all keys when auth is disabled (permissive by default).

func (*Service) GetRequestActor

func (s *Service) GetRequestActor(r *http.Request) (actorType, actorName string)

GetRequestActor returns the actor type and name from the request. Returns ("user", username), ("token", masked_token), or ("public", "").

func (*Service) GetSessionUser

func (s *Service) GetSessionUser(ctx context.Context, token string) (string, bool)

GetSessionUser returns the username for a valid session. Returns empty string and false if session is invalid or expired. Note: expiration is checked in store.GetSession, which returns ErrNotFound for expired sessions.

func (*Service) InvalidateSession

func (s *Service) InvalidateSession(ctx context.Context, token string)

InvalidateSession removes a session.

func (*Service) IsAdmin

func (s *Service) IsAdmin(username string) bool

IsAdmin returns true if user has admin privileges. Returns false when auth is disabled.

func (*Service) IsRequestAdmin

func (s *Service) IsRequestAdmin(r *http.Request) bool

IsRequestAdmin checks if the request is from an admin (user or token). Returns false when auth is disabled.

func (*Service) IsValidUser

func (s *Service) IsValidUser(username, password string) bool

IsValidUser checks if username/password are valid credentials. Uses constant-time comparison to prevent username enumeration via timing attacks.

func (*Service) LoginTTL

func (s *Service) LoginTTL() time.Duration

LoginTTL returns the configured login session TTL.

func (*Service) Reload

func (s *Service) Reload(ctx context.Context) error

Reload reloads the auth configuration from the file. Validates new config before applying. On success, invalidates sessions only for users that were removed or had their password changed. On error, keeps the existing config and returns the error.

func (*Service) SessionMiddleware

func (s *Service) SessionMiddleware(loginURL string) func(http.Handler) http.Handler

SessionMiddleware returns middleware that requires a valid session cookie. Used for web UI routes. Redirects to loginURL if not authenticated. For HTMX requests, uses HX-Redirect header to trigger full page navigation.

func (*Service) TokenMiddleware

func (s *Service) TokenMiddleware(next http.Handler) http.Handler

TokenMiddleware returns middleware that requires a valid token with appropriate permissions. Accepts X-Auth-Token header or Authorization: Bearer <token>. Used for API routes. Returns 401/403 if not authorized. Public access (token="*") is checked first and allows unauthenticated requests. For list operations (empty key), only validates token existence, filtering happens in handler.

func (*Service) UserCanWrite

func (s *Service) UserCanWrite(username string) bool

UserCanWrite returns true if user has any write permission. Returns true when auth is disabled (permissive by default).

type SessionStore

type SessionStore interface {
	CreateSession(ctx context.Context, token, username string, expiresAt time.Time) error
	GetSession(ctx context.Context, token string) (username string, expiresAt time.Time, err error)
	DeleteSession(ctx context.Context, token string) error
	DeleteAllSessions(ctx context.Context) error
	DeleteSessionsByUsername(ctx context.Context, username string) error
	DeleteExpiredSessions(ctx context.Context) (int64, error)
}

SessionStore is the interface for persistent session storage.

type TokenACL

type TokenACL struct {
	Token string
	Admin bool // grants admin privileges (audit access)
	// contains filtered or unexported fields
}

TokenACL defines access control for an API token.

func (TokenACL) CheckKeyPermission

func (acl TokenACL) CheckKeyPermission(key string, needWrite bool) bool

CheckKeyPermission checks if this ACL grants permission for a key. For secret keys (containing "secrets" path segment), the matching prefix must also explicitly contain "secrets" - wildcards like "*" or "app/*" do not grant access to secrets.

type TokenConfig

type TokenConfig struct {
	Token       string             `yaml:"token" json:"token" jsonschema:"required"`
	Admin       bool               `yaml:"admin,omitempty" json:"admin,omitempty" jsonschema:"description=grants admin privileges (audit access)"`
	Permissions []PermissionConfig `yaml:"permissions,omitempty" json:"permissions,omitempty"`
}

TokenConfig represents an API token in the auth config file.

type User

type User struct {
	Name         string
	PasswordHash string
	Admin        bool     // grants admin privileges (audit access)
	ACL          TokenACL // reuse ACL structure for permissions
}

User represents an authenticated user with ACL.

type UserConfig

type UserConfig struct {
	Name        string             `yaml:"name" json:"name" jsonschema:"required"`
	Password    string             `yaml:"password" json:"password" jsonschema:"required"` // bcrypt hash
	Admin       bool               `yaml:"admin,omitempty" json:"admin,omitempty" jsonschema:"description=grants admin privileges (audit access)"`
	Permissions []PermissionConfig `yaml:"permissions,omitempty" json:"permissions,omitempty"`
}

UserConfig represents a user in the auth config file.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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