auth

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2026 License: GPL-3.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const SessionTokenTTL = 5 * time.Minute

SessionTokenTTL is the validity window for session reference tokens.

Variables

This section is empty.

Functions

func AppAuthMiddleware

func AppAuthMiddleware(deps *Deps) func(http.Handler) http.Handler

AppAuthMiddleware authenticates if possible, but does not require it. Public apps allow unauthenticated access; the proxy handler decides whether to allow or deny based on the app's access_type.

When OIDC is not configured (v0 compat), the middleware passes all requests through unchanged (no identity in context).

func CallbackHandler

func CallbackHandler(deps *Deps) http.HandlerFunc

CallbackHandler handles the IdP callback after user authentication.

func ContextWithCaller

func ContextWithCaller(ctx context.Context, c *CallerIdentity) context.Context

ContextWithCaller returns a new context carrying the given CallerIdentity.

func ContextWithUser

func ContextWithUser(ctx context.Context, u *AuthenticatedUser) context.Context

ContextWithUser returns a new context carrying the given AuthenticatedUser.

func EncodeSessionToken

func EncodeSessionToken(claims *SessionTokenClaims, key *SigningKey) (string, error)

EncodeSessionToken serializes and signs a session reference token. Format: base64url(json) + "." + base64url(hmac)

func GeneratePAT

func GeneratePAT() (plaintext string, hash []byte, err error)

GeneratePAT creates a new personal access token with the by_ prefix. Returns the plaintext token (shown once to the user) and its SHA-256 hash (stored in the database).

func HashPAT

func HashPAT(plaintext string) []byte

HashPAT computes the SHA-256 hash of a plaintext PAT.

func LoginHandler

func LoginHandler(deps *Deps) http.HandlerFunc

LoginHandler initiates the OIDC authorization code flow. Query params: ?return_url=/app/my-app/ (optional, default: /)

func LogoutHandler

func LogoutHandler(deps *Deps) http.HandlerFunc

LogoutHandler clears the session cookie and removes the server-side session. Redirects to / (or to the IdP's end_session_endpoint if available).

func NowUnix

func NowUnix() int64

NowUnix is the exported accessor for nowUnix, used by tests.

Types

type AuthSource

type AuthSource int

AuthSource describes how the caller authenticated.

const (
	AuthSourceSession AuthSource = iota // Browser session via OIDC
	AuthSourcePAT                       // Personal Access Token
)

type AuthenticatedUser

type AuthenticatedUser struct {
	Sub         string
	AccessToken string
}

AuthenticatedUser represents a validated user identity extracted from a session. Stored in the request context by the auth middleware.

func UserFromContext

func UserFromContext(ctx context.Context) *AuthenticatedUser

UserFromContext retrieves the AuthenticatedUser from the request context, or nil if not present.

type CallerIdentity

type CallerIdentity struct {
	Sub    string
	Name   string // human-readable display name (from OIDC name claim / DB)
	Role   Role
	Source AuthSource
}

CallerIdentity is the unified caller identity produced by auth middlewares. Stored in request context for use by authorization checks.

func CallerFromContext

func CallerFromContext(ctx context.Context) *CallerIdentity

CallerFromContext extracts the CallerIdentity from the context. Returns nil if no identity is present.

func (*CallerIdentity) DisplayName

func (c *CallerIdentity) DisplayName() string

DisplayName returns the human-readable name if available, otherwise the Sub.

type CookiePayload

type CookiePayload struct {
	Sub      string `json:"sub"`
	IssuedAt int64  `json:"issued_at"`
}

CookiePayload is the minimal payload encoded into the session cookie. Signed with HMAC-SHA256. All other session data lives server-side.

func DecodeCookie

func DecodeCookie(value string, key *SigningKey) (*CookiePayload, error)

DecodeCookie verifies the HMAC signature and deserializes the payload.

func (*CookiePayload) Encode

func (p *CookiePayload) Encode(key *SigningKey) (string, error)

Encode serializes the payload and signs it with HMAC-SHA256. Format: base64url(json) + "." + base64url(hmac)

type Deps

type Deps struct {
	Config       *config.Config
	OIDCClient   *OIDCClient
	SigningKey   *SigningKey
	UserSessions *UserSessionStore
	AuditLog     *audit.Log
	DB           *db.DB
}

Deps carries the dependencies that auth handlers and middleware need. Constructed in the router layer from the server struct, avoiding a circular import between auth and server.

type OIDCClient

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

OIDCClient wraps the go-oidc provider and oauth2 config. Initialized once at server startup via Discover().

func Discover

func Discover(ctx context.Context, issuerURL, discoveryURL, clientID, clientSecret, redirectURL string) (*OIDCClient, error)

Discover performs OIDC discovery against the issuer URL and returns a configured client ready for the authorization code flow.

If discoveryURL is non-empty, OIDC discovery is performed against that URL instead of issuerURL. This is useful in Docker environments where the IdP is reachable at a different internal address (e.g. http://dex:5556) than the public issuer URL used in tokens (e.g. http://localhost:5556). A custom HTTP transport rewrites all server-side requests to use the internal address. Token issuer validation still uses issuerURL.

func (*OIDCClient) AuthCodeURL

func (c *OIDCClient) AuthCodeURL(state string, nonce string) string

AuthCodeURL generates the authorization URL with a random state and nonce.

func (*OIDCClient) EndSessionEndpoint

func (c *OIDCClient) EndSessionEndpoint() string

EndSessionEndpoint returns the IdP's end_session_endpoint if advertised in discovery metadata, or empty string otherwise.

func (*OIDCClient) Exchange

func (c *OIDCClient) Exchange(ctx context.Context, code string) (*oauth2.Token, *oidc.IDToken, map[string]json.RawMessage, error)

Exchange trades an authorization code for tokens.

func (*OIDCClient) JWKSURI

func (c *OIDCClient) JWKSURI() string

JWKSURI returns the IdP's jwks_uri from discovery metadata.

func (*OIDCClient) RefreshToken

func (c *OIDCClient) RefreshToken(ctx context.Context, refreshToken string) (*oauth2.Token, error)

RefreshToken exchanges a refresh token for a new access token.

type Role

type Role int

Role is a system-level role managed directly in blockyard's users table. Ordered by privilege — higher value means more privilege.

const (
	RoleNone      Role = iota // No mapped role
	RoleViewer                // Can view granted apps
	RolePublisher             // Can create + manage own apps
	RoleAdmin                 // Full access to everything
)

func ParseRole

func ParseRole(s string) Role

ParseRole converts a string to a Role. Returns RoleNone for unrecognized values.

func (Role) CanCreateApp

func (r Role) CanCreateApp() bool

CanCreateApp reports whether this role can create new apps.

func (Role) CanManageRoles

func (r Role) CanManageRoles() bool

CanManageRoles reports whether this role can manage users.

func (Role) CanManageTags

func (r Role) CanManageTags() bool

CanManageTags reports whether this role can create or delete tags.

func (Role) CanViewAllApps

func (r Role) CanViewAllApps() bool

CanViewAllApps reports whether this role can see all apps regardless of ownership or grants.

func (Role) String

func (r Role) String() string

String returns the lowercase name of the role.

type SessionTokenClaims

type SessionTokenClaims struct {
	Sub string `json:"sub"` // user subject
	App string `json:"app"` // app ID
	Wid string `json:"wid"` // worker ID
	Iat int64  `json:"iat"` // issued at (unix seconds)
	Exp int64  `json:"exp"` // expiry (unix seconds)
}

SessionTokenClaims is the payload of a session reference token. Issued by the proxy on each request to shared containers. The app exchanges this for real credentials via the credential exchange API.

func DecodeSessionToken

func DecodeSessionToken(token string, key *SigningKey) (*SessionTokenClaims, error)

DecodeSessionToken verifies the HMAC signature and deserializes the claims. Returns an error if the signature is invalid or the token has expired.

type SigningKey

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

SigningKey holds the derived HMAC key for cookie signing.

func DeriveSessionTokenKey

func DeriveSessionTokenKey(secret string) *SigningKey

DeriveSessionTokenKey derives a signing key for session tokens. Uses a different domain string than cookie signing to prevent cross-protocol token confusion.

func DeriveSigningKey

func DeriveSigningKey(secret string) *SigningKey

DeriveSigningKey derives a signing key from a secret using HMAC with a domain separation string.

func NewSigningKey added in v0.0.3

func NewSigningKey(key []byte) *SigningKey

NewSigningKey creates a signing key from raw bytes. Used for ephemeral keys generated from crypto/rand.

type UserSession

type UserSession struct {
	AccessToken  string
	RefreshToken string
	ExpiresAt    int64 // unix timestamp
}

UserSession holds per-user session data stored server-side. Keyed by sub.

func EnsureFreshToken

func EnsureFreshToken(ctx context.Context, deps *Deps, sub string) (*UserSession, error)

EnsureFreshToken checks if the user's access token is near expiry (within 60 seconds) and refreshes it if needed. Returns the current session, or an error if refresh fails. Thread-safe via per-user locks.

type UserSessionStore

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

UserSessionStore is an in-memory session store protected by a RWMutex.

func NewUserSessionStore

func NewUserSessionStore() *UserSessionStore

NewUserSessionStore creates an empty session store.

func (*UserSessionStore) Delete

func (s *UserSessionStore) Delete(sub string)

Delete removes a user's session (on logout).

func (*UserSessionStore) Get

func (s *UserSessionStore) Get(sub string) *UserSession

Get looks up a user's session by sub. Returns nil if not found.

func (*UserSessionStore) RefreshLock

func (s *UserSessionStore) RefreshLock(sub string) *sync.Mutex

RefreshLock returns the per-user mutex for token refresh. Creates one if it does not exist.

func (*UserSessionStore) Set

func (s *UserSessionStore) Set(sub string, session *UserSession)

Set inserts or replaces the session for a user.

func (*UserSessionStore) UpdateTokens

func (s *UserSessionStore) UpdateTokens(sub, accessToken string, refreshToken *string, expiresAt int64) bool

UpdateTokens updates the access/refresh tokens after a refresh. Returns false if the session does not exist.

Jump to

Keyboard shortcuts

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