Documentation
¶
Index ¶
- Constants
- Variables
- func CheckPassword(hash, plain string) error
- func ClearSessionCookie(w http.ResponseWriter)
- func DeriveHMACKey(vaultKey, purpose string) ([]byte, error)
- func GetSessionCookie(r *http.Request) (string, error)
- func HMACSign(key, msg []byte) []byte
- func HMACVerify(key, msg, sig []byte) bool
- func HashPassword(plain string) (string, error)
- func IsLinkCode(s string) bool
- func NewSessionID() string
- func SetBcryptCostForTesting(cost int) func()
- func SetSessionCookie(w http.ResponseWriter, sessionID string, secure bool)
- type AccessRequest
- type Action
- type AuthProvider
- type AuthService
- func (s *AuthService) CreateSessionForUser(ctx context.Context, userID string, sessionMgr *SessionManager) (OIDCLoginResult, error)
- func (s *AuthService) Logout(ctx context.Context, rawToken string) error
- func (s *AuthService) PrincipalFromToken(ctx context.Context, rawToken string) (*Principal, error)
- func (s *AuthService) ProcessOIDCLogin(ctx context.Context, ext ExternalIdentity, sessionMgr *SessionManager) (OIDCLoginResult, error)
- func (s *AuthService) UpdateUserAgeKeys(ctx context.Context, userID, publicKey, privateKey string) error
- type AuthState
- type AuthStore
- type AuthStores
- type ChannelIdentity
- type ChannelIdentityStore
- type Credential
- type CredentialService
- type CredentialStore
- type ExternalIdentity
- type LinkCodeStore
- type LoginIdentity
- type LoginIdentityStore
- type OAuthToken
- type OIDCLoginResult
- type PermissionChecker
- type Policy
- type PolicyEngine
- type Principal
- type RateLimiter
- func (rl *RateLimiter) CheckIP(ip string) error
- func (rl *RateLimiter) CheckRegistration(email string) error
- func (rl *RateLimiter) CheckUsername(username string) error
- func (rl *RateLimiter) RecordIPAttempt(ip string)
- func (rl *RateLimiter) RecordLoginFailure(username string)
- func (rl *RateLimiter) RecordLoginSuccess(username string)
- func (rl *RateLimiter) RecordRegistrationFailure(email string)
- func (rl *RateLimiter) RecordRegistrationSuccess(email string)
- type Resource
- type ResourceType
- type RoleBasedChecker
- type Session
- type SessionManager
- func (m *SessionManager) ClearCookie(w http.ResponseWriter)
- func (m *SessionManager) Create(ctx context.Context, userID string) (rawToken string, session Session, err error)
- func (m *SessionManager) Extend(ctx context.Context, sessionID string) error
- func (m *SessionManager) GetToken(r *http.Request) (string, error)
- func (m *SessionManager) Revoke(ctx context.Context, sessionID string) error
- func (m *SessionManager) SetCookie(w http.ResponseWriter, rawToken string, secure bool)
- func (m *SessionManager) Validate(ctx context.Context, rawToken string) (Session, error)
- func (m *SessionManager) WithStore(store SessionStore) *SessionManager
- type SessionStore
- type Subject
- type TokenService
- func (s *TokenService) Authenticate(ctx context.Context, rawToken string) (User, error)
- func (s *TokenService) AuthenticateScoped(ctx context.Context, rawToken string) (User, pkgauth.ScopedTokenClaims, error)
- func (s *TokenService) CreateScopedToken(ctx context.Context, userID, agentID, sessionID, projectID string) (string, error)
- func (s *TokenService) EnsureAutoToken(ctx context.Context, userID string) error
- func (s *TokenService) EnsureAutoTokenEnv(ctx context.Context, userID string) (map[string]string, error)
- func (s *TokenService) EnsureAutoTokenEnvForAgent(ctx context.Context, userID string, agentID string) (map[string]string, error)
- type Transactioner
- type User
- type UserStore
- type UserToken
- type VaultWriter
Constants ¶
const ( OpEq = "eq" OpNeq = "neq" OpIn = "in" OpNotIn = "not_in" OpContains = "contains" )
Condition operators.
const ( // SessionCookieName is the HTTP cookie name for session tokens. SessionCookieName = "stella_session" // SessionDuration is the default session lifetime. SessionDuration = 7 * 24 * time.Hour )
const ( EffectAllow = "allow" EffectDeny = "deny" )
Policy effect constants.
const ( RoleAdmin = "admin" RoleUser = "user" )
RoleAdmin and RoleUser are the built-in role IDs.
const ( // StellaTokenName is re-exported from the vault package for callers that only // import auth. StellaTokenName = vault.StellaTokenName )
Variables ¶
var ( ErrNotFound = errors.New("not found") ErrInvalidCredentials = errors.New("invalid credentials") ErrAlreadyConsumed = errors.New("already consumed") ErrExpired = errors.New("expired") )
Sentinel errors used across auth domain.
var ( ErrRateLimitIP = errors.New("too many requests from this IP, try again later") ErrRateLimitUsername = errors.New("too many failed attempts for this account, try again in 30 seconds") ErrRateLimitRegistration = errors.New("too many registration attempts for this email, try again in 30 seconds") )
Rate limiting errors.
var ErrAccessDenied = errors.New("access denied")
ErrAccessDenied is returned by Must when the request is denied.
var ErrNoSession = errors.New("no session cookie")
ErrNoSession is returned when no session cookie is present.
Functions ¶
func CheckPassword ¶
CheckPassword verifies a plaintext password against a bcrypt hash.
func ClearSessionCookie ¶
func ClearSessionCookie(w http.ResponseWriter)
ClearSessionCookie removes the session cookie from the response. Setting Secure=true is harmless on HTTP and ensures the cookie is properly cleared on HTTPS deployments.
func DeriveHMACKey ¶ added in v0.38.0
DeriveHMACKey derives a per-purpose HMAC key from the vault key. Used by StateManager in the oidc package.
func GetSessionCookie ¶
GetSessionCookie extracts the session ID from the request cookie. Returns ErrNoSession if the cookie is missing or empty.
func HMACVerify ¶ added in v0.38.0
HMACVerify returns true if sig is a valid HMAC-SHA256 of msg under key.
func HashPassword ¶
func IsLinkCode ¶
IsLinkCode returns true if the string looks like a valid link code format (6 alphanumeric characters). This is a quick check before attempting Consume.
func NewSessionID ¶
func NewSessionID() string
NewSessionID generates a cryptographically random hex-encoded session ID (32 bytes = 64 hex characters).
func SetBcryptCostForTesting ¶ added in v0.25.4
func SetBcryptCostForTesting(cost int) func()
SetBcryptCostForTesting overrides the bcrypt work factor and returns a reset func.
func SetSessionCookie ¶
func SetSessionCookie(w http.ResponseWriter, sessionID string, secure bool)
SetSessionCookie writes the session cookie to the response. The Secure flag is set when secure is true (i.e., not localhost/dev).
Types ¶
type AccessRequest ¶
type AccessRequest struct {
Subject Subject `json:"subject"`
Action Action `json:"action"`
Resource Resource `json:"resource"`
Context map[string]any `json:"context,omitempty"`
}
AccessRequest represents a request to check authorization.
type AuthProvider ¶ added in v0.38.0
type AuthProvider interface {
// Name returns the stable provider identifier used in route paths and DB records.
Name() string
// LoginURL generates the IdP redirect URL for the given state.
LoginURL(ctx context.Context, state AuthState) (string, error)
// HandleCallback validates the callback request, exchanges the code for
// tokens, verifies the ID token, and returns the normalised identity.
// Implementations must verify email_verified == true and reject missing emails.
HandleCallback(ctx context.Context, r *http.Request, state AuthState) (*ExternalIdentity, error)
}
AuthProvider is the abstraction over all login methods (OIDC, LocalProvider, GitHub OAuth, reverse proxy, etc.). Business code only depends on this interface.
type AuthService ¶ added in v0.38.0
type AuthService struct {
// contains filtered or unexported fields
}
AuthService composes the auth stores and owns business-level transactions such as ProcessOIDCLogin. It is the only place that coordinates cross-store writes inside a single DB transaction.
func NewAuthService ¶ added in v0.38.0
func NewAuthService( db *pgxpool.Pool, users UserStore, logins LoginIdentityStore, sessions SessionStore, ) *AuthService
NewAuthService creates an AuthService with all required stores.
func (*AuthService) CreateSessionForUser ¶ added in v0.40.0
func (s *AuthService) CreateSessionForUser(ctx context.Context, userID string, sessionMgr *SessionManager) (OIDCLoginResult, error)
CreateSessionForUser creates a login session for a user that has already been authenticated by Stella itself, such as local password login.
func (*AuthService) Logout ¶ added in v0.38.0
func (s *AuthService) Logout(ctx context.Context, rawToken string) error
Logout deletes the session identified by rawToken.
func (*AuthService) PrincipalFromToken ¶ added in v0.38.0
PrincipalFromToken resolves a Principal from a raw session token.
func (*AuthService) ProcessOIDCLogin ¶ added in v0.38.0
func (s *AuthService) ProcessOIDCLogin(ctx context.Context, ext ExternalIdentity, sessionMgr *SessionManager) (OIDCLoginResult, error)
ProcessOIDCLogin is the single transaction entry point for external identity callbacks. It resolves or creates the user and login identity, then creates a new session.
func (*AuthService) UpdateUserAgeKeys ¶ added in v0.38.0
func (s *AuthService) UpdateUserAgeKeys(ctx context.Context, userID, publicKey, privateKey string) error
UpdateUserAgeKeys stores vault age keys for userID in the OIDC user table.
type AuthState ¶ added in v0.38.0
AuthState carries the PKCE code verifier and CSRF state string between the login redirect and the callback. It is embedded in a signed cookie.
type AuthStore ¶
type AuthStore interface {
// Policies
CreatePolicy(ctx context.Context, p Policy) (Policy, error)
GetPolicy(ctx context.Context, id string) (Policy, error)
ListPolicies(ctx context.Context) ([]Policy, error)
ListEnabledPolicies(ctx context.Context) ([]Policy, error)
UpdatePolicy(ctx context.Context, p Policy) error
DeletePolicy(ctx context.Context, id string) error
// User-Agent assignments
AssignAgent(ctx context.Context, userID string, agentID string) error
RemoveAgent(ctx context.Context, userID string, agentID string) error
ListUserAgentIDs(ctx context.Context, userID string) ([]string, error)
ListAgentUserIDs(ctx context.Context, agentID string) ([]string, error)
// API tokens (auth_user_token)
CreateUserToken(ctx context.Context, token UserToken) (UserToken, error)
GetUserTokenByHash(ctx context.Context, tokenHash string) (UserToken, error)
GetActiveUserTokenByHash(ctx context.Context, tokenHash string) (UserToken, error)
GetActiveAutoUserToken(ctx context.Context, userID string) (UserToken, error)
RotateUserToken(ctx context.Context, id string) (int64, error)
RevokeUserToken(ctx context.Context, id string) (int64, error)
UpdateUserTokenLastUsed(ctx context.Context, id string) (int64, error)
}
AuthStore provides access to policies, user-agent assignments, and API tokens.
type AuthStores ¶ added in v0.38.0
type AuthStores struct {
Users UserStore
Logins LoginIdentityStore
Sessions SessionStore
Credentials CredentialStore
}
AuthStores groups the stores needed for a single transactional login flow.
type ChannelIdentity ¶ added in v0.38.0
type ChannelIdentity struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Platform string `json:"platform"`
ExternalID string `json:"external_id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
ChannelIdentity is a messaging-platform identity stored in channel_identity. It replaces the old Identity type for channel-linked accounts (Telegram, Slack, etc.).
type ChannelIdentityStore ¶ added in v0.38.0
type ChannelIdentityStore interface {
CreateChannelIdentity(ctx context.Context, i ChannelIdentity) (ChannelIdentity, error)
GetChannelIdentity(ctx context.Context, id string) (ChannelIdentity, error)
GetChannelIdentityByPlatform(ctx context.Context, platform, externalID string) (ChannelIdentity, error)
ListChannelIdentitiesByUser(ctx context.Context, userID string) ([]ChannelIdentity, error)
UpdateChannelIdentityExternalID(ctx context.Context, id, externalID string) error
DeleteChannelIdentity(ctx context.Context, id string) error
}
ChannelIdentityStore provides CRUD for channel_identity (messaging platform identities).
type Credential ¶ added in v0.38.0
type Credential struct {
ID string `json:"id"`
UserID string `json:"user_id"`
PasswordHash string `json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Credential stores the bcrypt password hash for local password login. It lives in auth_credential and is keyed by user_id (one per user).
type CredentialService ¶ added in v0.38.0
type CredentialService struct {
// contains filtered or unexported fields
}
CredentialService manages local password credentials stored in auth_credential. These credentials are used by Stella's local password login flow.
func NewCredentialService ¶ added in v0.38.0
func NewCredentialService(store CredentialStore) *CredentialService
NewCredentialService creates a CredentialService backed by the given store.
func (*CredentialService) HasCredential ¶ added in v0.38.0
HasCredential reports whether a credential row exists for userID.
func (*CredentialService) SetPassword ¶ added in v0.38.0
func (s *CredentialService) SetPassword(ctx context.Context, userID, plainPassword string) error
SetPassword creates or replaces the local password for a user.
func (*CredentialService) VerifyPassword ¶ added in v0.38.0
func (s *CredentialService) VerifyPassword(ctx context.Context, userID, plainPassword string) error
VerifyPassword checks plainPassword against the stored hash for userID. Returns ErrNotFound if no credential exists, ErrInvalidCredentials on mismatch.
type CredentialStore ¶ added in v0.38.0
type CredentialStore interface {
CreateCredential(ctx context.Context, c Credential) (Credential, error)
GetCredentialByUserID(ctx context.Context, userID string) (Credential, error)
UpdateCredentialHash(ctx context.Context, userID, passwordHash string) error
DeleteCredential(ctx context.Context, userID string) error
}
CredentialStore provides CRUD for auth_credential (local password hashes).
type ExternalIdentity ¶ added in v0.38.0
type ExternalIdentity struct {
Provider string
Subject string
Email string
Name string
AvatarURL string
Claims map[string]any
OAuthToken *OAuthToken // set by OAuth providers; nil for OIDC/local
}
ExternalIdentity is the normalised identity returned by an AuthProvider after a successful callback. It contains all information needed to upsert a User, LoginIdentity, and Membership in ProcessOIDCLogin.
type LinkCodeStore ¶
type LinkCodeStore struct {
// contains filtered or unexported fields
}
LinkCodeStore manages single-use link codes for channel account linking. Codes expire after 5 minutes. The default constructor keeps them in-memory; the shared constructor persists them to the Stella DB for cross-process use.
func NewLinkCodeStore ¶
func NewLinkCodeStore() *LinkCodeStore
NewLinkCodeStore creates a new link code store.
func NewSharedLinkCodeStore ¶
NewSharedLinkCodeStore creates a link code store backed by the shared Stella DB so admin and channel subprocesses can exchange codes across processes.
type LoginIdentity ¶ added in v0.38.0
type LoginIdentity struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Provider string `json:"provider"`
ProviderSubject string `json:"provider_subject"`
Email string `json:"email"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
RawClaims map[string]any `json:"raw_claims,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
LoginIdentity is an OIDC login identity stored in auth_identity. It is named LoginIdentity (not Identity) to avoid a conflict with the pre-existing channel Identity type during the migration period.
type LoginIdentityStore ¶ added in v0.38.0
type LoginIdentityStore interface {
CreateLoginIdentity(ctx context.Context, i LoginIdentity) (LoginIdentity, error)
GetLoginIdentityByProvider(ctx context.Context, provider, providerSubject string) (LoginIdentity, error)
ListLoginIdentitiesByUser(ctx context.Context, userID string) ([]LoginIdentity, error)
UpdateLoginIdentity(ctx context.Context, i LoginIdentity) error
}
LoginIdentityStore provides CRUD for auth_identity (OIDC login identities).
type OAuthToken ¶ added in v0.43.0
type OAuthToken struct {
AccessToken string
RefreshToken string
ExpiresIn int // seconds until access token expires
RefreshTokenExpiresIn int // seconds until refresh token expires
}
OAuthToken carries the raw token from an OAuth login callback so the server can reuse it for tool access when login and tool providers share the same app.
type OIDCLoginResult ¶ added in v0.38.0
type OIDCLoginResult struct {
User User
Session Session
IsNewUser bool
SessionToken string // raw token for the session cookie (not stored in DB)
}
OIDCLoginResult holds everything the HTTP handler needs after a successful login callback.
type PermissionChecker ¶ added in v0.38.0
type PermissionChecker interface {
Can(ctx context.Context, principal Principal, action Action, resource Resource) bool
}
PermissionChecker decides whether a principal may perform an action on a resource. Implementations should be stateless and fast — they are called on every request.
type Policy ¶
type Policy struct {
ID string `json:"id"`
Name string `json:"name"`
Effect string `json:"effect"`
Subjects string `json:"subjects"`
Actions string `json:"actions"`
Resources string `json:"resources"`
Conditions string `json:"conditions"`
Priority int `json:"priority"`
IsSystem bool `json:"is_system"`
Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"`
}
Policy represents an ABAC policy with JSON conditions.
func BuiltinPolicies ¶ added in v0.38.0
func BuiltinPolicies() []Policy
BuiltinPolicies returns the authoritative list of system policies. These are merged with custom DB policies at query time by ListEnabledPolicies.
type PolicyEngine ¶
type PolicyEngine struct {
// contains filtered or unexported fields
}
PolicyEngine evaluates access requests against loaded policies using a deny-overrides algorithm. Policies are loaded once at startup.
func NewEngine ¶
func NewEngine(ctx context.Context, store AuthStore) (*PolicyEngine, error)
NewEngine creates a PolicyEngine by loading all enabled policies from the store. Policies are sorted by priority (descending) for deterministic evaluation.
func NewEngineFromPolicies ¶
func NewEngineFromPolicies(policies []Policy) *PolicyEngine
NewEngineFromPolicies creates a PolicyEngine from a pre-loaded set of policies. Useful for testing.
func (*PolicyEngine) Can ¶
func (e *PolicyEngine) Can(_ context.Context, req AccessRequest) bool
Can returns true if the access request is allowed by the loaded policies. It uses the deny-overrides algorithm:
- Find all policies matching subject roles, action, and resource type
- Evaluate conditions (ABAC) for matching policies
- If ANY matching policy has effect=deny -> deny
- If at least one matching policy has effect=allow -> allow
- No match -> deny (default deny)
func (*PolicyEngine) Must ¶
func (e *PolicyEngine) Must(ctx context.Context, req AccessRequest) error
Must is like Can but returns ErrAccessDenied when the request is denied.
type Principal ¶ added in v0.38.0
type Principal struct {
UserID string `json:"user_id"`
Email string `json:"email"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
Role string `json:"role"` // user role: admin or user
}
Principal is the request-scoped identity injected into context by the auth middleware.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter provides per-IP and per-username rate limiting for login attempts.
func (*RateLimiter) CheckIP ¶
func (rl *RateLimiter) CheckIP(ip string) error
CheckIP verifies the IP has not exceeded the request limit. Does not increment the counter — call RecordIPAttempt after a failed attempt.
func (*RateLimiter) CheckRegistration ¶ added in v0.40.0
func (rl *RateLimiter) CheckRegistration(email string) error
CheckRegistration verifies the email is not in a registration cooldown period.
func (*RateLimiter) CheckUsername ¶
func (rl *RateLimiter) CheckUsername(username string) error
CheckUsername verifies the username is not in a cooldown period.
func (*RateLimiter) RecordIPAttempt ¶
func (rl *RateLimiter) RecordIPAttempt(ip string)
RecordIPAttempt records a failed attempt for rate limiting by IP.
func (*RateLimiter) RecordLoginFailure ¶
func (rl *RateLimiter) RecordLoginFailure(username string)
RecordLoginFailure records a failed login attempt for a username.
func (*RateLimiter) RecordLoginSuccess ¶
func (rl *RateLimiter) RecordLoginSuccess(username string)
RecordLoginSuccess resets the failure counter for a username.
func (*RateLimiter) RecordRegistrationFailure ¶ added in v0.40.0
func (rl *RateLimiter) RecordRegistrationFailure(email string)
RecordRegistrationFailure records a failed registration attempt for an email.
func (*RateLimiter) RecordRegistrationSuccess ¶ added in v0.40.0
func (rl *RateLimiter) RecordRegistrationSuccess(email string)
RecordRegistrationSuccess resets the registration failure counter for an email.
type Resource ¶
type Resource struct {
Type ResourceType `json:"type"`
ID string `json:"id"`
OwnerID string `json:"owner_id"`
Attrs map[string]any `json:"attrs,omitempty"`
}
Resource represents the target of an authorization request.
type ResourceType ¶
type ResourceType string
ResourceType is a string alias for resource types.
const ( ResourceAgent ResourceType = "agent" ResourceAgentList ResourceType = "agent_list" ResourceProvider ResourceType = "provider" ResourceChannel ResourceType = "channel" ResourceSession ResourceType = "session" ResourceUser ResourceType = "user" ResourceUserData ResourceType = "user_data" ResourceSkill ResourceType = "skill" ResourceScheduler ResourceType = "scheduler" ResourceSetting ResourceType = "setting" )
ResourceType constants.
type RoleBasedChecker ¶ added in v0.38.0
type RoleBasedChecker struct{}
RoleBasedChecker is the single-tenant implementation: admin can do anything, regular users can only act on their own resources.
type Session ¶
type Session struct {
ID string `json:"id"`
UserID string `json:"user_id"`
TokenHash string `json:"-"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Session represents an HTTP session. TokenHash is the SHA-256 hash of the raw token stored in the session cookie. Old sessions (auth_sessions table) leave TokenHash empty; new sessions (auth_session table) always have it set.
type SessionManager ¶ added in v0.38.0
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager creates and validates login sessions backed by SessionStore. Raw tokens are stored in cookies; only SHA-256 hashes are stored in the DB.
func NewSessionManager ¶ added in v0.38.0
func NewSessionManager(store SessionStore, vaultKey string) (*SessionManager, error)
NewSessionManager creates a SessionManager. vaultKey is the raw STELLA_VAULT_KEY value; a per-purpose key is derived via HKDF-SHA256.
func (*SessionManager) ClearCookie ¶ added in v0.38.0
func (m *SessionManager) ClearCookie(w http.ResponseWriter)
ClearCookie removes the session cookie from the response.
func (*SessionManager) Create ¶ added in v0.38.0
func (m *SessionManager) Create(ctx context.Context, userID string) (rawToken string, session Session, err error)
Create generates a new session for userID. Returns the raw token to set as a cookie value; only the SHA-256 hash is stored in the DB.
func (*SessionManager) Extend ¶ added in v0.38.0
func (m *SessionManager) Extend(ctx context.Context, sessionID string) error
Extend updates the session expiry to now + SessionDuration.
func (*SessionManager) GetToken ¶ added in v0.38.0
func (m *SessionManager) GetToken(r *http.Request) (string, error)
GetToken extracts the raw token from the request cookie.
func (*SessionManager) Revoke ¶ added in v0.38.0
func (m *SessionManager) Revoke(ctx context.Context, sessionID string) error
Revoke deletes the session from the DB.
func (*SessionManager) SetCookie ¶ added in v0.38.0
func (m *SessionManager) SetCookie(w http.ResponseWriter, rawToken string, secure bool)
SetCookie writes the session token cookie to the response.
func (*SessionManager) Validate ¶ added in v0.38.0
Validate looks up the session by the SHA-256 hash of rawToken and returns it. Returns an error if the session is not found or has expired.
func (*SessionManager) WithStore ¶ added in v0.38.0
func (m *SessionManager) WithStore(store SessionStore) *SessionManager
WithStore returns a shallow copy of the SessionManager backed by a different SessionStore. Used to run session creation inside a DB transaction.
type SessionStore ¶ added in v0.38.0
type SessionStore interface {
CreateSession(ctx context.Context, s Session) (Session, error)
GetSessionByTokenHash(ctx context.Context, tokenHash string) (Session, error)
DeleteSession(ctx context.Context, id string) error
DeleteExpiredSessions(ctx context.Context) error
DeleteUserSessions(ctx context.Context, userID string) error
UpdateSessionExpiry(ctx context.Context, id string, expiresAt time.Time) error
GetSession(ctx context.Context, id string) (Session, error)
ListSessionsByUser(ctx context.Context, userID string) ([]Session, error)
}
SessionStore provides CRUD for auth_session (token-hash-based sessions).
type Subject ¶
type Subject struct {
UserID string `json:"user_id"`
Roles []string `json:"roles"`
AgentIDs []string `json:"agent_ids"`
Attrs map[string]any `json:"attrs,omitempty"`
}
Subject represents the entity requesting access.
type TokenService ¶
type TokenService struct {
// contains filtered or unexported fields
}
TokenService owns API token lifecycle and authentication.
func NewTokenService ¶
func NewTokenService(store tokenStore, vault VaultWriter) *TokenService
NewTokenService creates a token service backed by auth persistence and vault writes.
func (*TokenService) Authenticate ¶
Authenticate returns the active user identified by rawToken.
func (*TokenService) AuthenticateScoped ¶ added in v0.41.3
func (s *TokenService) AuthenticateScoped(ctx context.Context, rawToken string) (User, pkgauth.ScopedTokenClaims, error)
AuthenticateScoped returns the active user and scoped claims identified by rawToken.
func (*TokenService) CreateScopedToken ¶ added in v0.41.3
func (s *TokenService) CreateScopedToken(ctx context.Context, userID, agentID, sessionID, projectID string) (string, error)
CreateScopedToken signs a short-lived sandbox token bound to one user-agent session. For group sessions, userID is a group principal ("group:{group_id}") and the token is signed without an auth user lookup — the group principal is not a human user, so GetUser would fail.
func (*TokenService) EnsureAutoToken ¶
func (s *TokenService) EnsureAutoToken(ctx context.Context, userID string) error
EnsureAutoToken ensures userID has one active auto-generated token whose vault plaintext matches the DB token hash. Concurrent callers are serialized so the vault never exposes an unrecorded loser token between ensure and env load.
func (*TokenService) EnsureAutoTokenEnv ¶ added in v0.38.3
func (s *TokenService) EnsureAutoTokenEnv(ctx context.Context, userID string) (map[string]string, error)
EnsureAutoTokenEnv ensures the auto token and returns the user's vault env under the same lock, so sandbox env injection cannot observe a transient token written by a concurrent loser.
The vault is decrypted once up front and reused for both token validation and the returned env; it is reloaded only when ensure actually wrote to the vault (token created or rotated). This collapses the two full-vault decrypts the path used to do per sandbox start into one in the steady state.
func (*TokenService) EnsureAutoTokenEnvForAgent ¶ added in v0.48.0
func (s *TokenService) EnsureAutoTokenEnvForAgent(ctx context.Context, userID string, agentID string) (map[string]string, error)
EnsureAutoTokenEnvForAgent ensures the auto token and returns scoped runtime env under the same lock, preserving the token/env atomicity guarantee while allowing agent-specific vault scopes to participate in sandbox env resolution.
type Transactioner ¶ added in v0.38.0
type Transactioner interface {
BeginAuthTx(ctx context.Context) (stores AuthStores, commit func() error, rollback func(), err error)
}
Transactioner is an optional interface that store implementations may satisfy to run ProcessOIDCLogin atomically. OIDCStore implements this.
type User ¶ added in v0.38.0
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
Role string `json:"role"`
DefaultAgentID string `json:"default_agent_id,omitempty"`
NotifyIdentityID *string `json:"notify_identity_id,omitempty"`
IsActive bool `json:"is_active"`
AgePublicKey string `json:"-"`
AgePrivateKey string `json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
User is the OIDC-based user record stored in auth_user.
type UserStore ¶ added in v0.38.0
type UserStore interface {
CreateUser(ctx context.Context, u User) (User, error)
GetUser(ctx context.Context, id string) (User, error)
GetUserByEmail(ctx context.Context, email string) (User, error)
ListUsers(ctx context.Context) ([]User, error)
ListUsersPaged(ctx context.Context, limit, offset int64) ([]User, error)
UpdateUser(ctx context.Context, u User) error
DeleteUser(ctx context.Context, id string) error
CountUsers(ctx context.Context) (int64, error)
UpdateUserAgeKeys(ctx context.Context, userID, publicKey, privateKey string) error
UpdateUserDefaultAgent(ctx context.Context, userID, agentID string) error
UpdateUserNotifyIdentity(ctx context.Context, userID string, identityID *string) error
UpdateUserRole(ctx context.Context, userID string, role string) error
UpdateUserActive(ctx context.Context, userID string, isActive bool) error
}
UserStore provides CRUD for auth_user.
type UserToken ¶
type UserToken struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Name string `json:"name"`
TokenHash string `json:"-"`
TokenPrefix string `json:"token_prefix"`
AutoGenerated bool `json:"auto_generated"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
RotatedAt *time.Time `json:"rotated_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
UserToken represents an API token owned by a user.