auth

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package auth implements VORTEX's authentication and authorization (build plan M3.5): a role-based access-control model (org → team → user), API-key issuance and verification, OIDC/SSO login, and the HTTP middleware that ties them together to protect the management API.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned when no stored key matches a presented secret.
	ErrNotFound = errors.New("auth: api key not found")
	// ErrExpired is returned when a matching key has passed its ExpiresAt.
	ErrExpired = errors.New("auth: api key expired")
)

API-key store errors.

Functions

func NewAuthMiddleware

func NewAuthMiddleware(keys *APIKeyStore, oidc *OIDCProvider, rbac *RBAC) func(http.Handler) http.Handler

NewAuthMiddleware builds the management-API authentication+authorization middleware. Authentication is attempted in this order:

  1. Authorization: Bearer <token> — verified as an OIDC token (if oidc is configured), otherwise as an API-key secret.
  2. X-API-Key: <secret> — verified as an API-key secret.

A request with no usable credential gets 401. Once authenticated, if the route declares a required role (SetRequiredRole) the user must hold it via rbac.Can(..manage..); otherwise any authenticated user passes. An authz failure gets 403.

func SetRequiredRole

func SetRequiredRole(ctx context.Context, role Role) context.Context

SetRequiredRole returns a copy of ctx carrying the role required to access the current route. When unset, any authenticated user is allowed.

func WithUser

func WithUser(ctx context.Context, u User) context.Context

WithUser returns a copy of ctx carrying the authenticated user.

Types

type APIKey

type APIKey struct {
	ID          string    `json:"id"`   // public identifier (16 hex chars)
	Hash        string    `json:"hash"` // bcrypt hash of the secret
	UserID      string    `json:"user_id"`
	OrgID       string    `json:"org_id"`
	Roles       []Role    `json:"roles"`
	CreatedAt   time.Time `json:"created_at"`
	ExpiresAt   time.Time `json:"expires_at"` // zero = never expires
	Description string    `json:"description"`
}

APIKey is an issued credential. The plaintext secret is never stored; only its bcrypt hash is kept, so a leaked store cannot be used to authenticate.

type APIKeyStore

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

APIKeyStore holds issued API keys in memory, with optional JSON persistence. It is safe for concurrent use.

func NewAPIKeyStore

func NewAPIKeyStore() *APIKeyStore

NewAPIKeyStore returns an empty store.

func (*APIKeyStore) Issue

func (s *APIKeyStore) Issue(userID, orgID string, roles []Role, desc string, ttl time.Duration) (APIKey, string, error)

Issue creates a new API key for userID/orgID with the given roles. It returns the stored APIKey (hash only) and the plaintext secret, which is shown to the caller exactly once and never persisted. ttl=0 means the key never expires.

func (*APIKeyStore) List

func (s *APIKeyStore) List(orgID string) []APIKey

List returns all keys for orgID with their hashes redacted (the public view).

func (*APIKeyStore) Load

func (s *APIKeyStore) Load(path string) error

Load replaces the store's contents with the keys in the JSON file at path. A missing file is treated as an empty store (not an error).

func (*APIKeyStore) Revoke

func (s *APIKeyStore) Revoke(id string) error

Revoke removes the key with the given ID. It is idempotent.

func (*APIKeyStore) Save

func (s *APIKeyStore) Save(path string) error

Save persists the store to path as JSON (hashes only, never secrets).

func (*APIKeyStore) Verify

func (s *APIKeyStore) Verify(secret string) (APIKey, error)

Verify checks a presented secret and returns the matching key. The secret carries its key ID as a prefix ("<id>.<random>"), so verification is a single bcrypt comparison against that key. It returns ErrNotFound when no key matches and ErrExpired when the matching key has expired.

type Action

type Action string

Action is an operation a role may be permitted to perform on a resource.

const (
	ActionRead   Action = "read"
	ActionWrite  Action = "write"
	ActionDeploy Action = "deploy"
	ActionManage Action = "manage"
)

Actions.

type OIDCConfig

type OIDCConfig struct {
	ProviderURL  string   // issuer URL, e.g. https://accounts.google.com
	ClientID     string   // OAuth2 client ID
	ClientSecret string   // OAuth2 client secret
	RedirectURL  string   // callback URL registered with the provider
	Scopes       []string // requested scopes; defaults to openid, email, profile
}

OIDCConfig configures the OIDC/SSO login flow.

type OIDCProvider

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

OIDCProvider wraps an OIDC issuer: the discovered provider, an ID-token verifier, and the OAuth2 config used to build auth URLs and exchange codes.

func NewOIDCProvider

func NewOIDCProvider(ctx context.Context, cfg OIDCConfig) (*OIDCProvider, error)

NewOIDCProvider discovers the issuer's endpoints from cfg.ProviderURL and builds a provider ready to issue auth URLs, exchange codes, and verify tokens. It returns an error if discovery fails.

func (*OIDCProvider) AuthCodeURL

func (p *OIDCProvider) AuthCodeURL(state string) string

AuthCodeURL returns the provider's authorization URL for the given state, which the client redirects the user to in order to log in.

func (*OIDCProvider) Exchange

func (p *OIDCProvider) Exchange(ctx context.Context, code string) (User, error)

Exchange exchanges an authorization code for tokens, verifies the ID token, and maps its claims onto a User. New SSO users get the viewer role by default.

func (*OIDCProvider) Middleware

func (p *OIDCProvider) Middleware() func(http.Handler) http.Handler

Middleware authenticates requests by verifying a bearer ID token against the OIDC provider and storing the resulting User in the request context. Requests without a valid token receive 401.

type Permission

type Permission struct {
	Role      Role
	Actions   []Action
	Resources []Resource
}

Permission defines what a role may do: the set of actions it can perform on the set of resources.

type RBAC

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

RBAC holds role definitions and answers authorization questions. It is safe for concurrent use.

func NewRBAC

func NewRBAC() *RBAC

NewRBAC returns an RBAC seeded with the built-in role definitions:

admin    — every action on every resource
operator — read+write+deploy on routes, config, nodes
viewer   — read on every resource
readonly — read on routes and config only

func (*RBAC) AddRole

func (r *RBAC) AddRole(name Role, perms Permission) error

AddRole adds or replaces a role definition.

func (*RBAC) Can

func (r *RBAC) Can(user User, action Action, resource Resource) bool

Can reports whether any of the user's roles grants action on resource.

func (*RBAC) Roles

func (r *RBAC) Roles() []Role

Roles returns the names of all defined roles.

type Resource

type Resource string

Resource is a category of object that actions apply to.

const (
	ResourceRoutes  Resource = "routes"
	ResourceSecrets Resource = "secrets"
	ResourceConfig  Resource = "config"
	ResourceNodes   Resource = "nodes"
)

Resources.

type Role

type Role string

Role is a named bundle of permissions assigned to users and API keys.

const (
	RoleAdmin    Role = "admin"
	RoleOperator Role = "operator"
	RoleViewer   Role = "viewer"
	RoleReadonly Role = "readonly"
)

Built-in roles.

func RequiredRoleFromContext

func RequiredRoleFromContext(ctx context.Context) (Role, bool)

RequiredRoleFromContext returns the required role set by SetRequiredRole.

type User

type User struct {
	ID     string
	Email  string
	OrgID  string
	TeamID string
	Roles  []Role
}

User is an authenticated principal in the org → team → user hierarchy.

func UserFromContext

func UserFromContext(ctx context.Context) (User, bool)

UserFromContext returns the authenticated user stored in ctx, if any.

Jump to

Keyboard shortcuts

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