auth

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EffectiveUserID

func EffectiveUserID(ctx context.Context) string

EffectiveUserID returns a stable user identifier from context. Delegates to the internal auth package.

func InjectTokens

func InjectTokens(ctx context.Context, tokens *scyauth.Token) context.Context

InjectTokens stores OAuth tokens in context so that MCPAuthToken and downstream MCP clients can forward the logged-in user's token. External auth middleware (outside this module) should call this after authenticating the user from a session or JWT.

func InjectUser

func InjectUser(ctx context.Context, subject string) context.Context

InjectUser stores user identity in context using the agently-core auth key. External middleware (outside this module) can call this to bridge their own auth context into the context key that EffectiveUserID reads.

func MCPAuthToken

func MCPAuthToken(ctx context.Context, useIDToken bool) string

MCPAuthToken selects a single token string suitable for outbound MCP calls. Delegates to the internal auth package.

func NewTokenStoreAdapter

func NewTokenStoreAdapter(store TokenStore) token.TokenStore

NewTokenStoreAdapter wraps a service/auth.TokenStore to satisfy token.TokenStore.

func Protect

func Protect(cfg *iauth.Config, sessions *Manager, opts ...ProtectOption) func(http.Handler) http.Handler

func ProtectWithTokenProvider

func ProtectWithTokenProvider(cfg *iauth.Config, sessions *Manager, tp token.Provider, opts ...ProtectOption) func(http.Handler) http.Handler

Protect returns middleware that extracts auth credentials from the request (Bearer token or session cookie) and populates the request context with identity information via the internal/auth context helpers.

Requests to /v1/api/auth/* and OPTIONS are passed through without auth. When JWT auth is configured, Bearer tokens are cryptographically verified.

ProtectWithTokenProvider is like Protect but also stores session tokens in the given token.Provider so they are available for subsequent requests from that user.

Types

type Handler

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

Handler serves auth-related HTTP endpoints. It is designed to be mounted under /v1/api/auth/* on the application router.

func NewHandler

func NewHandler(cfg *iauth.Config, sessions *Manager, opts ...HandlerOption) *Handler

NewHandler creates an auth HTTP handler.

func (*Handler) Register

func (h *Handler) Register(mux *http.ServeMux)

Register mounts auth routes on the given mux.

func (*Handler) RegisterPreferences

func (h *Handler) RegisterPreferences(mux *http.ServeMux)

RegisterPreferences mounts preference endpoints on the given mux. These endpoints require the auth middleware to populate user context.

type HandlerOption

type HandlerOption func(*Handler)

HandlerOption customises the auth Handler.

func WithTokenProvider

func WithTokenProvider(tp token.Provider) HandlerOption

WithTokenProvider injects a shared token lifecycle manager.

func WithTokenStore

func WithTokenStore(ts TokenStore) HandlerOption

WithTokenStore injects an OAuth token store.

func WithUserService

func WithUserService(us UserService) HandlerOption

WithUserService injects a user service.

type JWTService

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

JWTService wraps scy's JWT signer and verifier for the agently-core auth layer.

func NewJWTService

func NewJWTService(cfg *iauth.JWT) *JWTService

NewJWTService creates a JWT service from the given config. Call Init() before use to load keys.

func NewJWTServiceFromConfigValues added in v0.1.1

func NewJWTServiceFromConfigValues(enabled bool, rsa []string, hmac, certURL, rsaPrivateKey string) *JWTService

NewJWTServiceFromConfigValues creates a JWT service from raw config values for callers outside agently-core that cannot import the internal auth package.

func (*JWTService) Init

func (j *JWTService) Init(ctx context.Context) error

Init loads keys from scy resources. Safe to call multiple times.

func (*JWTService) PublicKeys

func (j *JWTService) PublicKeys() (map[string]*rsa.PublicKey, error)

PublicKeys returns the loaded RSA public keys (for diagnostics/testing).

func (*JWTService) Sign

func (j *JWTService) Sign(ttl time.Duration, claims interface{}) (string, error)

Sign creates a signed JWT token with the given claims and TTL. Returns an error if no signer is configured.

func (*JWTService) Verify

func (j *JWTService) Verify(ctx context.Context, tokenString string) (*iauth.UserInfo, error)

Verify validates a JWT token string and returns the parsed claims. Returns an error if the token is invalid, expired, or signature verification fails.

type Manager

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

Manager manages user sessions with an in-memory cache and optional persistent store.

func NewManager

func NewManager(ttl time.Duration, store SessionStore) *Manager

NewManager creates a session manager with the given TTL. If store is nil, sessions are stored only in memory.

func (*Manager) ActiveSessions

func (m *Manager) ActiveSessions() []*Session

ActiveSessions returns a snapshot of all non-expired sessions in memory.

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context, id string)

Delete removes a session.

func (*Manager) Get

func (m *Manager) Get(ctx context.Context, id string) *Session

Get retrieves a session by ID. Returns nil if not found or expired.

func (*Manager) Put

func (m *Manager) Put(ctx context.Context, s *Session)

Put stores a session.

type OAuthToken

type OAuthToken struct {
	Username     string    `json:"username"`
	Provider     string    `json:"provider"`
	AccessToken  string    `json:"accessToken"`
	IDToken      string    `json:"idToken,omitempty"`
	RefreshToken string    `json:"refreshToken,omitempty"`
	ExpiresAt    time.Time `json:"expiresAt,omitempty"`
}

OAuthToken represents a stored OAuth token set for a user/provider pair.

type PreferencesPatch

type PreferencesPatch struct {
	DisplayName        *string                           `json:"displayName,omitempty"`
	Timezone           *string                           `json:"timezone,omitempty"`
	DefaultAgentRef    *string                           `json:"defaultAgentRef,omitempty"`
	DefaultModelRef    *string                           `json:"defaultModelRef,omitempty"`
	DefaultEmbedderRef *string                           `json:"defaultEmbedderRef,omitempty"`
	AgentPrefs         map[string]map[string]interface{} `json:"agentPrefs,omitempty"`
}

PreferencesPatch describes a partial update to user preferences.

type ProtectOption

type ProtectOption func(*protectConfig)

ProtectOption customises the Protect middleware.

func WithJWTService

func WithJWTService(j *JWTService) ProtectOption

WithJWTService injects a pre-initialised JWTService for Bearer token verification.

type Session

type Session struct {
	ID        string         `json:"id"`
	Username  string         `json:"username"`
	Email     string         `json:"email,omitempty"`
	Subject   string         `json:"subject,omitempty"`
	Tokens    *scyauth.Token `json:"-"`
	CreatedAt time.Time      `json:"createdAt"`
	ExpiresAt time.Time      `json:"expiresAt"`
}

Session represents an authenticated user session.

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired returns true when the session has passed its expiry time.

type SessionRecord

type SessionRecord struct {
	ID           string    `json:"id"`
	Username     string    `json:"username"`
	Email        string    `json:"email,omitempty"`
	Subject      string    `json:"subject,omitempty"`
	AccessToken  string    `json:"accessToken,omitempty"`
	IDToken      string    `json:"idToken,omitempty"`
	RefreshToken string    `json:"refreshToken,omitempty"`
	CreatedAt    time.Time `json:"createdAt"`
	ExpiresAt    time.Time `json:"expiresAt"`
}

SessionRecord is the persistent form of a session for external stores.

type SessionStore

type SessionStore interface {
	Get(ctx context.Context, id string) (*SessionRecord, error)
	Upsert(ctx context.Context, rec *SessionRecord) error
	Delete(ctx context.Context, id string) error
}

SessionStore is a pluggable backend for persistent session storage.

type SessionStoreDAO

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

SessionStoreDAO uses Datly to persist sessions.

func NewSessionStoreDAO

func NewSessionStoreDAO(dao *datly.Service) *SessionStoreDAO

NewSessionStoreDAO constructs a Datly-backed session store.

func (*SessionStoreDAO) Delete

func (s *SessionStoreDAO) Delete(ctx context.Context, id string) error

Delete removes a session by id.

func (*SessionStoreDAO) Get

Get loads a session by id.

func (*SessionStoreDAO) Upsert

func (s *SessionStoreDAO) Upsert(ctx context.Context, rec *SessionRecord) error

Upsert inserts or updates a session record.

type TokenStore

type TokenStore interface {
	Get(ctx context.Context, username, provider string) (*OAuthToken, error)
	Put(ctx context.Context, token *OAuthToken) error
	Delete(ctx context.Context, username, provider string) error

	// TryAcquireRefreshLease atomically attempts to acquire a distributed lease
	// for refreshing the token identified by (username, provider).
	TryAcquireRefreshLease(ctx context.Context, username, provider, owner string, ttl time.Duration) (version int64, acquired bool, err error)

	// ReleaseRefreshLease releases a previously acquired lease.
	ReleaseRefreshLease(ctx context.Context, username, provider, owner string) error

	// CASPut atomically updates the token only if the current version matches
	// expectedVersion and the lease is held by owner.
	CASPut(ctx context.Context, token *OAuthToken, expectedVersion int64, owner string) (swapped bool, err error)
}

TokenStore abstracts encrypted OAuth token persistence. Implementations may use scy-backed secrets, database storage, etc.

type TokenStoreDAO

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

TokenStoreDAO is a Datly-backed TokenStore with Blowfish encryption.

func NewTokenStoreDAO

func NewTokenStoreDAO(dao *datly.Service, salt string) *TokenStoreDAO

NewTokenStoreDAO creates a Datly-backed token store.

func (*TokenStoreDAO) CASPut

func (s *TokenStoreDAO) CASPut(ctx context.Context, token *OAuthToken, expectedVersion int64, owner string) (bool, error)

CASPut atomically updates the token only if the current version matches expectedVersion and the lease is held by owner. On success, bumps version and clears the lease. Returns (true, nil) if the swap succeeded.

func (*TokenStoreDAO) Delete

func (s *TokenStoreDAO) Delete(ctx context.Context, username, provider string) error

Delete removes a token by upserting an empty enc_token.

func (*TokenStoreDAO) Get

func (s *TokenStoreDAO) Get(ctx context.Context, username, provider string) (*OAuthToken, error)

Get loads and decrypts a token from DB.

func (*TokenStoreDAO) Put

func (s *TokenStoreDAO) Put(ctx context.Context, token *OAuthToken) error

Put encrypts and saves a token via the Datly write handler.

func (*TokenStoreDAO) ReleaseRefreshLease

func (s *TokenStoreDAO) ReleaseRefreshLease(ctx context.Context, username, provider, owner string) error

ReleaseRefreshLease releases a previously acquired lease, resetting the row to idle. The owner check ensures we only release our own lease.

func (*TokenStoreDAO) TryAcquireRefreshLease

func (s *TokenStoreDAO) TryAcquireRefreshLease(ctx context.Context, username, provider, owner string, ttl time.Duration) (int64, bool, error)

TryAcquireRefreshLease atomically attempts to acquire a distributed lease for refreshing the token identified by (username, provider). The lease is granted only when the row is idle or has an expired lease. All timestamp comparisons use the DB server's CURRENT_TIMESTAMP to avoid clock-skew issues.

type User

type User struct {
	Username    string                 `json:"username"`
	Email       string                 `json:"email,omitempty"`
	DisplayName string                 `json:"displayName,omitempty"`
	Subject     string                 `json:"subject,omitempty"`
	Preferences map[string]interface{} `json:"preferences,omitempty"`
}

User represents a registered user.

type UserService

type UserService interface {
	GetByUsername(ctx context.Context, username string) (*User, error)
	Upsert(ctx context.Context, user *User) error
	UpdatePreferences(ctx context.Context, username string, patch *PreferencesPatch) error
}

UserService abstracts user CRUD. Implementations may use Datly, SQL, or an in-memory store.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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