identity

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RoleAdmin  = "admin"
	RoleMember = "member"
)

Platform user roles (users.role). Distinct from org/team membership roles.

View Source
const DefaultPasswordResetTTL = time.Hour

Variables

View Source
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.

View Source
var ErrEmailNotVerified = errors.New("email not verified")

ErrEmailNotVerified is returned when JIT provisioning requires a verified email.

View Source
var ErrMissingFederatedEmail = errors.New("federated email required")

ErrMissingFederatedEmail is returned when claims lack an email address.

View Source
var ErrMissingFederatedSubject = errors.New("federated subject required")

ErrMissingFederatedSubject is returned when claims lack a subject.

Functions

func HashOpaqueToken

func HashOpaqueToken(raw string) string

HashOpaqueToken returns the hex-encoded SHA-256 of the raw token.

func IsPlatformAdmin added in v0.3.0

func IsPlatformAdmin(role string) bool

IsPlatformAdmin reports whether the user may manage platform topology (regions/deployments).

func NewOpaqueToken

func NewOpaqueToken() (raw, hash string, err error)

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

type ServiceProviderMeta interface {
	MetadataXML() ([]byte, error)
}

ServiceProviderMeta is implemented by SAML adapters that expose SP metadata XML.

type TokenIssuer

type TokenIssuer interface {
	Issue(userID, email, role string) (string, error)
}

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:

  1. Existing ExternalIdentity by (provider, subject)
  2. Verified email matches existing user → link identity
  3. 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.

Jump to

Keyboard shortcuts

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