Documentation
¶
Index ¶
- Constants
- Variables
- func HashOpaqueToken(raw string) string
- func IsPlatformAdmin(role string) bool
- func NewOpaqueToken() (raw, hash string, err error)
- type AssertionExchanger
- type AuthStarter
- type ExternalIdentity
- type ExternalIdentityRepository
- type FederatedClaims
- type FederationProvider
- type PasswordHasher
- type PasswordResetRepository
- type PasswordResetToken
- type ResolveDeps
- type SSOState
- type SSOStateStore
- type ServiceProviderMeta
- type TokenIssuer
- type User
- type UserRepository
Constants ¶
const ( RoleAdmin = "admin" RoleMember = "member" )
Platform user roles (users.role). Distinct from org/team membership roles.
const DefaultPasswordResetTTL = time.Hour
Variables ¶
var ( ErrInvalidCredentials = errors.New("invalid credentials") ErrSSODisabled = errors.New("sso disabled") ErrSignupDisabled = errors.New("signup disabled") ErrUnknownProvider = errors.New("unknown sso provider") ErrInvalidSSOState = errors.New("invalid or expired sso state") ErrInvalidResetToken = errors.New("invalid or expired reset token") )
Domain sentinel errors for AuthN.
var ErrEmailNotVerified = errors.New("email not verified")
ErrEmailNotVerified is returned when JIT provisioning requires a verified email.
var ErrMissingFederatedEmail = errors.New("federated email required")
ErrMissingFederatedEmail is returned when claims lack an email address.
var ErrMissingFederatedSubject = errors.New("federated subject required")
ErrMissingFederatedSubject is returned when claims lack a subject.
Functions ¶
func HashOpaqueToken ¶
HashOpaqueToken returns the hex-encoded SHA-256 of the raw token.
func IsPlatformAdmin ¶ added in v0.3.0
IsPlatformAdmin reports whether the user may manage platform topology (regions/deployments).
func NewOpaqueToken ¶
NewOpaqueToken generates an opaque token and its hash (same shape as invite tokens).
Types ¶
type AssertionExchanger ¶
type AssertionExchanger interface {
ExchangeAssertion(ctx context.Context, response, redirectURI string, possibleRequestIDs []string) (FederatedClaims, error)
}
AssertionExchanger is an optional FederationProvider extension for SAML ACS. possibleRequestIDs should include the AuthnRequest ID from BeginSSO (and "" when IdP-initiated is allowed).
type AuthStarter ¶
type AuthStarter interface {
AuthURLWithID(state, redirectURI string) (authURL, requestID string, err error)
}
AuthStarter is an optional FederationProvider extension used by SAML to return the AuthnRequest ID for InResponseTo validation on ACS.
type ExternalIdentity ¶
type ExternalIdentity struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Provider string `json:"provider"`
Issuer string `json:"issuer"`
Subject string `json:"subject"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
ExternalIdentity links a platform user to a federated IdP subject. Uniqueness is (Provider, Subject).
type ExternalIdentityRepository ¶
type ExternalIdentityRepository interface {
GetByProviderSubject(ctx context.Context, provider, subject string) (*ExternalIdentity, error)
Create(ctx context.Context, identity ExternalIdentity) error
}
ExternalIdentityRepository persists federated IdP linkages.
type FederatedClaims ¶
type FederatedClaims struct {
Provider string
Issuer string
Subject string
Email string
EmailVerified bool
Name string
}
FederatedClaims are protocol-agnostic identity assertions from an IdP. OAuth2, OIDC, and (later) SAML adapters all map into this shape.
type FederationProvider ¶
type FederationProvider interface {
// Name returns the configured provider id (e.g. "google").
Name() string
// DisplayName is a human-readable label for the login UI.
DisplayName() string
// Type is the protocol kind: "oidc", "oauth2", or "saml".
Type() string
// AuthURL builds the IdP authorization redirect URL for the given CSRF state.
AuthURL(state, redirectURI string) (string, error)
// Exchange trades an authorization code (or mapped SAMLResponse) for FederatedClaims.
Exchange(ctx context.Context, code, redirectURI string) (FederatedClaims, error)
}
FederationProvider is a protocol-agnostic SSO IdP adapter. OAuth2/OIDC and SAML 2.0 implement this port. SAML ACS maps the assertion payload at the HTTP edge into Exchange / AssertionExchanger.
type PasswordHasher ¶
type PasswordHasher interface {
Hash(password string) (string, error)
Check(hash, password string) bool
}
PasswordHasher hashes and verifies local passwords.
type PasswordResetRepository ¶
type PasswordResetRepository interface {
Create(ctx context.Context, token PasswordResetToken) error
DeleteUnusedForUser(ctx context.Context, userID string) error
GetByTokenHash(ctx context.Context, hash string) (*PasswordResetToken, error)
Consume(ctx context.Context, id string, usedAt time.Time) error
}
PasswordResetRepository stores opaque password-reset tokens (hash only).
type PasswordResetToken ¶
type PasswordResetToken struct {
ID string
UserID string
TokenHash string
ExpiresAt time.Time
CreatedAt time.Time
UsedAt *time.Time
}
PasswordResetToken is a stored reset challenge (hash only; raw token is emailed).
type ResolveDeps ¶
type ResolveDeps struct {
Users UserRepository
Identities ExternalIdentityRepository
NewUserID func() string
NewLinkID func() string
Now func() time.Time
}
ResolveDeps are persistence ports for ResolveOrProvisionUser.
type SSOState ¶
type SSOState struct {
Provider string
ReturnTo string
RequestID string // SAML AuthnRequest ID (empty for OAuth/OIDC)
ExpiresAt time.Time
}
SSOState holds short-lived CSRF state for an SSO login attempt.
type SSOStateStore ¶
type SSOStateStore interface {
Put(ctx context.Context, state string, value SSOState) error
// Take atomically loads and deletes state. Returns kernel.ErrNotFound when missing/expired.
Take(ctx context.Context, state string) (SSOState, error)
}
SSOStateStore stores CSRF state between begin and complete SSO. Implementations must be safe for multi-instance control planes (shared backend).
type ServiceProviderMeta ¶
ServiceProviderMeta is implemented by SAML adapters that expose SP metadata XML.
type TokenIssuer ¶
TokenIssuer creates platform session JWTs.
type User ¶
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Role string `json:"role"`
PasswordHash string `json:"-"`
CreatedAt time.Time `json:"created_at"`
}
User is a platform identity record.
func ResolveOrProvisionUser ¶
func ResolveOrProvisionUser(ctx context.Context, deps ResolveDeps, claims FederatedClaims) (*User, error)
ResolveOrProvisionUser finds or creates a platform user from federated claims (JIT).
Resolution order:
- Existing ExternalIdentity by (provider, subject)
- Verified email matches existing user → link identity
- JIT-create user (role member, no password) + link identity
Unverified email is rejected when no prior link exists.
type UserRepository ¶
type UserRepository interface {
GetByEmail(ctx context.Context, email string) (*User, error)
GetByID(ctx context.Context, id string) (*User, error)
Create(ctx context.Context, user User) error
UpdatePassword(ctx context.Context, userID, passwordHash string) error
}
UserRepository loads and creates platform users.