Documentation
¶
Index ¶
- Constants
- Variables
- func AuthCheckTypeStrings() []string
- func BuildPasskeyCreationOptions(c *AuthChallengePasskeyRegistration) ([]byte, error)
- func BuildPasskeyRequestOptions(c *AuthChallengePasskey) ([]byte, error)
- func CheckAs[T AuthFactor](attempt *AuthAttempt, typ AuthCheckType) (T, bool)
- func DecodePasskeyCredentialID(s string) []byte
- func DesignatedAttributeKeys(schemaDocument []byte) []string
- func DesignatedDisplay(document []byte) []string
- func DesignatedIdentifier(document []byte) string
- func EncodePasskeyCredentialID(id []byte) string
- func FieldsToStrings(f []Field) []string
- func FlattenValidationErrors(err error) map[string]string
- func FlowActionKindStrings() []string
- func FlowDefinitionPurposeStrings() []string
- func FlowDefinitionStatusStrings() []string
- func FlowDefinitionTransitionActionStrings() []string
- func FlowGateKindStrings() []string
- func FlowOnSuccessStrings() []string
- func FlowStepCompleteStrings() []string
- func FlowStepErrorAllowed(key string) bool
- func GeneratePasskeyCredentialName(transports []string, backupEligible bool) string
- func HashClaimChallengeToken(plain string) string
- func HashPassword(password string, hasher crypto.Hasher) (string, error)
- func HashSecret(plain string) string
- func ImplicitOutcomesForChallenge(c FlowFieldChallenge) []string
- func JSONSchemaKindStrings() []string
- func NewClaimChallengeToken() (plain, id string, err error)
- func PasskeysToCredentials(passkeys []*UserPasskey) []webauthn.Credential
- func RequireNonEmptyRecoveryCodes(codes []string) error
- func ResolveSessionTTL(requested *time.Duration, defaultTTL, maxTTL time.Duration) (time.Duration, error)
- func TeamBoundObjectType(objectType string) bool
- func TokenTypeStrings() []string
- func UniqueValueHash(value any) ([sha256.Size]byte, error)
- func ValidateBranding(b *Branding) error
- func ValidateEnvironmentName(name string) (string, error)
- func ValidateSessionToken(token *Token) error
- func ValidateTeamName(name string) (string, error)
- func WriteBuiltinJSONSchema(w io.Writer, schemaPath string, canonicalDocumentURL string) error
- type Attribute
- type AttributeKey
- type AttributeUniqueness
- type Attributes
- type AuthAttempt
- func (a *AuthAttempt) ChallengeByID(id string) (AuthChallenge, bool)
- func (a *AuthAttempt) ChallengeByType(typ AuthCheckType) (AuthChallenge, bool)
- func (a *AuthAttempt) ExpiresAt() time.Time
- func (a *AuthAttempt) FactorByClass(typ AuthCheckType) (AuthFactor, bool)
- func (a *AuthAttempt) FactorByType(typ AuthCheckType) (AuthFactor, bool)
- func (a *AuthAttempt) HasProvisionalRegistrationHandle(userID string) bool
- func (a *AuthAttempt) IsCompleted() bool
- func (a *AuthAttempt) IsExpired() bool
- func (a *AuthAttempt) IsHandedOff() bool
- func (a *AuthAttempt) PrepareChallenge(typ AuthCheckType) error
- func (a *AuthAttempt) PrepareHandoff() error
- func (a *AuthAttempt) PreparePasskeyChallenge() (string, error)
- func (a *AuthAttempt) PreparePasskeyRegistrationChallenge(requestedUserID string) (userID string, provisional bool, err error)
- func (a *AuthAttempt) PreparePasskeyRegistrationVerification(challengeID string) (*AuthChallengePasskeyRegistration, error)
- func (a *AuthAttempt) PreparePasskeyVerification(challengeID string) (AuthChallenge, *AuthFactorUser, error)
- func (a *AuthAttempt) PreparePasswordChallenge() error
- func (a *AuthAttempt) PreparePasswordVerification(challengeID string) (AuthChallenge, *AuthFactorUser, error)
- func (a *AuthAttempt) PrepareUserChallenge() error
- func (a *AuthAttempt) PrepareUserVerification(challengeID string) (AuthChallenge, error)
- func (a *AuthAttempt) PrepareVerification(challengeID string, checkType AuthCheckType) (AuthChallenge, error)
- func (a *AuthAttempt) SetCheck(check AuthCheck)
- func (a *AuthAttempt) SetPasskeyChallenge(passkeyChallenge *PasskeyChallenge) *AuthChallengePasskey
- func (a *AuthAttempt) SetPasskeyFactor(passkeyVerification *PasskeyVerification) *AuthFactorPasskey
- func (a *AuthAttempt) SetPasskeyRegistrationChallenge(registrationChallenge *PasskeyRegistrationChallenge, provisional bool) *AuthChallengePasskeyRegistration
- func (a *AuthAttempt) SetPasskeyRegistrationFactor(passkey *CreateUserPasskey) *AuthFactorPasskeyRegistration
- func (a *AuthAttempt) SetPasswordChallenge() *AuthChallengePassword
- func (a *AuthAttempt) SetPasswordFactor() *AuthFactorPassword
- func (a *AuthAttempt) SetUserChallenge() *AuthChallengeUser
- func (a *AuthAttempt) SetUserFactor(user *User) *AuthFactorUser
- type AuthAttemptCreatedPayload
- type AuthAttemptHandedOffPayload
- type AuthAttemptOption
- type AuthChallenge
- type AuthChallengePasskey
- func (a *AuthChallengePasskey) GetFailureCount() uint16
- func (a *AuthChallengePasskey) GetID() string
- func (a *AuthChallengePasskey) GetLastChallengedAt() time.Time
- func (a *AuthChallengePasskey) GetLastFailedAt() time.Time
- func (a *AuthChallengePasskey) Payload() any
- func (a *AuthChallengePasskey) SetFailureCount(failureCount uint16)
- func (a *AuthChallengePasskey) SetID(id string)
- func (a *AuthChallengePasskey) SetLastChallengedAt(lastChallengedAt time.Time)
- func (a *AuthChallengePasskey) SetLastFailedAt(lastFailedAt time.Time)
- func (a *AuthChallengePasskey) Type() AuthCheckType
- type AuthChallengePasskeyRegistration
- func (a *AuthChallengePasskeyRegistration) GetFailureCount() uint16
- func (a *AuthChallengePasskeyRegistration) GetID() string
- func (a *AuthChallengePasskeyRegistration) GetLastChallengedAt() time.Time
- func (a *AuthChallengePasskeyRegistration) GetLastFailedAt() time.Time
- func (a *AuthChallengePasskeyRegistration) Payload() any
- func (a *AuthChallengePasskeyRegistration) SetFailureCount(failureCount uint16)
- func (a *AuthChallengePasskeyRegistration) SetID(id string)
- func (a *AuthChallengePasskeyRegistration) SetLastChallengedAt(lastChallengedAt time.Time)
- func (a *AuthChallengePasskeyRegistration) SetLastFailedAt(lastFailedAt time.Time)
- func (a *AuthChallengePasskeyRegistration) Type() AuthCheckType
- type AuthChallengePassword
- func (a *AuthChallengePassword) GetFailureCount() uint16
- func (a *AuthChallengePassword) GetID() string
- func (a *AuthChallengePassword) GetLastChallengedAt() time.Time
- func (a *AuthChallengePassword) GetLastFailedAt() time.Time
- func (a *AuthChallengePassword) Payload() any
- func (a *AuthChallengePassword) SetFailureCount(failureCount uint16)
- func (a *AuthChallengePassword) SetID(id string)
- func (a *AuthChallengePassword) SetLastChallengedAt(lastChallengedAt time.Time)
- func (a *AuthChallengePassword) SetLastFailedAt(lastFailedAt time.Time)
- func (a *AuthChallengePassword) Type() AuthCheckType
- type AuthChallengeUser
- func (a *AuthChallengeUser) GetFailureCount() uint16
- func (a *AuthChallengeUser) GetID() string
- func (a *AuthChallengeUser) GetLastChallengedAt() time.Time
- func (a *AuthChallengeUser) GetLastFailedAt() time.Time
- func (a *AuthChallengeUser) Payload() any
- func (a *AuthChallengeUser) SetFailureCount(failureCount uint16)
- func (a *AuthChallengeUser) SetID(id string)
- func (a *AuthChallengeUser) SetLastChallengedAt(lastChallengedAt time.Time)
- func (a *AuthChallengeUser) SetLastFailedAt(lastFailedAt time.Time)
- func (a *AuthChallengeUser) Type() AuthCheckType
- type AuthCheck
- type AuthCheckPayload
- type AuthCheckType
- type AuthFactor
- type AuthFactorPasskey
- type AuthFactorPasskeyRegistration
- type AuthFactorPassword
- type AuthFactorPayload
- type AuthFactorUser
- type AuthTokenIssuedPayload
- type AuthTokenRevokedPayload
- type AuthzAssignment
- type AuthzAssignmentScope
- type AuthzCatalog
- type AuthzCatalogKind
- type AuthzCatalogStatus
- type AuthzCatalogVersion
- type AuthzCheckParams
- type AuthzExpressionEdge
- type AuthzGrantedPayload
- type AuthzListObjectsParams
- type AuthzMemberType
- type AuthzMembershipEdge
- type AuthzMembershipEdgeField
- type AuthzMembershipEdgeKey
- type AuthzPrincipalType
- type AuthzRelation
- type AuthzRelationClosure
- type AuthzRelationKind
- type AuthzRelationReference
- type AuthzRevokedPayload
- type AuthzScopeKind
- type AuthzSetType
- type Branding
- type BrandingCreatedPayload
- type BrandingField
- type BrandingPayload
- type ClaimChallenge
- type ClaimChallengeCreatedPayload
- type ClaimChallengeStatus
- type ClaimCompletedPayload
- type ClaimConflictDetails
- type CollectedAuthMethodData
- type CollectedFlowData
- type CreateAttribute
- type CreateAttributes
- type CreateRecoveryCodes
- type CreateUser
- type CreateUserParams
- type CreateUserPasskey
- type CreateUserTOTP
- type CreatedUserDetails
- type EncryptionKey
- func (k *EncryptionKey) Activate(currentKey *EncryptionKey)
- func (k *EncryptionKey) Crypter(kek crypto.Crypter) (crypto.Crypter, error)
- func (k *EncryptionKey) DecryptedKey(kek crypto.Decrypter) ([32]byte, error)
- func (k *EncryptionKey) IsActive() bool
- func (k *EncryptionKey) IsRemoved() bool
- func (k *EncryptionKey) MigrateToNewMasterKey(oldMasterKey crypto.Crypter, newMasterKey crypto.Crypter) error
- type EncryptionKeyField
- type EncryptionKeyPurpose
- type Environment
- type EnvironmentCreatedPayload
- type EnvironmentField
- type EnvironmentPayload
- type Error
- func ErrAuthAttemptAlreadyCompleted() Error
- func ErrAuthAttemptAlreadyHandedOff() Error
- func ErrAuthAttemptInvalidProof() Error
- func ErrAuthAttemptInvalidRequest() Error
- func ErrAuthAttemptInvalidState() Error
- func ErrAuthAttemptNotCompleted() Error
- func ErrAuthAttemptNotFound() Error
- func ErrAuthAttemptProofRejected(err error) Error
- func ErrAuthAttemptStaleChallenge() Error
- func ErrAuthUnauthorized(err error) Error
- func ErrBrandingInvalid(details any, parent error) Error
- func ErrBrandingMissingProjectID() Error
- func ErrBrandingNotFound() Error
- func ErrBrandingPermissionDenied() Error
- func ErrClaimChallengeInvalid() Error
- func ErrClaimChallengeNotFound() Error
- func ErrClaimNoPersonalTeam() Error
- func ErrClaimSessionExpired() Error
- func ErrClaimSessionNotActive() Error
- func ErrClaimSessionWrongProject() Error
- func ErrDecryptionFailed(parent error) Error
- func ErrEncryptionFailed(parent error) Error
- func ErrEncryptionKeyNotFound() Error
- func ErrEnvironmentNameInvalid() Error
- func ErrEnvironmentNotFound() Error
- func ErrEnvironmentPermissionDenied() Error
- func ErrEnvironmentProjectNotFound() Error
- func ErrEventInvalid(details any, parent error) Error
- func ErrEventNotFound() Error
- func ErrEventPermissionDenied() Error
- func ErrFlowCompleted() Error
- func ErrFlowCookieExpired() Error
- func ErrFlowCookieInvalid() Error
- func ErrFlowDefinitionAlreadyExists() Error
- func ErrFlowDefinitionInvalid(details any, parent error) Error
- func ErrFlowDefinitionNotFound() Error
- func ErrFlowDefinitionPermissionDenied() Error
- func ErrFlowDefinitionPurposeMismatch() Error
- func ErrFlowDefinitionUpdateConflict(details any) Error
- func ErrFlowIntegrity() Error
- func ErrFlowInvalidAction() Error
- func ErrFlowInvalidPurpose() Error
- func ErrFlowNotFound() Error
- func ErrFlowSessionConflict() Error
- func ErrFlowUnsupported() Error
- func ErrGrantAlreadyExists() Error
- func ErrGrantInvalid() Error
- func ErrGrantNotFound() Error
- func ErrGrantPermissionDenied() Error
- func ErrGrantPrincipalNotFound() Error
- func ErrInternal(err error) Error
- func ErrInvalidToken() Error
- func ErrInvalidTokenIdentifiers() Error
- func ErrJSONSchemaAlreadyExists() Error
- func ErrJSONSchemaInvalid() Error
- func ErrJSONSchemaNotFound() Error
- func ErrJSONSchemaPermissionDenied() Error
- func ErrJSONSchemaRevisionConflict() Error
- func ErrMissingFlowDefinitionID() Error
- func ErrMissingProjectID() Error
- func ErrNoReplacementKey() Error
- func ErrNotImplemented() Error
- func ErrPersonalTeamNotActive(status string) Error
- func ErrProjectAlreadyClaimed() Error
- func ErrProjectClaimExpired() Error
- func ErrProjectMissingID() Error
- func ErrProjectNameInvalid() Error
- func ErrProjectNotFound() Error
- func ErrProjectPermissionDenied() Error
- func ErrRequestInvalid() Error
- func ErrSchemaFetchFailed(details any, parent error) Error
- func ErrSessionExchangeConflict() Error
- func ErrSessionInvalidHandoffToken() Error
- func ErrSessionInvalidTTL() Error
- func ErrSessionNotFound() Error
- func ErrSessionPermissionDenied() Error
- func ErrSessionTokenCreationFailed() Error
- func ErrSessionTokenInvalid() Error
- func ErrSigningKeyNotFound() Error
- func ErrSupportedEncryptionAlgorithm(alg jose.ContentEncryption) Error
- func ErrTeamAlreadyExists() Error
- func ErrTeamNameInvalid() Error
- func ErrTeamNotFound() Error
- func ErrTeamPermissionDenied() Error
- func ErrTeamProjectNotFound() Error
- func ErrTokenRevoked() Error
- func ErrUnavailable() Error
- func ErrUserAlreadyExists() Error
- func ErrUserInvalid() Error
- func ErrUserNotFound() Error
- func ErrUserPasswordInvalid() Error
- func ErrUserPermissionDenied() Error
- func TokenNotFound() Error
- func (e Error) As(target any) bool
- func (e Error) Error() string
- func (e Error) Is(target error) bool
- func (e Error) LogValue() slog.Value
- func (e Error) Unwrap() error
- func (e Error) WithDetails(details any) Error
- func (e Error) WithMessage(msg string) Error
- func (e Error) WithParent(parent error) Error
- type Event
- type EventActorType
- type EventCategory
- type EventClientMetadata
- type EventField
- type EventMetadata
- type EventSink
- type EventSinkCursor
- type EventSinkScope
- type EventSinkType
- type EventType
- type Field
- type FlowAction
- type FlowActionKind
- type FlowAuthAttemptService
- type FlowAuthRequestRef
- type FlowBackEntry
- type FlowChallengeResponse
- type FlowCreateAttemptInput
- type FlowDefinition
- type FlowDefinitionAudience
- type FlowDefinitionField
- type FlowDefinitionPurpose
- type FlowDefinitionStatus
- type FlowDefinitionStep
- type FlowDefinitionTransitionAction
- type FlowField
- type FlowFieldChallenge
- type FlowFieldResolver
- type FlowFieldType
- type FlowFieldValidation
- type FlowFieldValidationError
- type FlowFieldValidationErrors
- type FlowFieldValidationRule
- type FlowGateKind
- type FlowHandoffInput
- type FlowHandoffOutput
- type FlowIssuePasskeyChallengeInput
- type FlowIssuePasskeyRegistrationChallengeInput
- type FlowOnSuccess
- type FlowOnSuccessHandler
- type FlowOnSuccessInput
- type FlowOnSuccessResult
- type FlowPasskeyChallengeOutput
- type FlowPasskeyRP
- type FlowPasskeyRegistrationChallengeOutput
- type FlowPendingChallenge
- type FlowProgress
- type FlowResolvedFields
- type FlowSSOProvider
- type FlowSSOProviderRef
- type FlowSessionRef
- type FlowStartInput
- type FlowState
- type FlowStateMachine
- type FlowStateMachineRuntime
- func (r *FlowStateMachineRuntime) Process(ctx context.Context, def *FlowDefinition, state *FlowState, in FlowSubmitInput) (FlowStepResult, error)
- func (r *FlowStateMachineRuntime) Render(ctx context.Context, def *FlowDefinition, state *FlowState) (FlowStepResult, error)
- func (r *FlowStateMachineRuntime) Start(ctx context.Context, in FlowStartInput) (FlowStepResult, error)
- type FlowStep
- type FlowStepAction
- type FlowStepChallenge
- type FlowStepComplete
- type FlowStepGate
- type FlowStepResult
- type FlowStepTexts
- type FlowStepTransition
- type FlowSubmitIdentifierInput
- type FlowSubmitInput
- type FlowSubmitPasskeyInput
- type FlowSubmitPasskeyRegistrationInput
- type FlowSubmitPasswordInput
- type FlowdefAudiencePayload
- type FlowdefPayload
- type HandoffToken
- type JSONSchema
- type JSONSchemaField
- type JSONSchemaKind
- type JSONSchemaResolver
- type JSONSchemaStore
- type JWEHeader
- type KeyState
- type KnownSchemaKind
- type MasterKey
- type MasterKeys
- type MembershipStatus
- type PasskeyChallenge
- type PasskeyCredentialParameter
- type PasskeyRegistrationChallenge
- type PasskeyVerification
- type PersonalTeamNotActiveDetails
- type PivotingTarget
- type Project
- type ProjectCreatedPayload
- type ProjectDeletedPayload
- type ProjectField
- type ProjectKeySet
- type ProjectPayload
- type ProjectUpdatedPayload
- type RequestAPIPayload
- type RequestInvalidFieldDetails
- type ResourceKind
- type ResourcePrefix
- type ResourceScope
- type SchemaCreatedPayload
- type SchemaFieldResolver
- func (r *SchemaFieldResolver) MissingRequired(fields FlowResolvedFields, values map[string]any) FlowFieldValidationErrors
- func (r *SchemaFieldResolver) Resolve(schema *jsonschema.Schema, stepName string, fieldNames []Field) (FlowResolvedFields, error)
- func (r *SchemaFieldResolver) Validate(fields FlowResolvedFields, values map[string]any) error
- type SchemaResolver
- type SchemaValidator
- type Session
- type SessionDeletedPayload
- type SessionEstablishedPayload
- type SessionExpiredPayload
- type SessionField
- type SessionInvalidTTLDetails
- type SessionState
- type SetUserPassword
- type SigningKey
- type SigningKeyField
- type SigningKeyPurpose
- type Team
- type TeamCreatedPayload
- type TeamDeactivatedPayload
- type TeamField
- type TeamMembership
- type TeamMembershipField
- type TeamMembershipUpdatedPayload
- type TeamPayload
- type TeamStatus
- type TeamUpdatedPayload
- type Token
- type TokenField
- type TokenType
- func (i TokenType) IsATokenType() bool
- func (t TokenType) IsProjectSecret() bool
- func (i TokenType) MarshalJSON() ([]byte, error)
- func (t TokenType) Persistable() bool
- func (t *TokenType) Scan(value any) error
- func (i TokenType) String() string
- func (i *TokenType) UnmarshalJSON(data []byte) error
- func (t TokenType) Value() (driver.Value, error)
- type User
- type UserAgent
- type UserCreateFailedPayload
- type UserCreatedPayload
- type UserDeactivatedPayload
- type UserDeletedPayload
- type UserField
- type UserMetadata
- type UserPasskey
- type UserPasskeyAttestationTypeUpdate
- type UserPasskeyBackupEligibleUpdate
- type UserPasskeyBackupStateUpdate
- type UserPasskeyField
- type UserPasskeyLastUsedAtUpdate
- type UserPasskeySignCountUpdate
- type UserPasskeyTransportsUpdate
- type UserPasskeyUpdate
- type UserPasskeyVerifiedAtUpdate
- type UserPassword
- type UserPasswordChangeRequiredUpdate
- type UserPasswordChangedAtUpdate
- type UserPasswordEncodedHashUpdate
- type UserPasswordField
- type UserPasswordIncrementFailedAttemptsUpdate
- type UserPasswordLastSuccessfulCheckUpdate
- type UserPasswordResetFailedAttemptsUpdate
- type UserPasswordUpdate
- type UserPasswordVerificationIDUpdate
- type UserRecoveryCodes
- type UserRecoveryCodesCodesUpdate
- type UserRecoveryCodesField
- type UserRecoveryCodesIncrementFailedAttemptsUpdate
- type UserRecoveryCodesLastSuccessfulCheckUpdate
- type UserRecoveryCodesResetFailedAttemptsUpdate
- type UserRecoveryCodesUpdate
- type UserRef
- type UserSchemaUnknownDetails
- type UserStatus
- type UserTOTP
- type UserTOTPField
- type UserTOTPIncrementFailedAttemptsUpdate
- type UserTOTPLastSuccessfulCheckUpdate
- type UserTOTPResetFailedAttemptsUpdate
- type UserTOTPSecretUpdate
- type UserTOTPUpdate
- type UserTOTPVerifiedAtUpdate
- type UserTeam
- type UserTeamField
- type UserUpdatedPayload
Constants ¶
const ( SystemCatalogID = "cat_sys_1" SystemCatalogOwnerID = "system" )
System catalog identity (must match Goose seed).
const ( BrandingLayoutCentered = "centered" BrandingLayoutSplit = "split" )
Branding layout presets understood by the bundled login template. The wire enum is defined in api/openapi/components/flows/branding.yaml; richer designs are delivered as Liquid templates, not new enum values (ADR 040).
const ( EnvironmentNameMaxLength = 63 EnvironmentNamePattern = `^[a-z0-9]([a-z0-9-]*[a-z0-9])?$` )
const ( // FlowStepErrorInvalidCredentials reports a rejected password // proof. The client routes it inline to the password field // (fieldErrorKeys in liquid.ts). FlowStepErrorInvalidCredentials = "error.invalid_credentials" // FlowStepErrorPasskeyInvalid reports a rejected passkey assertion. FlowStepErrorPasskeyInvalid = "error.passkey_invalid" // FlowStepErrorPasskeyRegistrationInvalid reports a rejected // passkey registration attestation. FlowStepErrorPasskeyRegistrationInvalid = "error.passkey_registration_invalid" )
Step error text keys the state machine emits when an auth-attempt proof is rejected. Every engine-emitted step error must be a localizable `error.*` catalog key or a reserved outcome token: /login localizes only `error.*`-prefixed step errors and treats outcome tokens as routing, so anything else renders verbatim (see `localiseFlowErrorKeys` in packages/components/src/orchestrator/liquid.ts). New emission sites add a const here; FlowStepErrorAllowed and its contract test keep the set honest.
const ( DefaultMaxJSONSchemaResolveDepth = 10 DefaultMaxJSONSchemaSize = 1 << 20 // 1 MB )
const ( // SchemaAnnotationIdentifier designates the leaf property whose value // identifies a user (ADR 058 §1). Schema-root, dot-joined path. SchemaAnnotationIdentifier = "x-identifier" // SchemaAnnotationDisplay lists the leaf property paths rendering the // user's display name (ADR 058 §2). Schema-root. SchemaAnnotationDisplay = "x-display" // SchemaAnnotationUnique carries a property's uniqueness scope. SchemaAnnotationUnique = "x-unique" // SchemaAnnotationAuthMethods configures the schema's auth methods. SchemaAnnotationAuthMethods = "x-auth-methods" )
Platform annotations read from tenant schema documents. One spelling each — a mistyped annotation does not fail loudly, it reads as absent.
const ( SchemaUniqueScopeProject = "project" SchemaUniqueScopeTeam = "team" )
Values of the SchemaAnnotationUnique annotation.
const ( PasskeyNameSecurityKey = "Security key" PasskeyNameSynced = "Synced passkey" PasskeyNameDeviceBound = "Device-bound passkey" )
Fallback passkey names, used when registration carries no caller-supplied name. WebAuthn reports no human-readable label for the authenticator, so the fallback describes the credential itself.
const AuthAttemptTTL = 15 * time.Minute
const ClaimChallengeTTL = 10 * time.Minute
ClaimChallengeTTL is the challenge lifetime (ADR 046 §3).
const FlowActionPasskey = "passkey"
FlowActionPasskey is the action a step declares to offer passkey authentication. Selecting it issues a WebAuthn challenge; the matching transition fires once the returned assertion verifies.
const FlowActionPasskeyRegister = "passkey_register"
FlowActionPasskeyRegister is the action a step declares to offer passkey enrollment. Selecting it issues a registration challenge; the matching transition fires once the returned attestation verifies.
const FlowActionSubmit = "submit"
FlowActionSubmit is the conventional outcome name for the primary "advance forward" action on a step.
const FlowChallengeMethodPasskey = "passkey"
FlowChallengeMethodPasskey is the FlowStepChallenge.Method / FlowPendingChallenge.Method value for the WebAuthn passkey ceremony.
const FlowChallengeMethodPasskeyRegister = "passkey_register"
FlowChallengeMethodPasskeyRegister is the FlowStepChallenge.Method / FlowPendingChallenge.Method value for the WebAuthn registration ceremony.
const FlowImplicitOutcomeUserAlreadyExists = "user_already_exists"
FlowImplicitOutcomeUserAlreadyExists drives the register → login flip.
const FlowImplicitOutcomeUserNotFound = "user_not_found"
FlowImplicitOutcomeUserNotFound drives the login → register flip.
const MaxBrandingTemplateBytes = 131072 // 128 KiB
MaxBrandingTemplateBytes caps the stored template size. Matches the maxLength on branding.liquid_template in the OpenAPI contract (which ogen enforces in characters; this gate re-checks in bytes).
const PasskeyRegistrationChallengeTTL = 5 * time.Minute
PasskeyRegistrationChallengeTTL bounds the registration ceremony: the attestation must come back within this window even though the attempt itself lives longer.
const SchemaDocumentKindUser = "user-schema"
SchemaDocumentKindUser is the `kind` discriminator of a user schema document (distinct from SchemaKindUser, the meta-schema filename stem).
const TeamNameMaxLength = 200
TeamNameMaxLength bounds the name in characters.
Variables ¶
var ( ErrMissingBuiltinPublicBase = errors.New("missing builtinPublicBase") ErrInvalidBuiltinPublicBase = errors.New("invalid builtinPublicBase") ErrBuiltinTemplateRenderFailed = errors.New("failed to render builtin template") ErrMetaSchemaCompileFailed = errors.New("failed to compile meta-schema") ErrMissingBuiltinMetaSchema = errors.New("missing built-in meta-schema") ErrMetaSchemaRefNotFound = errors.New("meta-schema $ref not found in builtins") ErrMaxResolveDepthReached = errors.New("max resolve depth reached") ErrSchemaValidationFailed = errors.New("schema validation failed") ErrSchemaParseFailed = errors.New("schema parse failed") ErrMissingSchemaID = errors.New("missing schema ID") ErrUnknownSchemaURI = errors.New("unknown built-in schema URI") ErrUnknownSchemaKind = errors.New("unknown schema kind") )
Errors
var DefaultEnvironmentNames = []string{"dev", "staging", "prod"}
var ErrEmptyRecoveryCodes = errors.New("recovery codes must contain at least one code")
var ErrFlowFieldNotScalar = errors.New("flow field: not a scalar property, name a nested leaf instead")
ErrFlowFieldNotScalar is returned by FlowFieldResolver.Resolve when a field names an object- or array-typed property. An object is collected one leaf at a time through its dotted path (`address.street`); an array has no field-shaped input.
var ErrFlowFieldUnknown = errors.New("flow field: not a property in the user schema")
ErrFlowFieldUnknown is returned by FlowFieldResolver.Resolve when a requested field name is not a property in the user schema. The offending field name is appended via `fmt.Errorf("%w: %q", ...)`.
var ErrFlowFieldUnsupportedType = errors.New("flow field: unsupported JSON type")
ErrFlowFieldUnsupportedType is returned by FlowFieldResolver.Resolve when a property declares a JSON `type` set the resolver cannot reduce to a single input kind. The nullable idiom `["null", X]` is reduced to X and does not trigger this error; any other multi-entry union does.
var ErrInvalidTokenType = errors.New("token type is not persistable")
ErrInvalidTokenType is returned when a token type cannot be stored (see TokenType.Persistable).
var ErrSchemaDesignationInvalid = errors.New("schema designation invalid")
ErrSchemaDesignationInvalid reports an x-identifier / x-display designation the user meta-schema cannot check itself (ADR 058 §1–§2): the named property must exist, be a leaf, and — for x-identifier — carry project-scoped uniqueness; a schema that enables an auth method needing identifier-first dispatch must designate an identifier.
var PlatformProjectID = PrefixProject.IDPrefix("platform") // "proj_platform"
PlatformProjectID is the well-known id of the deployment's platform project. The server owns it: bootstrap (platform.bootstrap_project) creates this row and default-project resolution pins to it. Readable body per ADR 047 §3.3; operators never author it.
var RosterMembershipStatuses = []MembershipStatus{ MembershipStatusPending, MembershipStatusActive, MembershipStatusInactive, }
RosterMembershipStatuses are the participation states that keep a user on a team's roster. MembershipStatusRemoved is deliberately absent: a removed membership is history, not roster, and roster reads must not serve it.
Functions ¶
func AuthCheckTypeStrings ¶
func AuthCheckTypeStrings() []string
AuthCheckTypeStrings returns a slice of all String values of the enum
func BuildPasskeyCreationOptions ¶
func BuildPasskeyCreationOptions(c *AuthChallengePasskeyRegistration) ([]byte, error)
BuildPasskeyCreationOptions renders the stored registration challenge as the WebAuthn PublicKeyCredentialCreationOptions JSON the browser passes to navigator.credentials.create(). Mirrors BuildPasskeyRequestOptions for the registration ceremony.
func BuildPasskeyRequestOptions ¶
func BuildPasskeyRequestOptions(c *AuthChallengePasskey) ([]byte, error)
BuildPasskeyRequestOptions renders the stored passkey challenge as the WebAuthn PublicKeyCredentialRequestOptions JSON (wrapped in the standard `{"publicKey": ...}` envelope) that the browser passes to navigator.credentials.get(). It reconstructs the options from the persisted challenge fields rather than the discarded ceremony output (see CreatePasskeyChallenge), so the flow engine and the auth-attempt REST API can share one mapping.
func CheckAs ¶
func CheckAs[T AuthFactor](attempt *AuthAttempt, typ AuthCheckType) (T, bool)
CheckAs retrieves a check of the given type from the attempt and casts it to a specific AuthFactor type, returning the typed factor and true if it exists and matches the type.
func DecodePasskeyCredentialID ¶
DecodePasskeyCredentialID reverses EncodePasskeyCredentialID.
func DesignatedAttributeKeys ¶
DesignatedAttributeKeys returns the attribute keys a schema document's designations read — the hydration set a batch ref resolution needs (ADR 058 §3a: rows hydrate only the designated attribute keys).
func DesignatedDisplay ¶
DesignatedDisplay reads the root x-display designation from a raw schema document: the ordered property paths whose values render the user's display name (ADR 058 §2). Same reader contract as DesignatedIdentifier — anything unreadable, including non-string entries, reads as undesignated.
func DesignatedIdentifier ¶
DesignatedIdentifier reads the root x-identifier designation from a raw schema document. It returns "" for a document that designates nothing — including one that is not a JSON object, since designation validity is enforced when the schema is created ([validateUserSchemaDesignations]) and readers treat anything unreadable as undesignated.
func EncodePasskeyCredentialID ¶
EncodePasskeyCredentialID returns the storage form for WebAuthn credential IDs. Credential IDs are arbitrary bytes, so TEXT database columns must store an ASCII-safe representation.
func FieldsToStrings ¶
FieldsToStrings lowers typed Field values back to wire-format strings at the API/repository boundary.
func FlattenValidationErrors ¶
FlattenValidationErrors collects meta-schema validation errors into a loc → msg map. loc segments are joined with "/" (e.g. "/required/x-auth-methods").
func FlowActionKindStrings ¶
func FlowActionKindStrings() []string
FlowActionKindStrings returns a slice of all String values of the enum
func FlowDefinitionPurposeStrings ¶
func FlowDefinitionPurposeStrings() []string
FlowDefinitionPurposeStrings returns a slice of all String values of the enum
func FlowDefinitionStatusStrings ¶
func FlowDefinitionStatusStrings() []string
FlowDefinitionStatusStrings returns a slice of all String values of the enum
func FlowDefinitionTransitionActionStrings ¶
func FlowDefinitionTransitionActionStrings() []string
FlowDefinitionTransitionActionStrings returns a slice of all String values of the enum
func FlowGateKindStrings ¶
func FlowGateKindStrings() []string
FlowGateKindStrings returns a slice of all String values of the enum
func FlowOnSuccessStrings ¶
func FlowOnSuccessStrings() []string
FlowOnSuccessStrings returns a slice of all String values of the enum
func FlowStepCompleteStrings ¶
func FlowStepCompleteStrings() []string
FlowStepCompleteStrings returns a slice of all String values of the enum
func FlowStepErrorAllowed ¶
FlowStepErrorAllowed reports whether a step error value honors the client contract: a localizable `error.*` text key or a reserved outcome token (reservedOutcomes in flow_definition_validator.go).
func GeneratePasskeyCredentialName ¶
PasskeyCredentialName returns the name stored for a registered credential. A caller-supplied name always wins; otherwise the name is derived from the credential's transports and backup eligibility. It never returns an empty string: the passkey list is a user-facing management surface, so every credential needs something displayable — the user's display name is not a candidate, since it is identical for every credential they register.
func HashClaimChallengeToken ¶
HashClaimChallengeToken derives the stored challenge id from a presented plaintext token. The claim_challenges.id column is TEXT, so unlike the handoff token's raw []byte hash this one is hex-encoded.
func HashSecret ¶
HashSecret is the proof-of-possession hash of a presented bearer string (ADR 029): hex-encoded SHA-256. HandleOAuth2 stores it on claim init and the claim service compares it on claim/status with a constant-time compare, so the handler, domain, and tests must all derive it from this one definition.
func ImplicitOutcomesForChallenge ¶
func ImplicitOutcomesForChallenge(c FlowFieldChallenge) []string
ImplicitOutcomesForChallenge returns the transition outcomes a field contributes by virtue of its challenge. Returns nil when the challenge implies no outcomes. Resolvers call it to populate FlowResolvedFields.ImplicitOutcomes; the state machine calls it to validate flow definitions against schema-implied outcomes.
func JSONSchemaKindStrings ¶
func JSONSchemaKindStrings() []string
JSONSchemaKindStrings returns a slice of all String values of the enum
func NewClaimChallengeToken ¶
NewClaimChallengeToken mints the plaintext challenge token and the stored challenge id (handoff-token pattern, ADR 046 §3): 128 bits of crypto/rand, prefixed and base64url-encoded. Only the id — the SHA-256 of the plaintext — is ever persisted; the plaintext travels in the claim_url and the CLI poll.
The plaintext uses the wire prefix "ch_" (challenge-id.yaml pins ^ch_[a-zA-Z0-9_-]+$, shared with the api-mock and CLI, and ogen validates it on input and output). PrefixClaimChallenge stays for error codes only; the stored id is an unprefixed hex digest either way.
func PasskeysToCredentials ¶
func PasskeysToCredentials(passkeys []*UserPasskey) []webauthn.Credential
func ResolveSessionTTL ¶
func ResolveSessionTTL(requested *time.Duration, defaultTTL, maxTTL time.Duration) (time.Duration, error)
ResolveSessionTTL picks the effective session TTL for exchange. When requested is nil, defaultTTL is used. Otherwise requested must be positive and <= maxTTL.
func TeamBoundObjectType ¶
TeamBoundObjectType reports whether objectType is always team-scoped for sk_team_ principals (user, team, team_membership, event). Mint-time validation and the sk_team allowlist share this set so a new allowlist entry cannot silently allow project-scoped minting.
func TokenTypeStrings ¶
func TokenTypeStrings() []string
TokenTypeStrings returns a slice of all String values of the enum
func UniqueValueHash ¶
UniqueValueHash is the one comparison function behind attribute uniqueness: the unique-attributes registry stores it and identifier resolution looks it up, so both always agree on what counts as the same value (ADR 058 §4a). String values are Unicode case-folded before hashing — Alice@Example.com and alice@example.com are one unique value — while the attribute itself keeps its original casing. Non-string values hash as encoded.
func ValidateBranding ¶
ValidateBranding is the lexical save gate for branding revisions.
func ValidateEnvironmentName ¶
ValidateEnvironmentName returns the trimmed name, or ErrEnvironmentNameInvalid.
func ValidateSessionToken ¶
func ValidateTeamName ¶
ValidateTeamName returns the trimmed name, or ErrTeamNameInvalid when it is empty or longer than TeamNameMaxLength.
func WriteBuiltinJSONSchema ¶
WriteBuiltinJSONSchema renders a built-in JSON schema to w. schemaPath is the URL path after the configured public base, including the .json filename (for example user/v1/user.schema.json for URL https://iam.example.com/schema/user/v1/user.schema.json when the public base is https://iam.example.com/schema). canonicalDocumentURL must be the absolute schema URL used as JSON Schema $id and for resolution (typically the request URL used to serve this document).
Types ¶
type Attribute ¶
type Attribute struct {
Key AttributeKey `json:"key"`
Value any `json:"value"`
}
type AttributeKey ¶
type AttributeKey string
func (AttributeKey) AppendNode ¶
func (k AttributeKey) AppendNode(node string) AttributeKey
func (AttributeKey) Nodes ¶
func (k AttributeKey) Nodes() []string
type AttributeUniqueness ¶
type AttributeUniqueness int
const ( AttributeUniquenessUnspecified AttributeUniqueness = iota AttributeUniquenessTeam AttributeUniquenessProject )
type Attributes ¶
type Attributes []Attribute
func AttributesFromMap ¶
func AttributesFromMap(m map[string]any) Attributes
func (Attributes) Get ¶
func (attrs Attributes) Get(key AttributeKey) (value any, ok bool)
Get returns the value for the given key.
TODO(go v27): make this method generic
func (Attributes) MarshalJSON ¶
func (attrs Attributes) MarshalJSON() ([]byte, error)
func (*Attributes) UnmarshalJSON ¶
func (attrs *Attributes) UnmarshalJSON(data []byte) error
type AuthAttempt ¶
type AuthAttempt struct {
// ProjectID links to [Project].
ProjectID string
// ID is the unique identifier for the auth attempt within the project.
// The storage layer assigns this value on Create (dialect-minted prefixed opaque string).
ID string
// HandoffToken is the single-use token minted explicitly with the handoff call after all required factors are verified, used by the client to exchange for a session.
HandoffToken *HandoffToken
// HandedOffAt is the timestamp when the handoff token was generated after the attempt was completed.
HandedOffAt *time.Time
// Used to link an auth attempt to a session. Use case is step up auth.
// In this case we need to copy the factors from the session back to the auth attempt.
SessionID *string
// Links to the [AuthCheck]s that belong to the auth attempt.
// An auth attempt can have multiple checks (e.g. for multi-factor authentication), but a check can only belong to one auth attempt.
Checks []AuthCheck
RequiredChecks []AuthCheckType
// The time when the auth attempt was created, it must be set by the storage and is read-only.
CreatedAt time.Time
// TTL describes how long an auth attempt is valid, it should be set to a reasonable value (e.g. 5 minutes) to prevent abuse and to ensure that old auth attempts are cleaned up.
// An auth attempt gets garbage collected after CreatedAt + TimeToLive, so it is important to set it to a reasonable value to prevent abuse and to ensure that old auth attempts are cleaned up.
TimeToLive *time.Duration
// Internal marks a server-orchestrated ceremony (e.g. management-plane
// passkey enrollment, ADR 056) whose attempt row is only a state carrier:
// it must never be handed off, exchanged, or read through the attempt API.
Internal bool
}
AuthAttempt represents the object defined [here](https://github.com/zitadel/nextgen/blob/15bd7f438d709fcd5205a163e24374f6f667b68f/docs/design/api/resource-map.md#auth-flows) It is short-lived and should therefore be stored near the client, do not store PII data in it.
func NewAuthAttempt ¶
func NewAuthAttempt(projectID string, requiredChecks []AuthCheckType, opts ...AuthAttemptOption) (*AuthAttempt, error)
func (*AuthAttempt) ChallengeByID ¶
func (a *AuthAttempt) ChallengeByID(id string) (AuthChallenge, bool)
ChallengeByID returns the check with the given challenge ID. Used to validate that a client's challenge ID is current before accepting a proof.
func (*AuthAttempt) ChallengeByType ¶
func (a *AuthAttempt) ChallengeByType(typ AuthCheckType) (AuthChallenge, bool)
ChallengeByType returns the challenge of the given type, if it exists on the attempt.
func (*AuthAttempt) ExpiresAt ¶
func (a *AuthAttempt) ExpiresAt() time.Time
ExpiresAt returns the timestamp when the attempt expires.
func (*AuthAttempt) FactorByClass ¶
func (a *AuthAttempt) FactorByClass(typ AuthCheckType) (AuthFactor, bool)
FactorByClass returns a verified factor whose type competes in typ's class (see AuthCheckType.Class), if one exists on the attempt.
func (*AuthAttempt) FactorByType ¶
func (a *AuthAttempt) FactorByType(typ AuthCheckType) (AuthFactor, bool)
FactorByType returns the verified factor of the given type, if it exists on the attempt.
func (*AuthAttempt) HasProvisionalRegistrationHandle ¶
func (a *AuthAttempt) HasProvisionalRegistrationHandle(userID string) bool
HasProvisionalRegistrationHandle reports whether the attempt's current registration challenge is provisional and carries the given user handle. This is the only situation in which a caller-supplied handle is known to be server-minted, so a re-issued challenge may keep it; any other unknown handle must be replaced by a fresh mint, never adopted.
func (*AuthAttempt) IsCompleted ¶
func (a *AuthAttempt) IsCompleted() bool
IsCompleted returns true if all required checks are verified successfully. Matching is by factor class, so a completed passkey enrollment satisfies a required passkey check.
func (*AuthAttempt) IsExpired ¶
func (a *AuthAttempt) IsExpired() bool
IsExpired returns true if the attempt's TTL has elapsed. Returns false if the attempt is not yet initialized (zero CreatedAt) or TTL is nil.
func (*AuthAttempt) IsHandedOff ¶
func (a *AuthAttempt) IsHandedOff() bool
IsHandedOff returns true if a handoff token has been generated.
func (*AuthAttempt) PrepareChallenge ¶
func (a *AuthAttempt) PrepareChallenge(typ AuthCheckType) error
PrepareChallenge validates that a challenge can be issued for the given check type.
func (*AuthAttempt) PrepareHandoff ¶
func (a *AuthAttempt) PrepareHandoff() error
PrepareHandoff validates that a handoff can be issued. And will generate and store the handoff token. Note: The HandoffToken is generated using a crypto/rand token and stored in a hashed way for security reasons.
func (*AuthAttempt) PreparePasskeyChallenge ¶
func (a *AuthAttempt) PreparePasskeyChallenge() (string, error)
PreparePasskeyChallenge validates that a passkey challenge can be issued and returns the user ID if the user was already identified.
func (*AuthAttempt) PreparePasskeyRegistrationChallenge ¶
func (a *AuthAttempt) PreparePasskeyRegistrationChallenge(requestedUserID string) (userID string, provisional bool, err error)
PreparePasskeyRegistrationChallenge validates that a passkey registration challenge can be issued and resolves the user handle for the ceremony. Unlike password, no prior user factor is required: registration is how a user comes to exist in the first place.
With a pinned user factor the enrollment targets that user (requestedUserID must match when set) and the ceremony is not provisional. Without one the ceremony is provisional: every authenticated path persists a user factor — including discoverable passkey login — so an unpinned attempt has no user. A non-empty requestedUserID is kept by the caller only when AuthAttempt.HasProvisionalRegistrationHandle confirms it is the handle of the attempt's own in-flight ceremony (a re-issued challenge); any other handle must be replaced by a fresh mint, so a caller-chosen id never becomes a user id. An empty handle signals the caller to mint a fresh one.
func (*AuthAttempt) PreparePasskeyRegistrationVerification ¶
func (a *AuthAttempt) PreparePasskeyRegistrationVerification(challengeID string) (*AuthChallengePasskeyRegistration, error)
PreparePasskeyRegistrationVerification validates that a registration proof can be submitted. Beyond the generic checks it enforces the ceremony's own window (PasskeyRegistrationChallengeTTL), which is tighter than the attempt TTL, and that the attempt's user state still matches what the challenge was issued for: an authentication that happened after the issue supersedes the ceremony. Without this, a provisional attestation could create a second user on an attempt that meanwhile authenticated user A — overwriting the user check A→H while A's other factors survive, so the handoff would mint a session for H carrying factors verified against A.
func (*AuthAttempt) PreparePasskeyVerification ¶
func (a *AuthAttempt) PreparePasskeyVerification(challengeID string) (AuthChallenge, *AuthFactorUser, error)
PreparePasskeyVerification validates that a passkey proof can be submitted. It returns the already-identified user when one is pinned (identified login), or a nil user factor for a discoverable/usernameless login where the user is resolved cryptographically from the assertion's user handle.
Allowing a nil user factor is safe because subject-switching is structurally prevented: when a user is already pinned, verification runs the identified path constrained to that user's credentials, so an assertion from any other credential simply fails. A nil user factor only occurs on a clean attempt (a password factor cannot exist without a user factor), so discoverable login cannot override an authenticated subject.
func (*AuthAttempt) PreparePasswordChallenge ¶
func (a *AuthAttempt) PreparePasswordChallenge() error
PreparePasswordChallenge validates that a password challenge can be issued, which requires that a user was already identified to prevent issuing password challenges without a known user.
func (*AuthAttempt) PreparePasswordVerification ¶
func (a *AuthAttempt) PreparePasswordVerification(challengeID string) (AuthChallenge, *AuthFactorUser, error)
PreparePasswordVerification validates that a password proof can be submitted and returns the user ID to verify against.
func (*AuthAttempt) PrepareUserChallenge ¶
func (a *AuthAttempt) PrepareUserChallenge() error
PrepareUserChallenge validates that a user challenge can be issued. It's prohibited if the auth attempt is linked to a session with a verified user as this could lead to security issues. Also, as soon as there are more factors verified than the user (e.g. password) we'll not allow to change the user anymore. We'll probably change the latter in the future and reset all factors as soon as the new user challenge succeeded.
func (*AuthAttempt) PrepareUserVerification ¶
func (a *AuthAttempt) PrepareUserVerification(challengeID string) (AuthChallenge, error)
PrepareUserVerification validates that the attempt is in a state where a user (identifier) proof can be submitted.
func (*AuthAttempt) PrepareVerification ¶
func (a *AuthAttempt) PrepareVerification(challengeID string, checkType AuthCheckType) (AuthChallenge, error)
PrepareVerification verifies that the attempt is not expired or handed off, that the given challenge ID exists (preventing stale proofs), and that the proof type matches the challenge's type.
func (*AuthAttempt) SetCheck ¶
func (a *AuthAttempt) SetCheck(check AuthCheck)
SetCheck sets a check to the given check. In the case of an AuthChallenge, it will overwrite an existing challenge of the same type but keep factors of the same type. In the case of an AuthFactor, it will overwrite an existing factor of the same type and remove challenges of the same type.
func (*AuthAttempt) SetPasskeyChallenge ¶
func (a *AuthAttempt) SetPasskeyChallenge(passkeyChallenge *PasskeyChallenge) *AuthChallengePasskey
func (*AuthAttempt) SetPasskeyFactor ¶
func (a *AuthAttempt) SetPasskeyFactor(passkeyVerification *PasskeyVerification) *AuthFactorPasskey
func (*AuthAttempt) SetPasskeyRegistrationChallenge ¶
func (a *AuthAttempt) SetPasskeyRegistrationChallenge(registrationChallenge *PasskeyRegistrationChallenge, provisional bool) *AuthChallengePasskeyRegistration
SetPasskeyRegistrationChallenge registers a new passkey registration challenge on the attempt, replacing any existing challenge of the same type.
func (*AuthAttempt) SetPasskeyRegistrationFactor ¶
func (a *AuthAttempt) SetPasskeyRegistrationFactor(passkey *CreateUserPasskey) *AuthFactorPasskeyRegistration
SetPasskeyRegistrationFactor records a completed passkey enrollment as a verified factor on the attempt, replacing the registration challenge.
func (*AuthAttempt) SetPasswordChallenge ¶
func (a *AuthAttempt) SetPasswordChallenge() *AuthChallengePassword
SetPasswordChallenge registers a new password challenge on the attempt, replacing any existing challenge of the same type.
func (*AuthAttempt) SetPasswordFactor ¶
func (a *AuthAttempt) SetPasswordFactor() *AuthFactorPassword
SetPasswordFactor registers a verified password factor on the attempt, overwriting existing factors of the same type and clearing any associated challenges.
func (*AuthAttempt) SetUserChallenge ¶
func (a *AuthAttempt) SetUserChallenge() *AuthChallengeUser
SetUserChallenge registers a new user challenge on the attempt, replacing any existing challenge of the same type.
func (*AuthAttempt) SetUserFactor ¶
func (a *AuthAttempt) SetUserFactor(user *User) *AuthFactorUser
SetUserFactor registers a verified user factor on the attempt, overwriting existing factors of the same type and clearing any associated challenges.
type AuthAttemptCreatedPayload ¶
type AuthAttemptCreatedPayload struct{}
AuthAttemptCreatedPayload is empty; flow_id/session_id live on event columns.
type AuthAttemptHandedOffPayload ¶
type AuthAttemptHandedOffPayload struct{}
AuthAttemptHandedOffPayload is empty; session_id lives on the event column.
type AuthAttemptOption ¶
type AuthAttemptOption func(*AuthAttempt)
func WithSession ¶
func WithSession(sessionID *string, authFactors ...AuthFactor) AuthAttemptOption
WithSession sets the session ID and copies existing factors from the session to the attempt.
type AuthChallenge ¶
type AuthChallengePasskey ¶
type AuthChallengePasskey struct {
*PasskeyChallenge
// contains filtered or unexported fields
}
func SetAuthChallengePasskey ¶
func SetAuthChallengePasskey(id string, lastChallengedAt, lastFailedAt time.Time, failureCount uint16) *AuthChallengePasskey
func (*AuthChallengePasskey) GetFailureCount ¶
func (a *AuthChallengePasskey) GetFailureCount() uint16
func (*AuthChallengePasskey) GetLastChallengedAt ¶
func (*AuthChallengePasskey) GetLastFailedAt ¶
func (*AuthChallengePasskey) Payload ¶
func (a *AuthChallengePasskey) Payload() any
func (*AuthChallengePasskey) SetFailureCount ¶
func (a *AuthChallengePasskey) SetFailureCount(failureCount uint16)
func (*AuthChallengePasskey) SetLastChallengedAt ¶
func (*AuthChallengePasskey) SetLastFailedAt ¶
func (*AuthChallengePasskey) Type ¶
func (a *AuthChallengePasskey) Type() AuthCheckType
type AuthChallengePasskeyRegistration ¶
type AuthChallengePasskeyRegistration struct {
*PasskeyRegistrationChallenge
// Provisional is true when the challenge minted the user handle itself:
// the user row does not exist yet and is created when the attestation is
// verified.
Provisional bool
// contains filtered or unexported fields
}
func SetAuthChallengePasskeyRegistration ¶
func SetAuthChallengePasskeyRegistration(id string, lastChallengedAt, lastFailedAt time.Time, failureCount uint16) *AuthChallengePasskeyRegistration
func (*AuthChallengePasskeyRegistration) GetFailureCount ¶
func (a *AuthChallengePasskeyRegistration) GetFailureCount() uint16
func (*AuthChallengePasskeyRegistration) GetID ¶
func (a *AuthChallengePasskeyRegistration) GetID() string
func (*AuthChallengePasskeyRegistration) GetLastChallengedAt ¶
func (*AuthChallengePasskeyRegistration) GetLastFailedAt ¶
func (*AuthChallengePasskeyRegistration) Payload ¶
func (a *AuthChallengePasskeyRegistration) Payload() any
func (*AuthChallengePasskeyRegistration) SetFailureCount ¶
func (a *AuthChallengePasskeyRegistration) SetFailureCount(failureCount uint16)
func (*AuthChallengePasskeyRegistration) SetID ¶
func (a *AuthChallengePasskeyRegistration) SetID(id string)
func (*AuthChallengePasskeyRegistration) SetLastChallengedAt ¶
func (*AuthChallengePasskeyRegistration) SetLastFailedAt ¶
func (*AuthChallengePasskeyRegistration) Type ¶
func (a *AuthChallengePasskeyRegistration) Type() AuthCheckType
type AuthChallengePassword ¶
type AuthChallengePassword struct {
// contains filtered or unexported fields
}
func SetAuthChallengePassword ¶
func SetAuthChallengePassword(id string, lastChallengedAt, lastFailedAt time.Time, failureCount uint16) *AuthChallengePassword
func (*AuthChallengePassword) GetFailureCount ¶
func (a *AuthChallengePassword) GetFailureCount() uint16
func (*AuthChallengePassword) GetLastChallengedAt ¶
func (*AuthChallengePassword) GetLastFailedAt ¶
func (*AuthChallengePassword) Payload ¶
func (a *AuthChallengePassword) Payload() any
func (*AuthChallengePassword) SetFailureCount ¶
func (a *AuthChallengePassword) SetFailureCount(failureCount uint16)
func (*AuthChallengePassword) SetLastChallengedAt ¶
func (*AuthChallengePassword) SetLastFailedAt ¶
func (*AuthChallengePassword) Type ¶
func (a *AuthChallengePassword) Type() AuthCheckType
type AuthChallengeUser ¶
type AuthChallengeUser struct {
// contains filtered or unexported fields
}
func SetAuthChallengeUser ¶
func SetAuthChallengeUser(id string, lastChallengedAt, lastFailedAt time.Time, failureCount uint16) *AuthChallengeUser
func (*AuthChallengeUser) GetFailureCount ¶
func (a *AuthChallengeUser) GetFailureCount() uint16
func (*AuthChallengeUser) GetLastChallengedAt ¶
func (*AuthChallengeUser) GetLastFailedAt ¶
func (*AuthChallengeUser) Payload ¶
func (a *AuthChallengeUser) Payload() any
func (*AuthChallengeUser) SetFailureCount ¶
func (a *AuthChallengeUser) SetFailureCount(failureCount uint16)
func (*AuthChallengeUser) SetLastChallengedAt ¶
func (*AuthChallengeUser) SetLastFailedAt ¶
func (*AuthChallengeUser) Type ¶
func (a *AuthChallengeUser) Type() AuthCheckType
type AuthCheck ¶
type AuthCheck interface {
Type() AuthCheckType
Payload() any
}
type AuthCheckPayload ¶
type AuthCheckType ¶
type AuthCheckType uint8
const ( AuthCheckTypeUnspecified AuthCheckType = iota AuthCheckTypeUser AuthCheckTypePassword AuthCheckTypePasskey AuthCheckTypePasskeyRegistration )
func AuthCheckTypeString ¶
func AuthCheckTypeString(s string) (AuthCheckType, error)
AuthCheckTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func AuthCheckTypeValues ¶
func AuthCheckTypeValues() []AuthCheckType
AuthCheckTypeValues returns all values of the enum
func (AuthCheckType) Class ¶
func (t AuthCheckType) Class() AuthCheckType
Class returns the factor class a check type competes in. Passkey enrollment proves the same thing an assertion does for that credential (ADR 056), so AuthCheckTypePasskeyRegistration shares the passkey class; every other type is its own class. Anything comparing "which kind of factor is this" — required-check matching, session merging, wire rendering — compares classes, not raw types.
func (AuthCheckType) IsAAuthCheckType ¶
func (i AuthCheckType) IsAAuthCheckType() bool
IsAAuthCheckType returns "true" if the value is listed in the enum definition. "false" otherwise
func (AuthCheckType) MarshalText ¶
func (i AuthCheckType) MarshalText() ([]byte, error)
MarshalText implements the encoding.TextMarshaler interface for AuthCheckType
func (AuthCheckType) String ¶
func (i AuthCheckType) String() string
func (*AuthCheckType) UnmarshalText ¶
func (i *AuthCheckType) UnmarshalText(text []byte) error
UnmarshalText implements the encoding.TextUnmarshaler interface for AuthCheckType
type AuthFactor ¶
type AuthFactorPasskey ¶
type AuthFactorPasskey struct {
UserVerified bool
UserID string
CredentialID []byte
BackupEligible bool
BackupState bool
// contains filtered or unexported fields
}
func SetAuthFactorPasskey ¶
func SetAuthFactorPasskey(lastVerifiedAt time.Time) *AuthFactorPasskey
func (*AuthFactorPasskey) GetLastVerifiedAt ¶
func (*AuthFactorPasskey) Payload ¶
func (a *AuthFactorPasskey) Payload() any
func (*AuthFactorPasskey) SetLastVerifiedAt ¶
func (*AuthFactorPasskey) Type ¶
func (a *AuthFactorPasskey) Type() AuthCheckType
type AuthFactorPasskeyRegistration ¶
type AuthFactorPasskeyRegistration struct {
UserVerified bool
UserID string
// CredentialID is base64url-encoded ([EncodePasskeyCredentialID]).
CredentialID string
BackupEligible bool
BackupState bool
// PasskeyID and Name identify the persisted credential row, so callers of
// the verify transaction can answer with the created passkey without a
// read-back that could fail after the ceremony is already consumed.
PasskeyID string
Name string
// contains filtered or unexported fields
}
AuthFactorPasskeyRegistration records a completed passkey enrollment on the attempt. It merges into the session as a passkey-class factor: creating the credential with user verification proves possession and presence just like an assertion does for that credential.
func SetAuthFactorPasskeyRegistration ¶
func SetAuthFactorPasskeyRegistration(lastVerifiedAt time.Time) *AuthFactorPasskeyRegistration
func (*AuthFactorPasskeyRegistration) GetLastVerifiedAt ¶
func (*AuthFactorPasskeyRegistration) Payload ¶
func (a *AuthFactorPasskeyRegistration) Payload() any
func (*AuthFactorPasskeyRegistration) SetLastVerifiedAt ¶
func (*AuthFactorPasskeyRegistration) Type ¶
func (a *AuthFactorPasskeyRegistration) Type() AuthCheckType
type AuthFactorPassword ¶
type AuthFactorPassword struct {
// contains filtered or unexported fields
}
func SetAuthFactorPassword ¶
func SetAuthFactorPassword(lastVerifiedAt time.Time) *AuthFactorPassword
func (*AuthFactorPassword) GetLastVerifiedAt ¶
func (*AuthFactorPassword) Payload ¶
func (a *AuthFactorPassword) Payload() any
func (*AuthFactorPassword) SetLastVerifiedAt ¶
func (*AuthFactorPassword) Type ¶
func (a *AuthFactorPassword) Type() AuthCheckType
type AuthFactorPayload ¶
type AuthFactorUser ¶
type AuthFactorUser struct {
UserID string
// contains filtered or unexported fields
}
func SetAuthFactorUser ¶
func SetAuthFactorUser(lastVerifiedAt time.Time) *AuthFactorUser
func (*AuthFactorUser) GetLastVerifiedAt ¶
func (*AuthFactorUser) Payload ¶
func (a *AuthFactorUser) Payload() any
func (*AuthFactorUser) SetLastVerifiedAt ¶
func (*AuthFactorUser) Type ¶
func (a *AuthFactorUser) Type() AuthCheckType
type AuthTokenIssuedPayload ¶
type AuthTokenIssuedPayload struct {
Scopes []string `json:"scopes,omitempty"`
}
type AuthTokenRevokedPayload ¶
type AuthTokenRevokedPayload struct{}
type AuthzAssignment ¶
type AuthzAssignment struct {
ID string
ProjectID string
CatalogID string
PrincipalType AuthzPrincipalType
PrincipalID string
ObjectType string
Relation string
ScopeKind AuthzScopeKind
ScopeTeamID *string
ScopeResourceID *string
GrantorType *string
GrantorID *string
DelegationID *string
ExpiresAt *time.Time
RevokedAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
AuthzAssignment binds a principal to a catalog relation at an explicit scope. This is a grant row for the grants API / resolver — not dual-written from ordinary CreateUser/CreateTeam.
Relation identity is (ObjectType, Relation), matching authz_relations.
func NewClaimTeamAssignment ¶
func NewClaimTeamAssignment(projectID, teamID string) *AuthzAssignment
NewClaimTeamAssignment is the grant claim/complete writes (ADR 046 §1): the team principal on the seeded project.team relation at project scope, making the project owned by the claiming user's personal team. Grantor columns stay unset — the schema CHECK ties grantor_id to delegation_id, so claimed-by provenance is carried by the authz.granted audit event's actor instead.
func NewSKProjProjectSetupAssignment ¶
func NewSKProjProjectSetupAssignment(projectID string) *AuthzAssignment
NewSKProjProjectSetupAssignment is the grant seeded at CreateProject so the returned full project secret can set up the project via resolver.Check.
Relation is project.viewer (not admin): the seeded system catalog closure treats viewer as the assigned relation that satisfies viewer/editor/admin checks (placeholders pending #420). PrincipalID equals the project id so the grant survives secret rotate/claim.
func (*AuthzAssignment) ApplyScope ¶
func (a *AuthzAssignment) ApplyScope(scope AuthzAssignmentScope)
ApplyScope sets the scope columns from a constructor-built scope value.
type AuthzAssignmentScope ¶
type AuthzAssignmentScope struct {
Kind AuthzScopeKind
TeamID *string
ResourceID *string
}
AuthzAssignmentScope encodes the CHECK-constrained scope columns.
func NewProjectAssignmentScope ¶
func NewProjectAssignmentScope() AuthzAssignmentScope
func NewResourceAssignmentScope ¶
func NewResourceAssignmentScope(resourceID string) AuthzAssignmentScope
func NewTeamAssignmentScope ¶
func NewTeamAssignmentScope(teamID string) AuthzAssignmentScope
type AuthzCatalog ¶
type AuthzCatalog struct {
ID string
CatalogKind AuthzCatalogKind
OwnerID string
Version int
Status AuthzCatalogStatus
SourceHash *string
Relations []AuthzRelation
References []AuthzRelationReference
Edges []AuthzExpressionEdge
Closure []AuthzRelationClosure
}
AuthzCatalog is one persisted catalog version plus its projected relation rows (authz_relations / references / expression_edges / relation_closure).
type AuthzCatalogKind ¶
type AuthzCatalogKind string
AuthzCatalogKind is authz_catalogs.catalog_kind.
const ( AuthzCatalogKindSystem AuthzCatalogKind = "system" AuthzCatalogKindAppGroup AuthzCatalogKind = "app_group" )
func (AuthzCatalogKind) String ¶
func (k AuthzCatalogKind) String() string
type AuthzCatalogStatus ¶
type AuthzCatalogStatus string
AuthzCatalogStatus is authz_catalogs.status.
const ( AuthzCatalogStatusDraft AuthzCatalogStatus = "draft" AuthzCatalogStatusActive AuthzCatalogStatus = "active" AuthzCatalogStatusRetired AuthzCatalogStatus = "retired" )
func (AuthzCatalogStatus) String ¶
func (s AuthzCatalogStatus) String() string
type AuthzCatalogVersion ¶
type AuthzCatalogVersion struct {
ID string
CatalogKind AuthzCatalogKind
OwnerID string
Version int
SourceHash *string
}
AuthzCatalogVersion is the catalog row metadata written with a compiled CatalogMutations payload (see PersistCatalogVersion).
type AuthzCheckParams ¶
type AuthzCheckParams struct {
CatalogID string
ProjectID string
PrincipalHomeProjectID string
PrincipalType AuthzPrincipalType
PrincipalID string
ObjectType string
Relation string
ConstraintTeamID string
ResourceID string
// ResourceTeamID is RSI.team_id for by-id Check (team-scoped grant arm).
ResourceTeamID string
}
AuthzCheckParams is the storage-level input for a single-resource permission check. PrincipalHomeProjectID is the project used for membership-edge lookup (defaults to ProjectID).
ConstraintTeamID, when set (sk_team_ tokens), requires the checked or listed object to belong to that team: users via authz_membership_edges, teams by id, other kinds via resource_scope_index.team_id (Check binds ResourceTeamID). ResourceID is the object being checked (empty for permission-level Check / list materialization). ResourceTeamID is RSI.team_id for by-id Check.
func (AuthzCheckParams) HomeProjectID ¶
func (p AuthzCheckParams) HomeProjectID() string
HomeProjectID returns PrincipalHomeProjectID, or ProjectID when unset.
type AuthzExpressionEdge ¶
type AuthzExpressionEdge struct {
ObjectType string
Relation string
Kind string
SourceObjectType *string
SourceRelation *string
TuplesetObjectType *string
TuplesetRelation *string
Position int
}
AuthzExpressionEdge is one authz_expression_edges row. Kind is the CHECK value: direct | computed_userset | tuple_to_userset.
type AuthzGrantedPayload ¶
type AuthzListObjectsParams ¶
type AuthzListObjectsParams struct {
AuthzCheckParams
ResourceKind ResourceKind
}
AuthzListObjectsParams lists resource_scope_index ids the principal may see for one resource kind under a required catalog relation (L4 / oracle helper). Endpoint wiring injects an authz predicate into the resource query (ADR 033).
type AuthzMemberType ¶
type AuthzMemberType string
AuthzMemberType is authz_membership_edges.member_type.
const (
AuthzMemberTypeUser AuthzMemberType = "user"
)
func (AuthzMemberType) String ¶
func (t AuthzMemberType) String() string
type AuthzMembershipEdge ¶
type AuthzMembershipEdge struct {
ProjectID string
MemberType AuthzMemberType
MemberID string
SetType AuthzSetType
SetID string
CreatedAt time.Time
}
AuthzMembershipEdge is the authz projection of set membership (not lifecycle). The resolver expands team grants through these edges; team_memberships remains the roster table and is not read at check time.
func NewUserTeamMembershipEdge ¶
func NewUserTeamMembershipEdge(projectID, teamID, userID string) *AuthzMembershipEdge
type AuthzMembershipEdgeField ¶
type AuthzMembershipEdgeField uint8
AuthzMembershipEdgeField enumerates AuthzMembershipEdge columns for filter deletes.
const ( AuthzMembershipEdgeFieldUnspecified AuthzMembershipEdgeField = iota AuthzMembershipEdgeFieldProjectID AuthzMembershipEdgeFieldMemberType AuthzMembershipEdgeFieldMemberID AuthzMembershipEdgeFieldSetType AuthzMembershipEdgeFieldSetID AuthzMembershipEdgeFieldCreatedAt )
type AuthzMembershipEdgeKey ¶
type AuthzMembershipEdgeKey struct {
ProjectID string
SetType AuthzSetType
SetID string
MemberType AuthzMemberType
MemberID string
}
AuthzMembershipEdgeKey identifies one authz_membership_edges row.
func NewUserTeamMembershipEdgeKey ¶
func NewUserTeamMembershipEdgeKey(projectID, teamID, userID string) AuthzMembershipEdgeKey
type AuthzPrincipalType ¶
type AuthzPrincipalType string
AuthzPrincipalType is authz_assignments.principal_type (no project principals; see D13).
const ( AuthzPrincipalTypeUser AuthzPrincipalType = "user" AuthzPrincipalTypeTeam AuthzPrincipalType = "team" AuthzPrincipalTypeAgent AuthzPrincipalType = "agent" AuthzPrincipalTypeSKProj AuthzPrincipalType = "sk_proj" AuthzPrincipalTypeSKTeam AuthzPrincipalType = "sk_team" )
func (AuthzPrincipalType) String ¶
func (t AuthzPrincipalType) String() string
type AuthzRelation ¶
type AuthzRelation struct {
ObjectType string
Relation string
Kind AuthzRelationKind
}
AuthzRelation is one authz_relations row.
type AuthzRelationClosure ¶
type AuthzRelationClosure struct {
FromObjectType string
FromRelation string
ToObjectType string
ToRelation string
Depth int
}
AuthzRelationClosure is one authz_relation_closure row.
type AuthzRelationKind ¶
type AuthzRelationKind string
AuthzRelationKind is authz_relations.kind.
const ( AuthzRelationKindRelation AuthzRelationKind = "relation" AuthzRelationKindPermission AuthzRelationKind = "permission" )
func (AuthzRelationKind) String ¶
func (k AuthzRelationKind) String() string
type AuthzRelationReference ¶
type AuthzRelationReference struct {
ObjectType string
Relation string
RefType string
RefRelation string
Wildcard bool
Condition string
Position int
}
AuthzRelationReference is one authz_relation_references row.
type AuthzRevokedPayload ¶
type AuthzScopeKind ¶
type AuthzScopeKind string
AuthzScopeKind is authz_assignments.scope_kind.
const ( AuthzScopeKindProject AuthzScopeKind = "project" AuthzScopeKindTeam AuthzScopeKind = "team" AuthzScopeKindResource AuthzScopeKind = "resource" )
func (AuthzScopeKind) String ¶
func (k AuthzScopeKind) String() string
type AuthzSetType ¶
type AuthzSetType string
AuthzSetType is authz_membership_edges.set_type.
const (
AuthzSetTypeTeam AuthzSetType = "team"
)
func (AuthzSetType) String ¶
func (t AuthzSetType) String() string
type Branding ¶
type Branding struct {
ProjectID string
ID string
Layout string
LiquidTemplate string
LogoURL string
FontURL string
HeroURL string
CreatedAt time.Time
}
Branding is one immutable branding revision for a project. Revisions are never updated or deleted; every edit publishes a new revision and flow responses resolve the newest one per project (ADR 040).
type BrandingCreatedPayload ¶
type BrandingCreatedPayload = BrandingPayload
BrandingCreatedPayload is an alias for branding.created.
type BrandingField ¶
type BrandingField uint8
BrandingField enumerates the fields of Branding which can be used for filtering and ordering in list operations.
const ( BrandingFieldUnspecified BrandingField = iota BrandingFieldProjectID BrandingFieldID BrandingFieldCreatedAt )
type BrandingPayload ¶
type ClaimChallenge ¶
type ClaimChallenge struct {
// ID is the SHA-256 hash of the challenge token. It is the primary key and
// is supplied by the caller, not minted here.
ID string
// ProjectID links to [Project].
ProjectID string
// InitiatingSecretHash is the SHA-256 of the project secret that initiated
// the claim; it proves possession on claim/status (see Claim E1).
InitiatingSecretHash string
Status ClaimChallengeStatus
ExpiresAt time.Time
CreatedAt time.Time
}
ClaimChallenge is the ephemeral proof-of-possession record for a project claim (ADR 046). Its ID is the SHA-256 hash of a handoff-token-style challenge token minted by the caller: the plaintext travels outside the system, only the hash is stored.
func NewClaimChallenge ¶
func NewClaimChallenge(id, projectID, initiatingSecretHash string, expiresAt time.Time) (*ClaimChallenge, error)
NewClaimChallenge builds a pending claim challenge. Unlike managed resources the ID is not minted here: it is the externally computed SHA-256 hash of the challenge token (handoff-token pattern, ADR 046 §3).
type ClaimChallengeCreatedPayload ¶
type ClaimChallengeCreatedPayload struct{}
type ClaimChallengeStatus ¶
type ClaimChallengeStatus string
ClaimChallengeStatus is the lifecycle state of a claim challenge. It mirrors the DB CHECK on claim_challenges.status.
const ( ClaimChallengeStatusPending ClaimChallengeStatus = "pending" ClaimChallengeStatusCompleted ClaimChallengeStatus = "completed" )
func (ClaimChallengeStatus) String ¶
func (s ClaimChallengeStatus) String() string
type ClaimCompletedPayload ¶
type ClaimCompletedPayload struct {
TeamID string `json:"team_id,omitempty"`
}
type ClaimConflictDetails ¶
type ClaimConflictDetails struct {
TeamID string `json:"team_id"`
DashboardURL string `json:"dashboard_url"`
}
ClaimConflictDetails is the client-facing details body of the 409 already_claimed response: the owning team and where to manage the project.
type CollectedAuthMethodData ¶
type CollectedAuthMethodData struct {
Password string
}
type CollectedFlowData ¶
type CollectedFlowData struct {
UserData map[string]any
UserID string
AuthMethods CollectedAuthMethodData
}
type CreateAttribute ¶
type CreateAttribute struct {
Key AttributeKey `json:"key"`
Value any `json:"value"`
UniqueScope AttributeUniqueness `json:"unique_scope"`
ValueHash [sha256.Size]byte `json:"value_hash"`
}
func NewCreateAttribute ¶
func NewCreateAttribute(key AttributeKey, value any, unique AttributeUniqueness) (*CreateAttribute, error)
type CreateAttributes ¶
type CreateAttributes []CreateAttribute
func CreateAttributesFromMap ¶
func (CreateAttributes) Get ¶
func (attrs CreateAttributes) Get(key AttributeKey) (value *CreateAttribute, ok bool)
Get returns the value for the given key.
TODO(go v27): make this method generic
type CreateRecoveryCodes ¶
type CreateUser ¶
type CreateUser struct {
ProjectID string
SchemaURL string
ID string
// LifecycleOwnerTeamID decides who manages this user's identity lifecycle (ADR 024).
// nil => self-owned: the user survives team deletion and owns their own deprovisioning.
// set => team-owned: deleting/deactivating that team can deactivate this user per policy.
LifecycleOwnerTeamID *string
// InitialMembershipTeamID is optional membership context at create time — not lifecycle ownership.
// When set, Create also inserts an active team_memberships row for this team and uses it as the
// team-scoped EAV uniqueness scope for attributes. A self-owned signup user can still set this
// to their default workspace team; an enterprise provisioned user may set both fields to the
// same tenant team, but lifecycle ownership and team membership remain separate concerns.
InitialMembershipTeamID *string
Attributes CreateAttributes
}
func NewCreateUser ¶
func NewCreateUser(params CreateUserParams) (*CreateUser, error)
NewCreateUser builds a CreateUser from the schema-defined attributes.
func (*CreateUser) AttributeTeamScope ¶
func (c *CreateUser) AttributeTeamScope() string
AttributeTeamScope returns the team id used for team-scoped unique attributes on create.
type CreateUserParams ¶
type CreateUserParams struct {
ProjectID string
// TeamID is optional membership context, not lifecycle ownership — it
// becomes [CreateUser.InitialMembershipTeamID].
TeamID *string
// ID is empty for a server-minted id; non-empty is for ceremony only.
ID string
// SchemaURL names the schema, and Schema is that schema's document.
SchemaURL string
Schema []byte
// Attributes is the instance the schema validates: envelope fields (id,
// schema, metadata) are not part of it, so a schema may declare properties
// of those names and closed-world keywords such as additionalProperties:
// false hold.
Attributes map[string]any
}
CreateUserParams are the inputs to NewCreateUser. A struct rather than positional arguments because ID and SchemaURL are both strings: transposing them would type-check and write a schema url as the row's primary key.
type CreateUserPasskey ¶
type CreateUserPasskey struct {
ID string
ProjectID string
UserID string
CredentialID string
PublicKey []byte
AAGUID []byte
AttestationType *string
Transports []string
SignCount int64
UserVerified bool
BackupEligible bool
BackupState bool
Name string
VerifiedAt *time.Time
}
func VerifyPasskeyRegistration ¶
func VerifyPasskeyRegistration(challenge *PasskeyRegistrationChallenge, attestation []byte, name string) (*CreateUserPasskey, error)
VerifyPasskeyRegistration parses the attestation response and calls webauthn.CreateCredential. Returns a CreateUserPasskey ready for storage. CredentialID is base64url-encoded to ensure valid UTF-8 in the TEXT column (valid for both Postgres and Spanner).
name labels the new credential in passkey management surfaces. It is the caller's if supplied, otherwise derived from the credential — see [PasskeyCredentialName].
type CreateUserTOTP ¶
type CreatedUserDetails ¶
type CreatedUserDetails struct {
UserID string `json:"user_id"`
}
CreatedUserDetails names a user the server created, for the answer that cannot carry its representation.
type EncryptionKey ¶
type EncryptionKey struct {
ID string
ProjectID string
Purpose EncryptionKeyPurpose
Key string
Algorithm jose.ContentEncryption
State KeyState
CreatedAt time.Time
ActivatedAt *time.Time
RetiredAt *time.Time
}
func NewEncryptionKey ¶
func NewEncryptionKey( projectID string, purpose EncryptionKeyPurpose, algorithm jose.ContentEncryption, kek crypto.Crypter, ) (*EncryptionKey, error)
func (*EncryptionKey) Activate ¶
func (k *EncryptionKey) Activate(currentKey *EncryptionKey)
func (*EncryptionKey) DecryptedKey ¶
func (k *EncryptionKey) DecryptedKey(kek crypto.Decrypter) ([32]byte, error)
func (*EncryptionKey) IsActive ¶
func (k *EncryptionKey) IsActive() bool
func (*EncryptionKey) IsRemoved ¶
func (k *EncryptionKey) IsRemoved() bool
func (*EncryptionKey) MigrateToNewMasterKey ¶
func (k *EncryptionKey) MigrateToNewMasterKey(oldMasterKey crypto.Crypter, newMasterKey crypto.Crypter) error
MigrateToNewMasterKey re-wraps the key material under newMasterKey without changing the key itself, so nothing encrypted by this key has to be touched.
type EncryptionKeyField ¶
type EncryptionKeyField uint8
const ( EncryptionKeyFieldUnspecified EncryptionKeyField = iota EncryptionKeyFieldID EncryptionKeyFieldProjectID EncryptionKeyFieldKey EncryptionKeyFieldAlgorithm EncryptionKeyFieldState EncryptionKeyFieldCreatedAt EncryptionKeyFieldActivatedAt EncryptionKeyFieldRetiredAt EncryptionKeyFieldPurpose )
type EncryptionKeyPurpose ¶
type EncryptionKeyPurpose string
const ( // EncryptionKeyPurposeKEK indicates the key is the project's key encryption // key which is used to encrypt the purpose-scoped keys of the project. It is // itself encrypted by the master key. EncryptionKeyPurposeKEK EncryptionKeyPurpose = "kek" // EncryptionKeyPurposeToken indicates the key is used to encrypt tokens EncryptionKeyPurposeToken EncryptionKeyPurpose = "token" // EncryptionKeyPurposeSecret indicates the key is used to encrypt // third-party secrets like client-secrets, passwords,... for third party // applications EncryptionKeyPurposeSecret EncryptionKeyPurpose = "secret" // EncryptionKeyPurposeCookie indicates the key is used to encrypt cookies EncryptionKeyPurposeCookie EncryptionKeyPurpose = "cookie" )
type Environment ¶
func NewEnvironment ¶
func NewEnvironment(projectID, name string) (*Environment, error)
type EnvironmentCreatedPayload ¶
type EnvironmentCreatedPayload = EnvironmentPayload
type EnvironmentField ¶
type EnvironmentField uint8
const ( EnvironmentFieldUnspecified EnvironmentField = iota EnvironmentFieldProjectID EnvironmentFieldID EnvironmentFieldName EnvironmentFieldCreatedAt )
type EnvironmentPayload ¶
type EnvironmentPayload struct {
Name string `json:"name,omitempty"`
}
type Error ¶
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Details any `json:"details,omitempty"`
Parent error `json:"-"`
errreport.Origin
}
func ErrAuthAttemptAlreadyCompleted ¶
func ErrAuthAttemptAlreadyCompleted() Error
ErrAuthAttemptAlreadyCompleted returns an error indicating that the attempt is already completed.
func ErrAuthAttemptAlreadyHandedOff ¶
func ErrAuthAttemptAlreadyHandedOff() Error
ErrAuthAttemptAlreadyHandedOff returns an error indicating that the attempt is already handed off.
func ErrAuthAttemptInvalidProof ¶
func ErrAuthAttemptInvalidProof() Error
ErrAuthAttemptInvalidProof returns an error indicating that the proof is invalid.
func ErrAuthAttemptInvalidRequest ¶
func ErrAuthAttemptInvalidRequest() Error
ErrAuthAttemptInvalidRequest returns an error indicating that the request is invalid.
func ErrAuthAttemptInvalidState ¶
func ErrAuthAttemptInvalidState() Error
ErrAuthAttemptInvalidState returns an error indicating that the attempt is in an invalid state (e.g. expired).
func ErrAuthAttemptNotCompleted ¶
func ErrAuthAttemptNotCompleted() Error
ErrAuthAttemptNotCompleted returns an error indicating that the attempt is not completed.
func ErrAuthAttemptNotFound ¶
func ErrAuthAttemptNotFound() Error
ErrAuthAttemptNotFound returns an error indicating that the requested auth attempt was not found.
func ErrAuthAttemptProofRejected ¶
ErrAuthAttemptProofRejected returns an error indicating that the proof was rejected.
func ErrAuthAttemptStaleChallenge ¶
func ErrAuthAttemptStaleChallenge() Error
ErrAuthAttemptStaleChallenge returns an error indicating that the challenge is stale or has been re-issued.
func ErrAuthUnauthorized ¶
ErrAuthUnauthorized is returned when a request lacks valid credentials (e.g. missing session cookie, unsatisfied security requirement, expired nonce).
func ErrBrandingInvalid ¶
func ErrBrandingMissingProjectID ¶
func ErrBrandingMissingProjectID() Error
func ErrBrandingNotFound ¶
func ErrBrandingNotFound() Error
func ErrBrandingPermissionDenied ¶
func ErrBrandingPermissionDenied() Error
func ErrClaimChallengeInvalid ¶
func ErrClaimChallengeInvalid() Error
func ErrClaimChallengeNotFound ¶
func ErrClaimChallengeNotFound() Error
func ErrClaimNoPersonalTeam ¶
func ErrClaimNoPersonalTeam() Error
ErrClaimNoPersonalTeam covers a claim/complete session user without an active personal team. Impossible once #527's registration auto-creates it; until then it guards manually seeded platform projects.
func ErrClaimSessionExpired ¶
func ErrClaimSessionExpired() Error
func ErrClaimSessionNotActive ¶
func ErrClaimSessionNotActive() Error
func ErrClaimSessionWrongProject ¶
func ErrClaimSessionWrongProject() Error
func ErrDecryptionFailed ¶
func ErrEncryptionFailed ¶
func ErrEncryptionKeyNotFound ¶
func ErrEncryptionKeyNotFound() Error
func ErrEnvironmentNameInvalid ¶
func ErrEnvironmentNameInvalid() Error
func ErrEnvironmentNotFound ¶
func ErrEnvironmentNotFound() Error
func ErrEnvironmentPermissionDenied ¶
func ErrEnvironmentPermissionDenied() Error
func ErrEnvironmentProjectNotFound ¶
func ErrEnvironmentProjectNotFound() Error
func ErrEventInvalid ¶
func ErrEventNotFound ¶
func ErrEventNotFound() Error
func ErrEventPermissionDenied ¶
func ErrEventPermissionDenied() Error
func ErrFlowCompleted ¶
func ErrFlowCompleted() Error
func ErrFlowCookieExpired ¶
func ErrFlowCookieExpired() Error
func ErrFlowCookieInvalid ¶
func ErrFlowCookieInvalid() Error
func ErrFlowDefinitionAlreadyExists ¶
func ErrFlowDefinitionAlreadyExists() Error
func ErrFlowDefinitionNotFound ¶
func ErrFlowDefinitionNotFound() Error
ErrFlowDefinitionNotFound is returned when a direct lookup by name does not match any definition for the project.
func ErrFlowDefinitionPermissionDenied ¶
func ErrFlowDefinitionPermissionDenied() Error
func ErrFlowDefinitionPurposeMismatch ¶
func ErrFlowDefinitionPurposeMismatch() Error
ErrFlowDefinitionPurposeMismatch is returned when a direct lookup matches a definition that does not serve the requested purpose.
func ErrFlowIntegrity ¶
func ErrFlowIntegrity() Error
func ErrFlowInvalidAction ¶
func ErrFlowInvalidAction() Error
func ErrFlowInvalidPurpose ¶
func ErrFlowInvalidPurpose() Error
func ErrFlowNotFound ¶
func ErrFlowNotFound() Error
func ErrFlowSessionConflict ¶
func ErrFlowSessionConflict() Error
func ErrFlowUnsupported ¶
func ErrFlowUnsupported() Error
func ErrGrantAlreadyExists ¶
func ErrGrantAlreadyExists() Error
func ErrGrantInvalid ¶
func ErrGrantInvalid() Error
func ErrGrantNotFound ¶
func ErrGrantNotFound() Error
func ErrGrantPermissionDenied ¶
func ErrGrantPermissionDenied() Error
func ErrGrantPrincipalNotFound ¶
func ErrGrantPrincipalNotFound() Error
func ErrInternal ¶
ErrInternal is the catch-all for unexpected errors that have no specific domain code.
func ErrInvalidToken ¶
func ErrInvalidToken() Error
func ErrInvalidTokenIdentifiers ¶
func ErrInvalidTokenIdentifiers() Error
ErrInvalidTokenIdentifiers is returned when session identifier fields do not match Token.Type.
func ErrJSONSchemaAlreadyExists ¶
func ErrJSONSchemaAlreadyExists() Error
func ErrJSONSchemaInvalid ¶
func ErrJSONSchemaInvalid() Error
func ErrJSONSchemaNotFound ¶
func ErrJSONSchemaNotFound() Error
func ErrJSONSchemaPermissionDenied ¶
func ErrJSONSchemaPermissionDenied() Error
func ErrJSONSchemaRevisionConflict ¶
func ErrJSONSchemaRevisionConflict() Error
ErrJSONSchemaRevisionConflict reports that another revision of the same object type already holds this creation timestamp. Which of the two is the latest would be undecidable, so the loser is rejected and the caller can simply retry.
func ErrMissingFlowDefinitionID ¶
func ErrMissingFlowDefinitionID() Error
func ErrMissingProjectID ¶
func ErrMissingProjectID() Error
func ErrNoReplacementKey ¶
func ErrNoReplacementKey() Error
func ErrNotImplemented ¶
func ErrNotImplemented() Error
func ErrPersonalTeamNotActive ¶
ErrPersonalTeamNotActive covers a platform user whose personal team exists but is not active: the membership was flipped, or the team was deactivated and cascaded the membership to removed.
Deliberately distinct from ErrClaimNoPersonalTeam. "You hold no membership" is provisioned automatically on the next sign-in, while a membership that is not active will not be provisioned around, so a UI has to say different things about them.
What clears it depends on the status, which is why Details carries it rather than the message summarising one cause: `removed` follows a team or user deactivation and needs an administrator, while `pending` is an invitation the user can still accept.
func ErrProjectAlreadyClaimed ¶
func ErrProjectAlreadyClaimed() Error
func ErrProjectClaimExpired ¶
func ErrProjectClaimExpired() Error
func ErrProjectMissingID ¶
func ErrProjectMissingID() Error
func ErrProjectNameInvalid ¶
func ErrProjectNameInvalid() Error
func ErrProjectNotFound ¶
func ErrProjectNotFound() Error
func ErrProjectPermissionDenied ¶
func ErrProjectPermissionDenied() Error
func ErrRequestInvalid ¶
func ErrRequestInvalid() Error
ErrRequestInvalid is returned when an incoming HTTP request fails structural validation (missing required fields, wrong types, failed regex, etc.) before it reaches domain logic.
func ErrSchemaFetchFailed ¶
func ErrSessionExchangeConflict ¶
func ErrSessionExchangeConflict() Error
func ErrSessionInvalidHandoffToken ¶
func ErrSessionInvalidHandoffToken() Error
func ErrSessionInvalidTTL ¶
func ErrSessionInvalidTTL() Error
func ErrSessionNotFound ¶
func ErrSessionNotFound() Error
func ErrSessionPermissionDenied ¶
func ErrSessionPermissionDenied() Error
func ErrSessionTokenCreationFailed ¶
func ErrSessionTokenCreationFailed() Error
func ErrSessionTokenInvalid ¶
func ErrSessionTokenInvalid() Error
func ErrSigningKeyNotFound ¶
func ErrSigningKeyNotFound() Error
func ErrSupportedEncryptionAlgorithm ¶
func ErrSupportedEncryptionAlgorithm(alg jose.ContentEncryption) Error
func ErrTeamAlreadyExists ¶
func ErrTeamAlreadyExists() Error
func ErrTeamNameInvalid ¶
func ErrTeamNameInvalid() Error
func ErrTeamNotFound ¶
func ErrTeamNotFound() Error
func ErrTeamPermissionDenied ¶
func ErrTeamPermissionDenied() Error
func ErrTeamProjectNotFound ¶
func ErrTeamProjectNotFound() Error
func ErrTokenRevoked ¶
func ErrTokenRevoked() Error
ErrTokenRevoked is returned when a token decrypts and is well-formed but its record no longer grants anything — gone from storage or expired. It is deliberately indistinguishable from ErrInvalidToken to a caller: a bearer learns only that the credential does not work.
func ErrUnavailable ¶
func ErrUnavailable() Error
ErrUnavailable is returned when a request failed for a transient reason and retrying it may succeed, typically a database transaction that exhausted its abort retries under contention. Separate from ErrInternal because the caller's correct response differs: retry, rather than report a bug.
func ErrUserAlreadyExists ¶
func ErrUserAlreadyExists() Error
func ErrUserInvalid ¶
func ErrUserInvalid() Error
func ErrUserNotFound ¶
func ErrUserNotFound() Error
func ErrUserPasswordInvalid ¶
func ErrUserPasswordInvalid() Error
func ErrUserPermissionDenied ¶
func ErrUserPermissionDenied() Error
func TokenNotFound ¶
func TokenNotFound() Error
func (Error) LogValue ¶
LogValue implements slog.LogValuer. Details are client-facing and omitted from logs by default (ADR 030).
func (Error) WithDetails ¶
WithDetails returns a copy with additional context attached. Code is unchanged so errors.Is still matches the original sentinel.
func (Error) WithMessage ¶
WithMessage returns a copy with the message overridden. Code is unchanged so errors.Is still matches the original sentinel.
func (Error) WithParent ¶
WithParent returns a copy wrapping a lower-level cause. Code is unchanged so errors.Is still matches the original sentinel.
type Event ¶
type Event struct {
ProjectID string
ID string
EventType EventType
Category EventCategory
OccurredAt time.Time
CreatedAt time.Time
TeamID *string
ActorID *string
ActorType *EventActorType
EntityType *string
EntityID *string
ClientID string
TokenID string
DelegationType string
DelegationID string
Grantor string
Fingerprint string
RequestID *string
SessionID *string
FlowID *string
Payload json.RawMessage
Metadata json.RawMessage
// OccurredAtWait is an insert-only hint for Path A batching: dialects set
// occurred_at = created_at - wait (DB clock or equivalent). Path A wait is
// time since HTTP request start so request.api sorts first on request_id.
// Zero means Path B (occurred_at = created_at). Not a persisted column.
OccurredAtWait time.Duration
}
Event is one append-only wide-event row (ADR 048).
type EventActorType ¶
type EventActorType string
EventActorType is who triggered the event.
const ( EventActorTypeHuman EventActorType = "human" EventActorTypeService EventActorType = "service" EventActorTypeSystem EventActorType = "system" EventActorTypeAgent EventActorType = "agent" )
type EventCategory ¶
type EventCategory string
EventCategory is the ADR 048 wide-event category.
const ( EventCategoryRequest EventCategory = "request" EventCategoryAuth EventCategory = "auth" EventCategorySession EventCategory = "session" EventCategoryAdmin EventCategory = "admin" EventCategoryEntity EventCategory = "entity" EventCategorySignal EventCategory = "signal" )
type EventClientMetadata ¶
type EventClientMetadata struct {
IP string `json:"ip,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
Origin string `json:"origin,omitempty"`
}
EventClientMetadata is Path A requestor context on events.metadata.client.
type EventField ¶
type EventField uint8
EventField enumerates filterable/sortable Event columns.
const ( EventFieldUnspecified EventField = iota EventFieldProjectID EventFieldID EventFieldEventType EventFieldCategory EventFieldOccurredAt EventFieldCreatedAt EventFieldTeamID EventFieldActorID EventFieldActorType EventFieldEntityType EventFieldEntityID EventFieldClientID EventFieldTokenID EventFieldFingerprint EventFieldRequestID EventFieldSessionID EventFieldFlowID )
type EventMetadata ¶
type EventMetadata struct {
Client *EventClientMetadata `json:"client,omitempty"`
}
EventMetadata is the events.metadata JSON object.
type EventSink ¶
type EventSink struct {
ID string
Type EventSinkType
Scope EventSinkScope
ProjectID *string
URL string
Enabled bool
}
EventSink is a first-class export destination (ADR 049).
type EventSinkCursor ¶
type EventSinkCursor struct {
SinkID string
ProjectID string
LastCreatedAt time.Time
LastEventID string
}
EventSinkCursor is a per-(sink, project) watermark for export (ADR 049). Progress is keyset-ordered on (last_created_at, last_event_id).
type EventSinkScope ¶
type EventSinkScope string
const ( EventSinkScopeDeployment EventSinkScope = "deployment" EventSinkScopeProject EventSinkScope = "project" )
type EventSinkType ¶
type EventSinkType string
const ( EventSinkTypeStdout EventSinkType = "stdout" EventSinkTypeWebhook EventSinkType = "webhook" )
type EventType ¶
type EventType string
EventType is a semantic event name (dot-separated), e.g. user.created.
const ( EventTypeRequestAPI EventType = "request.api" EventTypeProjectCreated EventType = "project.created" EventTypeProjectUpdated EventType = "project.updated" EventTypeProjectDeleted EventType = "project.deleted" EventTypeUserCreated EventType = "user.created" EventTypeUserCreateFailed EventType = "user.create.failed" EventTypeUserDeleted EventType = "user.deleted" EventTypeTeamCreated EventType = "team.created" EventTypeTeamUpdated EventType = "team.updated" EventTypeTeamDeactivated EventType = "team.deactivated" EventTypeAuthTokenIssued EventType = "auth.token.issued" EventTypeAuthTokenRevoked EventType = "auth.token.revoked" EventTypeSessionEstablished EventType = "session.established" EventTypeSessionDeleted EventType = "session.deleted" EventTypeAuthAttemptCreated EventType = "auth.attempt.created" EventTypeAuthAttemptHandedOff EventType = "auth.attempt.handed_off" EventTypeAuthCheckFailed EventType = "auth.check.failed" EventTypeAuthCheckSucceeded EventType = "auth.check.succeeded" EventTypeFlowdefCreated EventType = "flowdef.created" EventTypeFlowdefUpdated EventType = "flowdef.updated" EventTypeFlowdefDeleted EventType = "flowdef.deleted" EventTypeSchemaCreated EventType = "schema.created" EventTypeBrandingCreated EventType = "branding.created" EventTypeEnvironmentCreated EventType = "environment.created" EventTypeAuthzGranted EventType = "authz.granted" EventTypeAuthzRevoked EventType = "authz.revoked" EventTypeAuthFactorPasswordSet EventType = "auth.factor.password.set" EventTypeAuthFactorPasskeyEnrolled EventType = "auth.factor.passkey.enrolled" )
Path A / Path B event types with live producers (see docs/design/api/events-catalog.md). Deferred types live only in the catalog Deferred section until follow-up issues land.
type Field ¶
type Field string
Field carries the raw field name from a flow-definition step.
func FieldsFromStrings ¶
FieldsFromStrings lifts wire-format string field names into typed Field values at the API/repository boundary.
func (Field) AuthMethod ¶
AuthMethod returns the method name after the `x-auth-methods#` prefix (e.g. "password").
func (Field) IsAuthMethod ¶
IsAuthMethod reports whether the field references an `x-auth-methods` entry.
func (Field) IsUserProperty ¶
IsUserProperty reports whether the field names a user-schema property.
type FlowAction ¶
type FlowAction struct {
Name string
Kind FlowActionKind
TextKey string
Primary bool
}
FlowAction is a single user action surfaced on FlowStep.Actions.
type FlowActionKind ¶
type FlowActionKind uint8
FlowActionKind classifies what the engine should do when a user invokes an action. Submit-style kinds run the input pipeline (field validation, challenge dispatch, on_success); Navigate skips the pipeline and just follows the matching transition.
const ( // FlowActionKindUnset is the zero value. stepActionKind returns it // when the submitted name isn't declared on the step. FlowActionKindUnset FlowActionKind = iota // FlowActionKindSubmit advances by collecting the step's fields and // running the standard validate/dispatch/on_success pipeline. FlowActionKindSubmit // FlowActionKindPasskey issues a WebAuthn assertion challenge and // resolves the matching transition once the assertion verifies. FlowActionKindPasskey // FlowActionKindPasskeyRegister issues a WebAuthn registration // challenge and resolves the matching transition once the attestation // verifies. FlowActionKindPasskeyRegister // the input pipeline. Used for pure-routing actions declared in the flow // definition where the submitted fields are irrelevant. FlowActionKindNavigate // FlowActionKindBack pops the previous step from runtime history and // re-renders it. Injected by the engine on rendered step responses when // history is non-empty and the current step is non-terminal; rejected by // the validator on inbound flow definitions — flow authors never declare it. FlowActionKindBack )
func FlowActionKindString ¶
func FlowActionKindString(s string) (FlowActionKind, error)
FlowActionKindString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowActionKindValues ¶
func FlowActionKindValues() []FlowActionKind
FlowActionKindValues returns all values of the enum
func (FlowActionKind) IsAFlowActionKind ¶
func (i FlowActionKind) IsAFlowActionKind() bool
IsAFlowActionKind returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowActionKind) Scan ¶
func (i *FlowActionKind) Scan(value interface{}) error
func (FlowActionKind) String ¶
func (i FlowActionKind) String() string
type FlowAuthAttemptService ¶
type FlowAuthAttemptService interface {
Start(ctx context.Context, in FlowCreateAttemptInput) (attemptID string, err error)
SubmitIdentifier(ctx context.Context, in FlowSubmitIdentifierInput) (userID string, err error)
SubmitPassword(ctx context.Context, in FlowSubmitPasswordInput) error
// IssuePasskeyChallenge mints a WebAuthn assertion challenge and
// returns its id plus the PublicKeyCredentialRequestOptions the
// browser passes to navigator.credentials.get().
IssuePasskeyChallenge(ctx context.Context, in FlowIssuePasskeyChallengeInput) (FlowPasskeyChallengeOutput, error)
// SubmitPasskey verifies the assertion against the issued challenge
// and returns the authenticated user id. For a discoverable login the
// user is resolved from the assertion; for an identified login it is
// the already-pinned user. Rejection surfaces as
// [ErrAuthAttemptProofRejected].
SubmitPasskey(ctx context.Context, in FlowSubmitPasskeyInput) (userID string, err error)
// IssuePasskeyRegistrationChallenge mints a WebAuthn registration
// challenge on the attempt and returns its id plus the
// PublicKeyCredentialCreationOptions the browser passes to
// navigator.credentials.create(). Enrollment rides the same two-phase
// ceremony shape as [IssuePasskeyChallenge]/[SubmitPasskey].
IssuePasskeyRegistrationChallenge(ctx context.Context, in FlowIssuePasskeyRegistrationChallengeInput) (FlowPasskeyRegistrationChallengeOutput, error)
// SubmitPasskeyRegistration verifies the attestation against the issued
// challenge and persists the new credential; for a provisional ceremony
// the user row is created in the same transaction. Rejection surfaces as
// [ErrAuthAttemptProofRejected]; a conflicting user as
// [ErrUserAlreadyExists].
SubmitPasskeyRegistration(ctx context.Context, in FlowSubmitPasskeyRegistrationInput) error
// Handoff mints the single-use token the client exchanges for a
// session. Called by the state machine on the terminal step.
Handoff(ctx context.Context, in FlowHandoffInput) (FlowHandoffOutput, error)
}
FlowAuthAttemptService is the FlowStateMachine's narrow view of the auth-attempt domain. Submit* calls collapse the underlying issue-then-verify cycle so the state machine never sees challenge IDs. Identifier no-match and password failure surface as ErrAuthAttemptProofRejected (use errors.Is).
Passkey is the exception: it is a two-phase WebAuthn ceremony, so it cannot collapse issue+verify into one call. [IssuePasskeyChallenge] mints the options the browser signs; [SubmitPasskey] verifies the returned assertion. The state machine threads the challenge id between the two via FlowState.PendingChallenge.
type FlowAuthRequestRef ¶
FlowAuthRequestRef ties a flow to the OIDC authorization request it is fulfilling.
type FlowBackEntry ¶
type FlowBackEntry struct {
StepName string
// Purpose is kept in the history so the flow returns with the current purpose.
Purpose FlowDefinitionPurpose
}
FlowBackEntry holds an entry to be pushed into BackStack.
type FlowChallengeResponse ¶
type FlowChallengeResponse struct {
ChallengeID string
Method string
// Proof is the method-specific payload (for passkey, the WebAuthn
// PublicKeyCredential assertion JSON).
Proof []byte
}
FlowChallengeResponse is the client's answer to a FlowPendingChallenge.
type FlowCreateAttemptInput ¶
type FlowCreateAttemptInput struct {
ProjectID string
SessionID *string
RequiredChecks []AuthCheckType
}
FlowCreateAttemptInput is the bootstrap input to FlowAuthAttemptService.Start. SessionID is set only for step-up auth; RequiredChecks overrides the project default when pinned.
type FlowDefinition ¶
type FlowDefinition struct {
ProjectID string
ID string
Name string
SchemaVersion string
Status FlowDefinitionStatus
CreatedAt time.Time
UpdatedAt time.Time
// UserSchema is the URL of the JSON schema this flow operates on.
UserSchema string
// Purposes maps each purpose this definition handles to the name of
// its entry-point step. Every value must match a step in [Steps].
Purposes map[FlowDefinitionPurpose]string
Audience FlowDefinitionAudience
Steps []FlowDefinitionStep
}
FlowDefinition is a customer-configured directed graph of authentication steps. It is immutable: modifications produce a new revision with a new SchemaVersion.
func NewFlowDefinition ¶
func NewFlowDefinition( flowDefID string, projectID string, name string, schemaVersion string, userSchema string, purposes map[FlowDefinitionPurpose]string, audience FlowDefinitionAudience, steps []FlowDefinitionStep, status FlowDefinitionStatus, ) (_ *FlowDefinition, err error)
func (*FlowDefinition) FindStep ¶
func (d *FlowDefinition) FindStep(name string) (*FlowDefinitionStep, bool)
FindStep returns a pointer into d.Steps for the step named name, or false if no such step exists.
func (*FlowDefinition) InitialStepFor ¶
func (d *FlowDefinition) InitialStepFor(purpose FlowDefinitionPurpose) (string, bool)
InitialStepFor returns the entry-point step name for purpose, or false if the definition does not serve it.
type FlowDefinitionAudience ¶
FlowDefinitionAudience describes which requests this definition should be selected for. Empty slices (or nil) mean "no restriction". Specificity for resolution is app > team > project-wide (both empty).
type FlowDefinitionField ¶
type FlowDefinitionField uint8
FlowDefinitionField enumerates the fields of FlowDefinition which can be used for ordering in list operations.
const ( FlowDefinitionFieldUnspecified FlowDefinitionField = iota FlowDefinitionFieldProjectID FlowDefinitionFieldID FlowDefinitionFieldName FlowDefinitionFieldSchemaVersion FlowDefinitionFieldStatus FlowDefinitionFieldCreatedAt FlowDefinitionFieldUpdatedAt FlowDefinitionFieldUserSchema FlowDefinitionFieldPurposes FlowDefinitionFieldAudience FlowDefinitionFieldSteps )
type FlowDefinitionPurpose ¶
type FlowDefinitionPurpose uint8
const ( FlowDefinitionPurposeLogin FlowDefinitionPurpose = iota FlowDefinitionPurposeRegister FlowDefinitionPurposeRecovery FlowDefinitionPurposeProfiling FlowDefinitionPurposeReauth FlowDefinitionPurposeLinkAccount )
func FlowDefinitionPurposeString ¶
func FlowDefinitionPurposeString(s string) (FlowDefinitionPurpose, error)
FlowDefinitionPurposeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowDefinitionPurposeValues ¶
func FlowDefinitionPurposeValues() []FlowDefinitionPurpose
FlowDefinitionPurposeValues returns all values of the enum
func (FlowDefinitionPurpose) IsAFlowDefinitionPurpose ¶
func (i FlowDefinitionPurpose) IsAFlowDefinitionPurpose() bool
IsAFlowDefinitionPurpose returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowDefinitionPurpose) Scan ¶
func (i *FlowDefinitionPurpose) Scan(value interface{}) error
func (FlowDefinitionPurpose) String ¶
func (i FlowDefinitionPurpose) String() string
type FlowDefinitionStatus ¶
type FlowDefinitionStatus uint8
const ( FlowDefinitionStatusDraft FlowDefinitionStatus = iota FlowDefinitionStatusActive FlowDefinitionStatusDeprecated FlowDefinitionStatusArchived )
func FlowDefinitionStatusString ¶
func FlowDefinitionStatusString(s string) (FlowDefinitionStatus, error)
FlowDefinitionStatusString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowDefinitionStatusValues ¶
func FlowDefinitionStatusValues() []FlowDefinitionStatus
FlowDefinitionStatusValues returns all values of the enum
func (FlowDefinitionStatus) IsAFlowDefinitionStatus ¶
func (i FlowDefinitionStatus) IsAFlowDefinitionStatus() bool
IsAFlowDefinitionStatus returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowDefinitionStatus) Scan ¶
func (i *FlowDefinitionStatus) Scan(value interface{}) error
func (FlowDefinitionStatus) String ¶
func (i FlowDefinitionStatus) String() string
type FlowDefinitionStep ¶
type FlowDefinitionStep struct {
Name string
// Fields lists the user-schema property names this step collects.
// Resolved against [FlowDefinition.UserSchema] at runtime to derive
// per-field type, validation, and implicit outcomes.
Fields []Field
// Actions are the user-selectable actions on this step, in display
// order. Each action's Name is what the frontend echoes back in the
// submit request.
Actions []FlowStepAction
// Gates are security challenges that must be satisfied before the
// step's submission is accepted, keyed by gate name.
Gates map[string]FlowStepGate
// SSOProviders lists the identity providers available on this step.
SSOProviders []FlowSSOProvider
// OnSuccess names the server-side mutation to run after field
// validation passes, before the transition fires. Nil means advance
// directly with no side effect.
OnSuccess *FlowOnSuccess
// Complete, when non-nil, marks this step as terminal and dictates
// how the frontend finishes (redirect vs. success screen). Nil for
// regular interactive steps.
Complete *FlowStepComplete
// Transitions maps an action or engine-emitted outcome name to the
// next state. The key is either an action declared in [Actions] or a
// reserved outcome the engine produces (e.g. `user_not_found`,
// `callback`).
Transitions map[string]FlowStepTransition
}
FlowDefinitionStep is a single node in the step graph.
type FlowDefinitionTransitionAction ¶
type FlowDefinitionTransitionAction uint8
const ( // Switch means switching to a new flow. Redirect the user to a new flow Switch FlowDefinitionTransitionAction = iota // Pivot means switching temporarily to a new flow, then comes back to current flow once done Pivot )
func FlowDefinitionTransitionActionString ¶
func FlowDefinitionTransitionActionString(s string) (FlowDefinitionTransitionAction, error)
FlowDefinitionTransitionActionString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowDefinitionTransitionActionValues ¶
func FlowDefinitionTransitionActionValues() []FlowDefinitionTransitionAction
FlowDefinitionTransitionActionValues returns all values of the enum
func (FlowDefinitionTransitionAction) IsAFlowDefinitionTransitionAction ¶
func (i FlowDefinitionTransitionAction) IsAFlowDefinitionTransitionAction() bool
IsAFlowDefinitionTransitionAction returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowDefinitionTransitionAction) Scan ¶
func (i *FlowDefinitionTransitionAction) Scan(value interface{}) error
func (FlowDefinitionTransitionAction) String ¶
func (i FlowDefinitionTransitionAction) String() string
type FlowField ¶
type FlowField struct {
// Name is the user-schema property this field collects, as a dotted
// path for a nested property (`address.street`).
Name string
// Type is the UI input kind the client should render. It is
// derived from the property's JSON `type` and `format` in the user
// meta-schema. The reserved `x-auth-methods#<method>` field name
// forces the input kind matching that credential method
// (e.g. `x-auth-methods#password` → password).
Type FlowFieldType
// TextKey is a localization key for the field label (e.g.
// `field.email`). Resolved client-side via the `| t` filter.
TextKey string
// Required reflects membership in the schema's `required` array at
// every level of the field's path: a nested leaf is required only
// when each of its ancestors is required too, matching what schema
// validation accepts for the document as a whole.
Required bool
// Value is an optional pre-fill (e.g. an identifier carried over
// from a pivot). Nil when no pre-fill applies.
Value *string
// Validation carries the schema-derived validation rules. Nil when
// the property has no rules beyond its JSON type.
Validation *FlowFieldValidation
// Unique mirrors the property's `x-unique` annotation: the scope at
// which the value must be unique, or [AttributeUniquenessUnspecified]
// when absent. The user-creation path consults it to set the
// per-attribute uniqueness scope on storage.
Unique AttributeUniqueness
// Challenge names the auth-attempt challenge the field maps to, or
// [FlowFieldChallengeNone] when the field carries neither an
// identifier nor a credential proof. Derivation paths: the field
// naming the schema's designated identifier (the schema-root
// `x-identifier` path, ADR 058) surfaces as
// [FlowFieldChallengeIdentifier]; the reserved `x-auth-methods#password` field
// name combined with `x-auth-methods.password.enabled = true` at
// the schema root surfaces as [FlowFieldChallengePassword]. Other
// credential kinds (passkey, magic_link, sso, otp) do not have
// field-shaped proofs and are produced by the state machine as
// challenge steps, not by the resolver. The state machine consults
// Challenge on submit to route the value — identifier fields drive
// identifier resolution (and the `user_not_found` implicit outcome),
// password fields drive the password challenge.
Challenge FlowFieldChallenge
}
FlowField is the resolved per-field metadata.
func FindCollectedFieldByChallenge ¶
func FindCollectedFieldByChallenge(resolved []FlowField, collected map[string]any, target FlowFieldChallenge) (name string, field FlowField, value any, ok bool)
FindCollectedFieldByChallenge looks up a field whose resolved Challenge matches target and whose name is present in collected. Returns the field name, the matched FlowField, and its collected value. Callers that don't need the FlowField discard it.
type FlowFieldChallenge ¶
type FlowFieldChallenge string
FlowFieldChallenge names the auth-attempt challenge a field maps to. Values mirror the keys of `x-auth-methods` in the user meta-schema (api/openapi/endpoints/schemas/user-schema.yaml). `identifier` is sourced from the schema-root `x-identifier` designation; `password` is sourced from the reserved `x-auth-methods#password` field name combined with `x-auth-methods.password.enabled` at the schema root. The remaining credential values (passkey, magic_link, sso, otp) have no field-shaped proof and are produced by the state machine as challenge steps rather than by the resolver. Empty means the field maps to no challenge.
const ( FlowFieldChallengeNone FlowFieldChallenge = "" FlowFieldChallengeIdentifier FlowFieldChallenge = "identifier" FlowFieldChallengePassword FlowFieldChallenge = "password" FlowFieldChallengePasskey FlowFieldChallenge = "passkey" FlowFieldChallengeMagicLink FlowFieldChallenge = "magic_link" FlowFieldChallengeSSO FlowFieldChallenge = "sso" FlowFieldChallengeOTP FlowFieldChallenge = "otp" )
func ManifestForOnSuccess ¶
func ManifestForOnSuccess(o FlowOnSuccess) []FlowFieldChallenge
ManifestForOnSuccess returns the credential kinds a mutation establishes. Dispatch (verify-vs-skip) and the validator (upstream-collects check) both read this table.
type FlowFieldResolver ¶
type FlowFieldResolver interface {
// Resolve returns the per-field metadata for fields against the
// provided user schema. stepName is the flow step the fields are
// being resolved for; it prefixes each field's text_key
// (`<stepName>.field.<name>`). Schema loading is the caller's
// responsibility — see [SchemaResolver].
Resolve(schema *jsonschema.Schema, stepName string, fields []Field) (FlowResolvedFields, error)
// Validate checks submitted values against the rules carried by a
// previously resolved field set.
Validate(fields FlowResolvedFields, values map[string]any) error
// MissingRequired reports the required fields absent from values.
// Applied only on field-collecting actions (the submit action and the
// passkey-register issue leg); other actions legitimately submit a
// subset of fields or none.
MissingRequired(fields FlowResolvedFields, values map[string]any) FlowFieldValidationErrors
}
FlowFieldResolver maps property names referenced by a flow step to fully-resolved FlowField payloads, surfaces the implicit transition outcomes the schema implies (the designated `x-identifier` property implies a `user_not_found` outcome), and validates submitted values against the schema-derived rules.
The contract is shaped to the user meta-schema at api/openapi/endpoints/schemas/user-schema.yaml.
type FlowFieldType ¶
type FlowFieldType string
FlowFieldType names the input kind the client should render. Mirrors the `type` enum in the OpenAPI flow-field component.
const ( // FlowFieldTypeUnknown is a reserved field type that is only used in case of errors FlowFieldTypeUnknown FlowFieldType = "unknown" FlowFieldTypeText FlowFieldType = "text" FlowFieldTypeEmail FlowFieldType = "email" FlowFieldTypePassword FlowFieldType = "password" FlowFieldTypeTel FlowFieldType = "tel" FlowFieldTypeNumber FlowFieldType = "number" FlowFieldTypeURL FlowFieldType = "url" FlowFieldTypeDate FlowFieldType = "date" FlowFieldTypeHidden FlowFieldType = "hidden" FlowFieldTypeCheckbox FlowFieldType = "checkbox" FlowFieldTypeSelect FlowFieldType = "select" )
type FlowFieldValidation ¶
type FlowFieldValidation struct {
Format string
MinLength int
MaxLength int
Enum []string
// Const, when non-nil, pins the property to a fixed value (JSON
// Schema `const`) of any type — e.g. a must-accept checkbox uses
// `const: true`. A differing submission is reported as
// [FlowFieldValidationRuleFormat].
Const any
}
FlowFieldValidation carries the validation rules the resolver surfaces to the client and enforces on submit. Each field maps to a user meta-schema keyword on [user-property.yaml]:
- Format ↔ `format` (enum: email, date-time, uuid, uri)
- MinLength ↔ `minLength`
- MaxLength ↔ `maxLength`
- Enum ↔ `enum` (closed set of allowed string values)
- Const ↔ `const` (property pinned to a fixed value)
Zero values mean "no rule". JSON Schema's `pattern` keyword is not part of the user meta-schema and is intentionally not surfaced.
type FlowFieldValidationError ¶
type FlowFieldValidationError struct {
Field string
Rule FlowFieldValidationRule
}
FlowFieldValidationError is a single rule violation reported by FlowFieldResolver.Validate.
func (FlowFieldValidationError) Error ¶
func (e FlowFieldValidationError) Error() string
func (FlowFieldValidationError) TextKey ¶
func (e FlowFieldValidationError) TextKey() string
TextKey returns the client-facing localisation key for the violation: `error.<field>_<rule>`, with the format rule aliased to `_invalid` — the text catalog's existing spelling (`error.email_invalid`). Field names are used verbatim, credential shape included (`error.x-auth-methods#password_required`): tenant schemas keep field naming open, so clients resolve unknown keys through generic `error.field_<rule>` fallbacks instead of a closed catalog — see `localiseFlowErrorKeys` in packages/components/src/orchestrator/liquid.ts.
type FlowFieldValidationErrors ¶
type FlowFieldValidationErrors []FlowFieldValidationError
FlowFieldValidationErrors collects rule violations. Returned as `error` by FlowFieldResolver.Validate.
func (FlowFieldValidationErrors) Error ¶
func (e FlowFieldValidationErrors) Error() string
func (FlowFieldValidationErrors) StepError ¶
func (e FlowFieldValidationErrors) StepError() string
StepError renders the violations for the wire `step.error` field: one FlowFieldValidationError.TextKey per violation, joined with "; ". Clients split on the joiner and localise each key. Error() stays the Go-side diagnostic ("flow field email: required") for logs and wrapped errors.
type FlowFieldValidationRule ¶
type FlowFieldValidationRule string
FlowFieldValidationRule names a schema-derived validation rule the resolver enforces. Each rule doubles as the key suffix of the wire dialect (see FlowFieldValidationError.TextKey), so a new rule also needs a generic `error.field_<rule>` catalog entry and a suffix mapping in the client's `localiseFlowErrorKeys` (packages/components/src/orchestrator/liquid.ts).
const ( FlowFieldValidationRuleRequired FlowFieldValidationRule = "required" FlowFieldValidationRuleFormat FlowFieldValidationRule = "format" FlowFieldValidationRuleMinLength FlowFieldValidationRule = "min_length" FlowFieldValidationRuleMaxLength FlowFieldValidationRule = "max_length" FlowFieldValidationRuleUnknown FlowFieldValidationRule = "unknown_field" )
type FlowGateKind ¶
type FlowGateKind uint8
const ( // FlowGateKindCaptcha challenges the user with a bot-detection // provider (altcha, turnstile, hcaptcha, etc). FlowGateKindCaptcha FlowGateKind = iota )
func FlowGateKindString ¶
func FlowGateKindString(s string) (FlowGateKind, error)
FlowGateKindString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowGateKindValues ¶
func FlowGateKindValues() []FlowGateKind
FlowGateKindValues returns all values of the enum
func (FlowGateKind) IsAFlowGateKind ¶
func (i FlowGateKind) IsAFlowGateKind() bool
IsAFlowGateKind returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowGateKind) Scan ¶
func (i *FlowGateKind) Scan(value interface{}) error
func (FlowGateKind) String ¶
func (i FlowGateKind) String() string
type FlowHandoffInput ¶
type FlowHandoffOutput ¶
type FlowIssuePasskeyChallengeInput ¶
type FlowIssuePasskeyChallengeInput struct {
ProjectID string
AttemptID string
RPID string
RPOrigins []string
UserVerification string
}
FlowIssuePasskeyChallengeInput carries the WebAuthn relying-party parameters the engine derives from the request. RPOrigins are the allowed origins; UserVerification is the requirement (empty defaults to the library default). RP params are needed only at issue time — verification re-reads them from the persisted challenge.
type FlowIssuePasskeyRegistrationChallengeInput ¶
type FlowIssuePasskeyRegistrationChallengeInput struct {
ProjectID string
AttemptID string
UserID string
Username string
DisplayName string
RPID string
RPOrigins []string
}
FlowIssuePasskeyRegistrationChallengeInput carries the relying-party parameters and the user context needed to begin a registration ceremony. UserID is the stable WebAuthn user handle (empty on a fresh sign-up: the attempt service mints a provisional one); Username and DisplayName are browser-visible labels when the flow has a collected identifier.
type FlowOnSuccess ¶
type FlowOnSuccess uint8
FlowOnSuccess names the server-side mutation that runs after a step's fields validate, before its transition fires. Nil on FlowDefinitionStep.OnSuccess means no side effect.
const (
FlowOnSuccessCreateUser FlowOnSuccess = iota
)
func FlowOnSuccessString ¶
func FlowOnSuccessString(s string) (FlowOnSuccess, error)
FlowOnSuccessString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowOnSuccessValues ¶
func FlowOnSuccessValues() []FlowOnSuccess
FlowOnSuccessValues returns all values of the enum
func (FlowOnSuccess) IsAFlowOnSuccess ¶
func (i FlowOnSuccess) IsAFlowOnSuccess() bool
IsAFlowOnSuccess returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowOnSuccess) Scan ¶
func (i *FlowOnSuccess) Scan(value interface{}) error
func (FlowOnSuccess) String ¶
func (i FlowOnSuccess) String() string
type FlowOnSuccessHandler ¶
type FlowOnSuccessHandler interface {
Handle(ctx context.Context, in FlowOnSuccessInput) (FlowOnSuccessResult, error)
}
FlowOnSuccessHandler is the contract every on_success mutation satisfies. The state machine calls Handle after a step's fields validate and before its transition fires.
Each FlowOnSuccess value maps to one handler. Implementations live in their own file (e.g. flow_on_success_create_user.go).
type FlowOnSuccessInput ¶
type FlowOnSuccessInput struct {
ProjectID string
UserSchemaURL string
Fields map[string]any
Resolved FlowResolvedFields
State *FlowState
ResolvedFlow *FlowDefinition
}
FlowOnSuccessInput is the per-call context the state machine threads into a handler.
type FlowOnSuccessResult ¶
type FlowOnSuccessResult struct {
StepError *string
// UserID is set when a handler creates a new user. The state machine
// only records it in flow state — a handler returning a UserID MUST
// have persisted the user's verified factors on the auth attempt
// inside its own transaction (see FlowCreateUserWithPasswordHandler's
// recordAttemptFactorsAction), or the exchanged session will be bound
// to a user with no factors.
UserID string
// Irreversible flags mutations the user cannot reverse (e.g. created a user).
Irreversible bool
}
FlowOnSuccessResult is what a handler returns. StepError keeps the user on the current step.
type FlowPasskeyChallengeOutput ¶
FlowPasskeyChallengeOutput is the issued challenge. Options is the PublicKeyCredentialRequestOptions JSON the client hands to the authenticator; ChallengeID binds the later assertion to this issue.
type FlowPasskeyRP ¶
FlowPasskeyRP is the relying-party context for issuing a passkey challenge, derived from the HTTP request at the API edge.
type FlowPasskeyRegistrationChallengeOutput ¶
type FlowPasskeyRegistrationChallengeOutput struct {
ChallengeID string
UserID string
Options []byte
}
FlowPasskeyRegistrationChallengeOutput is the issued challenge. UserID is the WebAuthn user handle (minted by the attempt service when the issue input had none).
type FlowPendingChallenge ¶
type FlowPendingChallenge struct {
// ID is the challenge identifier returned by the auth-attempt
// service at issue time. The client echoes it back in
// ChallengeResponse.
ID string
// Method names the ceremony kind (e.g. "passkey"). The state
// machine uses it to route verification to the right service.
Method string
// Options is the client-facing ceremony options JSON (for passkey,
// the PublicKeyCredentialRequestOptions). Surfaced on the rendered
// step's challenge so the browser can run the ceremony; persisted in
// the cookie so a re-render re-emits it.
Options []byte
// IssuedAt is when the challenge was minted. The auth-attempt
// service enforces its own freshness window; this field is kept for
// diagnostics and for the state machine to short-circuit obviously
// stale challenges before calling Verify.
IssuedAt time.Time
}
FlowPendingChallenge records the server-issued challenge the next submit must satisfy. The binding (id + method) is threaded through the cookie so the verify step can locate it; Options carries the client-facing ceremony options so a GET /flow re-render can re-emit them without re-issuing.
type FlowProgress ¶
type FlowProgress struct {
// DefinitionID is the flow definition currently being executed. On
// pivot it changes to the child definition; on pop it is restored
// from the parent entry on PivotStack.
DefinitionID string
// Purpose is the kind of flow (login, signup, recovery, …). The
// handler uses it to surface a coarse classification without parsing
// the definition.
Purpose FlowDefinitionPurpose
// CurrentPurpose is the dynamic dispatch mode. Flips on identifier
// outcomes; Purpose stays pinned for telemetry / ACR.
CurrentPurpose FlowDefinitionPurpose
// CurrentStep is the name of the step the user is currently on
// within DefinitionID. The next submit is interpreted against this
// step.
CurrentStep string
// History is the append-only audit trail of visited steps.
History []string
// BackStack maintains the history of visited steps, but gets
// cleared after an irreversible action.
// The engine also uses it to decide when an action.back should
// be injected into the response.
BackStack []FlowBackEntry
// CollectedData accumulates submitted field values for this
// progress entry, keyed by schema property name. A child flow's
// CollectedData is discarded when its progress is popped.
CollectedData CollectedFlowData
}
FlowProgress captures the user's position within a single flow definition: which definition is running, the current step, the history of steps visited so far, and the data submitted along the way. It is embedded in FlowState for the active flow and pushed onto FlowState.PivotStack for paused parents.
type FlowResolvedFields ¶
type FlowResolvedFields struct {
// Fields holds the resolved per-field metadata in the same order as
// the property names passed to Resolve.
Fields []FlowField
// ImplicitOutcomes lists the reserved transition outcomes each
// field contributes, keyed by field name. The state machine uses it
// to validate flow definitions and route schema-derived transitions.
ImplicitOutcomes map[string][]string
}
FlowResolvedFields is the output of FlowFieldResolver.Resolve.
type FlowSSOProvider ¶
FlowSSOProvider is an identity provider option offered on a step.
type FlowSSOProviderRef ¶
type FlowSSOProviderRef struct {
ID string
}
type FlowSessionRef ¶
FlowSessionRef pins the session row this flow runs on top of. A version mismatch surfaces as ErrFlowSessionConflict.
type FlowStartInput ¶
type FlowStartInput struct {
Definition *FlowDefinition
Purpose FlowDefinitionPurpose
Session FlowSessionRef
AuthRequest *FlowAuthRequestRef
RedirectURI *string
UserSchemaURL string
}
FlowStartInput carries everything the state machine needs to bootstrap a new flow.
type FlowState ¶
type FlowState struct {
// ID is the flow handle minted at Start. The handler verifies it
// matches the path (`/flow/{id}/...`) to reject path/cookie mismatches.
ID string
// ProjectID scopes the flow to a single tenant.
ProjectID string
// UserSchemaURL is the user schema this flow validates against,
// captured at Start time so a mid-flow default change doesn't
// reshape in-flight data.
UserSchemaURL string
// FlowProgress is the user's current progress: which definition is
// running, which step is being shown, and what's been collected so
// far. Promoted to the top level so callers read e.g.
// state.CurrentStep directly.
FlowProgress
// IssuedAt is when this state was last sealed into the cookie. The
// handler refuses to open a state older than the configured max-age,
// bounding how long a stolen cookie remains replayable. Refreshed on
// every advance.
IssuedAt time.Time
// SessionID is the stable identifier of the user session backing this
// flow. It survives pivots — child and parent flows share it.
SessionID string
// SessionVersion pins the session row version observed when this flow
// was last advanced. The state machine refuses to process a submit
// against a stale version (e.g. another tab logged out the session).
SessionVersion int64
// StepVersion pins the step revision observed when CurrentStep was
// emitted. If the definition is republished mid-flow, the state
// machine surfaces an integrity error rather than silently applying
// the new step shape to in-flight data.
StepVersion int64
// PivotStack records parent-flow resume points. When a flow pivots
// into another flow, the parent's FlowProgress is pushed; on the
// child's completion the state machine pops and re-renders the
// parent's next step. Empty for non-stacked flows.
PivotStack []FlowProgress
// AuthRequestID, when set, identifies the OIDC authorization request
// this flow is fulfilling. Nil for flows started outside an OIDC
// context (e.g. standalone registration or recovery).
AuthRequestID *string
// RedirectURI is the terminal redirect destination for `complete:
// redirect` flows (typically the OIDC callback). Nil for `complete:
// show` flows that end on a success screen.
RedirectURI *string
// RequestedACR is the Authentication Context Class Reference asked
// for by the relying party. The implicit policy evaluator compares
// it against the session's assurance levels to decide whether the
// flow can complete.
RequestedACR *string
// PendingChallenge binds an outstanding ceremony (passkey today,
// other methods later) to the current step. Set by the state
// machine when entering a step that declares a challenge; cleared
// once the matching ChallengeResponse verifies. Nil when no
// ceremony is in flight.
PendingChallenge *FlowPendingChallenge
// AuthAttemptID names the auth_attempts row this flow is collecting
// factors against. Created at Start; completed intrinsically by the
// last successful Submit* call; handed off by the API handler at
// the OIDC redirect boundary.
AuthAttemptID string
}
FlowState is the runtime state of a single in-flight flow. The handler JSON-encodes it as the payload of the sealed `_zflow` cookie on every response and decodes it back on every incoming request.
FlowState embeds FlowProgress: the active progress (definition, step, history, collected data) sits at the root, and any paused parents live on PivotStack. The remaining fields are session/OIDC context that only makes sense at the top level.
func (*FlowState) ClearBackStack ¶
func (s *FlowState) ClearBackStack()
ClearBackStack drops any accumulated back-navigation entries. Called past irreversible mutations and at flow termination.
func (*FlowState) ClearPendingChallenge ¶
func (s *FlowState) ClearPendingChallenge()
ClearPendingChallenge drops any outstanding ceremony binding on the state. Called when the challenge is superseded (verify succeeded, or the user navigated away).
func (*FlowState) PeekBackStack ¶
func (s *FlowState) PeekBackStack() (FlowBackEntry, bool)
PeekBackStack returns the top BackStack entry without mutating the state. Returns false when the stack is empty.
func (*FlowState) PopBackStack ¶
func (s *FlowState) PopBackStack() (FlowBackEntry, bool)
PopBackStack removes and returns the top BackStack entry. Returns false when the stack is empty, leaving the state untouched.
type FlowStateMachine ¶
type FlowStateMachine interface {
Start(ctx context.Context, in FlowStartInput) (FlowStepResult, error)
Process(ctx context.Context, def *FlowDefinition, state *FlowState, in FlowSubmitInput) (FlowStepResult, error)
// Render re-emits the current step without advancing. Backs GET /flow/{id}.
Render(ctx context.Context, def *FlowDefinition, state *FlowState) (FlowStepResult, error)
}
FlowStateMachine drives a flow definition forward in response to client submissions. The handler owns cookie I/O; the state machine never touches cookies.
MVP scope: single linear flow per `flow_id`, no pivot stack, no challenges, no gates. `Pop` on FlowStepResult stays reserved for the deferred pivot work.
type FlowStateMachineRuntime ¶
type FlowStateMachineRuntime struct {
// contains filtered or unexported fields
}
FlowStateMachineRuntime is the production FlowStateMachine.
func NewFlowStateMachine ¶
func NewFlowStateMachine( schemas SchemaResolver, schemaStore JSONSchemaStore, fields FlowFieldResolver, createUser FlowOnSuccessHandler, authAttempts FlowAuthAttemptService, now func() time.Time, ) *FlowStateMachineRuntime
NewFlowStateMachine wires the runtime. The now hook is injectable so tests can produce deterministic FlowState.IssuedAt values.
func (*FlowStateMachineRuntime) Process ¶
func (r *FlowStateMachineRuntime) Process(ctx context.Context, def *FlowDefinition, state *FlowState, in FlowSubmitInput) (FlowStepResult, error)
Process advances the flow one step by dispatching the submission to the handler for its action kind.
func (*FlowStateMachineRuntime) Render ¶
func (r *FlowStateMachineRuntime) Render(ctx context.Context, def *FlowDefinition, state *FlowState) (FlowStepResult, error)
Render re-emits the current step without advancing. Refreshes IssuedAt so the cookie max-age window slides while the user is on the step.
func (*FlowStateMachineRuntime) Start ¶
func (r *FlowStateMachineRuntime) Start(ctx context.Context, in FlowStartInput) (FlowStepResult, error)
type FlowStep ¶
type FlowStep struct {
Name string
Texts FlowStepTexts
Error *string
Complete *FlowStepComplete
RedirectURL *string
Fields []FlowField
Actions []FlowAction
SSOProviders []FlowSSOProvider
// Challenge is a pending authentication ceremony the client must
// satisfy before re-submitting (e.g. a passkey assertion). Nil unless
// the engine just issued one.
Challenge *FlowStepChallenge
}
FlowStep is the capability payload the API surfaces to the client. It mirrors the OpenAPI `flow-step` component in domain terms.
type FlowStepAction ¶
type FlowStepAction struct {
Name string
// Kind classifies how the engine handles this action. See
// [FlowActionKind] for the available kinds.
Kind FlowActionKind
TextKey string
Primary bool
}
FlowStepAction is a user-selectable action declared on a step.
type FlowStepChallenge ¶
type FlowStepChallenge struct {
Method string
ChallengeID string
// Options is the protocol-specific options JSON the client passes to
// the ceremony API (for passkey, PublicKeyCredentialRequestOptions).
Options []byte
}
FlowStepChallenge mirrors the OpenAPI `flow-step.challenge`: a pending ceremony the client runs (passkey today) before re-submitting the proof.
type FlowStepComplete ¶
type FlowStepComplete uint8
FlowStepComplete classifies a terminal step. The frontend uses this to decide between navigating to a protocol redirect URI or rendering a success/info screen. Set on FlowDefinitionStep.Complete to mark the step as terminal; nil for regular interactive steps.
const ( // FlowStepCompleteRedirect navigates the client to the protocol // redirect URI (typically the OIDC/SAML callback). FlowStepCompleteRedirect FlowStepComplete = iota // FlowStepCompleteShow renders the step as a success or info screen. FlowStepCompleteShow )
func FlowStepCompleteString ¶
func FlowStepCompleteString(s string) (FlowStepComplete, error)
FlowStepCompleteString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func FlowStepCompleteValues ¶
func FlowStepCompleteValues() []FlowStepComplete
FlowStepCompleteValues returns all values of the enum
func (FlowStepComplete) IsAFlowStepComplete ¶
func (i FlowStepComplete) IsAFlowStepComplete() bool
IsAFlowStepComplete returns "true" if the value is listed in the enum definition. "false" otherwise
func (*FlowStepComplete) Scan ¶
func (i *FlowStepComplete) Scan(value interface{}) error
func (FlowStepComplete) String ¶
func (i FlowStepComplete) String() string
type FlowStepGate ¶
type FlowStepGate struct {
Kind FlowGateKind
Provider string
// Config is provider-specific challenge configuration, opaque to the engine.
Config map[string]any
}
FlowStepGate is a security challenge attached to a step.
type FlowStepResult ¶
type FlowStepResult struct {
State *FlowState
Step *FlowStep
Pop bool
HandoffToken string
HandoffTokenExpiresAt time.Time
}
FlowStepResult is what the state machine returns from [Start] and [Process]. Pop is reserved for the deferred pivot stack. HandoffToken + HandoffTokenExpiresAt are populated only on the terminal step.
type FlowStepTexts ¶
FlowStepTexts holds the step-level localization keys (`<step>.title`, `<step>.description`) the template resolves via the `| t` filter.
type FlowStepTransition ¶
type FlowStepTransition struct {
Action *FlowDefinitionTransitionAction
// Target is either a step in the current flow OR a new flow.
// When Action == nil, Target refers to a step in the current flow
// When Action != nil, Target refers to another flow.
Target string
// Purpose, when non-nil, re-purposes the flow locally: taking this
// transition sets [FlowState.CurrentPurpose] to this purpose while the
// pinned [FlowState.Purpose] stays untouched. The purpose must be one
// the definition serves and Target must be that purpose's entry step
// (validated). Mutually exclusive with Action — a transition either
// pivots to another flow or re-purposes within this one, never both.
Purpose *FlowDefinitionPurpose
}
FlowStepTransition maps an action name to either a target step (regular) or a pivot purpose.
func (FlowStepTransition) IsCurrentFlow ¶
func (fst FlowStepTransition) IsCurrentFlow() bool
type FlowSubmitIdentifierInput ¶
type FlowSubmitIdentifierInput struct {
ProjectID string
AttemptID string
AttributeName string
Value string
}
FlowSubmitIdentifierInput names the submitted identifier field (AttributeName, e.g. "email") and the user-entered value the auth-attempt service resolves to a user.
type FlowSubmitInput ¶
type FlowSubmitInput struct {
Action string
Fields map[string]any
GateProofs map[string]string
SSOProvider *FlowSSOProviderRef
// ChallengeResponse carries the client's answer to a pending ceremony
// (e.g. a passkey assertion). Present on the verify leg of a two-phase
// challenge; nil otherwise.
ChallengeResponse *FlowChallengeResponse
// PasskeyRP carries the WebAuthn relying-party parameters the API
// derived from the request. Required on the passkey issue leg.
PasskeyRP *FlowPasskeyRP
}
FlowSubmitInput carries a single client submission.
GateProofs and SSOProvider are reserved; the state machine returns ErrFlowUnsupported for any flow that exercises them today.
type FlowSubmitPasskeyInput ¶
type FlowSubmitPasskeyInput struct {
ProjectID string
AttemptID string
ChallengeID string
Assertion []byte
}
FlowSubmitPasskeyInput carries the signed assertion (Proof) plus the ChallengeID returned by FlowAuthAttemptService.IssuePasskeyChallenge.
type FlowSubmitPasskeyRegistrationInput ¶
type FlowSubmitPasskeyRegistrationInput struct {
ProjectID string
AttemptID string
UserID string
ChallengeID string
Attestation []byte
UserSchemaURL string
UserAttributes map[string]any
}
FlowSubmitPasskeyRegistrationInput carries the attestation plus the ChallengeID returned by IssuePasskeyRegistrationChallenge. UserSchemaURL and UserAttributes feed the user creation that runs inside the verify transaction when the ceremony is provisional.
type FlowSubmitPasswordInput ¶
type FlowdefAudiencePayload ¶
type FlowdefAudiencePayload struct {
AppIDs []string `json:"app_ids,omitempty"`
TeamIDs []string `json:"team_ids,omitempty"`
}
FlowdefAudiencePayload is the allowlisted audience snapshot for flowdef events.
type FlowdefPayload ¶
type FlowdefPayload struct {
Name string `json:"name,omitempty"`
Status string `json:"status,omitempty"`
UserSchema string `json:"user_schema,omitempty"`
Purposes map[string]string `json:"purposes,omitempty"`
Audience *FlowdefAudiencePayload `json:"audience,omitempty"`
}
FlowdefPayload is shared by flowdef.created (snapshot) and flowdef.updated (delta). Steps are intentionally omitted (large graph).
func FlowdefPayloadDelta ¶
func FlowdefPayloadDelta(before, after *FlowDefinition) FlowdefPayload
FlowdefPayloadDelta is the allowlisted update delta (new values only).
func FlowdefPayloadSnapshot ¶
func FlowdefPayloadSnapshot(fd *FlowDefinition) FlowdefPayload
FlowdefPayloadSnapshot is the allowlisted create snapshot for flowdef events.
type HandoffToken ¶
type HandoffToken struct {
TokenHash []byte
// contains filtered or unexported fields
}
func (*HandoffToken) Plain ¶
func (t *HandoffToken) Plain() string
type JSONSchema ¶
type JSONSchema struct {
ProjectID string
URL string
ObjectType *string
Kind JSONSchemaKind
CreatedAt time.Time
Schema []byte
}
func NewJSONSchema ¶
func NewJSONSchema(projectID string, schemabs []byte) (_ *JSONSchema, err error)
type JSONSchemaField ¶
type JSONSchemaField uint8
JSONSchemaField enumerates the fields of JSONSchema which can be used for filtering and ordering in list operations.
const ( JSONSchemaFieldUnspecified JSONSchemaField = iota JSONSchemaFieldProjectID JSONSchemaFieldURL JSONSchemaFieldObjectType JSONSchemaFieldCreatedAt JSONSchemaFieldKind )
type JSONSchemaKind ¶
type JSONSchemaKind uint8
JSONSchemaKind is the `kind` a stored schema document declares. It is the discriminator the meta-schemas are keyed on, not the `kind` of a create request — `schema-url` describes how a schema was supplied, and the document fetched from that URL declares its own kind like any other.
const ( // JSONSchemaKindUnknown is recorded when a schema is persisted without its // document being parsed, so no declared kind was ever read. Filtering by // kind never matches it. JSONSchemaKindUnknown JSONSchemaKind = iota // unknown JSONSchemaKindUserSchema // user-schema )
func JSONSchemaKindString ¶
func JSONSchemaKindString(s string) (JSONSchemaKind, error)
JSONSchemaKindString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func JSONSchemaKindValues ¶
func JSONSchemaKindValues() []JSONSchemaKind
JSONSchemaKindValues returns all values of the enum
func (JSONSchemaKind) IsAJSONSchemaKind ¶
func (i JSONSchemaKind) IsAJSONSchemaKind() bool
IsAJSONSchemaKind returns "true" if the value is listed in the enum definition. "false" otherwise
func (*JSONSchemaKind) Scan ¶
func (i *JSONSchemaKind) Scan(value interface{}) error
func (JSONSchemaKind) String ¶
func (i JSONSchemaKind) String() string
type JSONSchemaResolver ¶
type JSONSchemaResolver struct {
// contains filtered or unexported fields
}
JSONSchemaResolver retrieves JSON schemas by their URL recursively, starting from the given schema URL and following all references in the schema. It caches resolved schemas in memory and uses a JSONSchemaStore to load and persist them for future use.
func NewJSONSchemaResolver ¶
func NewJSONSchemaResolver( cache *lru.TwoQueueCache[string, *jsonschema.Schema], maxResolveDepth int, maxSize int, httpClient *http.Client, builtinPublicBase *url.URL, ) *JSONSchemaResolver
NewJSONSchemaResolver wires a resolver with an LRU cache, resolve limits, an optional HTTP client for ingestion, and an optional builtinPublicBase URL. When builtinPublicBase is non-nil, schema URLs under that prefix are loaded from embedded templates instead of the database; they are not persisted via JSONSchemaStore.CreateJSONSchema. Persistence is supplied per JSONSchemaResolver.Resolve call via JSONSchemaStore.
func (*JSONSchemaResolver) Resolve ¶
func (r *JSONSchemaResolver) Resolve( ctx context.Context, store JSONSchemaStore, projectID string, schemaURL string, rootSchema []byte, ) (*jsonschema.Schema, error)
Resolve retrieves a JSON schema by its URL recursively, starting from the given schema URL and following all references in the schema. It first tries to find the fully resolved schema in the cache. If not found in the cache, it looks for the schema and all its references by URL from the store. When the resolver has an HTTP client, it can fetch a missing schema from its URL and persist it.
type JSONSchemaStore ¶
type JSONSchemaStore interface {
GetJSONSchemaByID(ctx context.Context, projectID, schemaID string) (*JSONSchema, error)
CreateJSONSchema(ctx context.Context, schema *JSONSchema) error
}
JSONSchemaStore is the persistence port for JSON schemas used by JSONSchemaResolver and service callers that only need get/create. Because schema validation happens on data writes in domain logic, schemas are immutable. They can only be created and deleted (if no data references them). Schemas can use versioned URLs to support multiple versions of the same schema.
Method names match the v2 statement surface so pool/tx statements satisfy this interface without an adapter.
type JWEHeader ¶
type JWEHeader struct {
KeyID string `json:"kid"`
EncryptionAlgorithm jose.ContentEncryption `json:"enc"`
}
func DecodeJWEHeader ¶
type KnownSchemaKind ¶
type KnownSchemaKind string
const ( SchemaKindUser KnownSchemaKind = "user" SchemaKindFlowDefinition KnownSchemaKind = "flow-definition" )
type MasterKey ¶
type MasterKey struct {
ID string
ShouldBeUsedForEncryption bool
// contains filtered or unexported fields
}
func NewMasterKey ¶
func NewMasterKey( id string, key rsa.PrivateKey, shouldBeUsedForEncryption bool, ) MasterKey
type MasterKeys ¶
func NewMasterKeys ¶
func NewMasterKeys(keys []MasterKey) (*MasterKeys, error)
func (MasterKeys) GetByKeyID ¶
func (ks MasterKeys) GetByKeyID(id string) *MasterKey
type MembershipStatus ¶
type MembershipStatus string
MembershipStatus is the roster participation state for a user on a team.
const ( MembershipStatusPending MembershipStatus = "pending" MembershipStatusActive MembershipStatus = "active" MembershipStatusInactive MembershipStatus = "inactive" MembershipStatusRemoved MembershipStatus = "removed" )
func (MembershipStatus) IsAuthzActive ¶
func (s MembershipStatus) IsAuthzActive() bool
IsAuthzActive reports whether the roster status should project an authz membership edge.
func (MembershipStatus) String ¶
func (s MembershipStatus) String() string
type PasskeyChallenge ¶
type PasskeyChallenge struct {
Challenge string
AllowedCredentialIDs [][]byte
// UserVerification mirrors the WebAuthn UserVerificationRequirement enum:
// "required", "preferred" or "discouraged" (or empty for unset).
UserVerification string
RPID string
// TODO: RPOrigins must be a subset of the project's allowed origins
// once a unified project-level origin config (prod + preview) exists.
RPOrigins []url.URL
UserID []byte `json:"user_id,omitempty" msg:"u,omitempty"`
Expires time.Time `json:"expires" msg:"exp"`
Extensions map[string]any `json:"extensions,omitempty" msg:"exts,omitempty"`
CredParams []PasskeyCredentialParameter `json:"credParams,omitempty" msg:"params,omitempty"`
// Mediation mirrors the WebAuthn CredentialMediationRequirement enum.
Mediation string `json:"mediation,omitempty" msg:"cmr,omitempty"`
}
func CreatePasskeyChallenge ¶
func CreatePasskeyChallenge(id string, keys []*UserPasskey, verification string, rpID string, origins []url.URL) (*PasskeyChallenge, error)
type PasskeyCredentialParameter ¶
PasskeyCredentialParameter mirrors a WebAuthn PublicKeyCredentialParameters entry as a plain-Go type so the persisted/transmitted domain model stays independent of go-webauthn. JSON shape matches the WebAuthn spec.
type PasskeyRegistrationChallenge ¶
type PasskeyRegistrationChallenge struct {
Challenge string
RPID string
RPOrigins []url.URL
UserID string
Username string
DisplayName string
ExcludeIDs [][]byte // existing credential IDs excluded from this registration
Expires time.Time
CredParams []protocol.CredentialParameter
Extensions protocol.AuthenticationExtensions
}
PasskeyRegistrationChallenge holds server-side state for a BeginRegistration call. It must be persisted between the issue and verify legs of the registration ceremony.
func CreatePasskeyRegistrationChallenge ¶
func CreatePasskeyRegistrationChallenge(userID, username, displayName string, existing []*UserPasskey, rpID string, origins []url.URL) (*PasskeyRegistrationChallenge, error)
CreatePasskeyRegistrationChallenge calls webauthn.BeginRegistration and maps the returned SessionData to a PasskeyRegistrationChallenge.
type PasskeyVerification ¶
type PasskeyVerification struct {
CredentialID []byte
SignCount uint32
UserVerified bool
BackupEligible bool
BackupState bool
UserID string
}
func VerifyPasskeyChallenge ¶
func VerifyPasskeyChallenge(challenge *PasskeyChallenge, response []byte, userID string, passkeys []*UserPasskey, passkey func(userID string) ([]*UserPasskey, error)) (*PasskeyVerification, error)
type PersonalTeamNotActiveDetails ¶
type PersonalTeamNotActiveDetails struct {
MembershipStatus string `json:"membership_status"`
}
PersonalTeamNotActiveDetails names the membership state that blocked the personal-team resolution.
type PivotingTarget ¶
func ValidateFlowDefinition ¶
func ValidateFlowDefinition(userSchema *jsonschema.Schema, flowDefinition FlowDefinition) ([]PivotingTarget, error)
ValidateFlowDefinition is ported (rules and message strings) to packages/config/src/validate.ts for CLI plan-time validation — keep rule changes in sync; a drift-audit test over this file guards the function names and shared literals. The sync burden is interim: the validate-only bundle endpoint (zitadel/nextgen#449) supersedes the port, and the TS side is deleted when it lands.
type Project ¶
type Project struct {
ID string
Name string
CreatedAt time.Time
UpdatedAt time.Time
// PreviewOrigins are the allowed origins for the preview secret.
// Callers must set this field before the project is persisted.
PreviewOrigins []string
}
Project is a minimal representation of the object defined [here](https://github.com/zitadel/nextgen/blob/main/docs/design/api/resource-map.md#projects) It is hardly ever modified but read a lot therefore it should be stored in global tables.
func (*Project) GenerateNewKeySet ¶
func (p *Project) GenerateNewKeySet(masterKey crypto.Crypter, mintID func(ResourcePrefix) (string, error)) (*ProjectKeySet, error)
GenerateNewKeySet creates the project's key encryption key, wrapped by the deployment's master key, and the purpose-scoped keys wrapped by that KEK. mintID must mint the KEK ID before wrapping — that ID is the JWE "kid" for purpose keys. Other key IDs stay empty for Create* Ensure.
func (*Project) PreviewToken ¶
type ProjectCreatedPayload ¶
type ProjectCreatedPayload = ProjectPayload
ProjectCreatedPayload is an alias kept for call-site clarity.
type ProjectDeletedPayload ¶
type ProjectDeletedPayload struct{}
type ProjectField ¶
type ProjectField uint8
ProjectField enumerates the fields of Project which can be used for ordering in list operations.
const ( ProjectFieldUnspecified ProjectField = iota ProjectFieldID ProjectFieldName ProjectFieldCreatedAt ProjectFieldUpdatedAt ProjectFieldPreviewOrigins )
type ProjectKeySet ¶
type ProjectKeySet struct {
KeyEncryptionKey *EncryptionKey
TokenEncryptionKey *EncryptionKey
SecretEncryptionKey *EncryptionKey
CookieEncryptionKey *EncryptionKey
TokenSigningKey *SigningKey
}
func (*ProjectKeySet) Activate ¶
func (s *ProjectKeySet) Activate(oldKeys *ProjectKeySet)
type ProjectPayload ¶
type ProjectPayload struct {
Name string `json:"name,omitempty"`
PreviewOrigins []string `json:"preview_origins,omitempty"`
}
ProjectPayload is shared by project.created (full snapshot) and project.updated (delta: only changed fields set).
type ProjectUpdatedPayload ¶
type ProjectUpdatedPayload = ProjectPayload
ProjectUpdatedPayload is an alias kept for call-site clarity.
type RequestAPIPayload ¶
type RequestInvalidFieldDetails ¶
type RequestInvalidFieldDetails struct {
Field string `json:"field"`
}
RequestInvalidFieldDetails names a request field that failed validation. Producers must attach only the field path — never parser text or payload fragments (ADR 030 Decision 4 + 6).
type ResourceKind ¶
type ResourceKind string
ResourceKind is the resource_scope_index.resource_kind discriminator.
const ( ResourceKindProject ResourceKind = "project" ResourceKindTeam ResourceKind = "team" ResourceKindUser ResourceKind = "user" ResourceKindSchema ResourceKind = "schema" ResourceKindBranding ResourceKind = "branding" ResourceKindFlowDefinition ResourceKind = "flow_definition" ResourceKindSession ResourceKind = "session" ResourceKindEnvironment ResourceKind = "environment" )
func (ResourceKind) String ¶
func (k ResourceKind) String() string
type ResourcePrefix ¶
type ResourcePrefix string
ResourcePrefix is the ID namespace for each domain resource ("user_xxxx"). Error codes often reuse that token for the resource's public API ("user.not_found") but may use a parent or surface prefix instead. Permission scopes follow the catalog name, not necessarily the ID abbrev.
const ( PrefixAuthAttempt ResourcePrefix = "att" PrefixChallenge ResourcePrefix = "ch" PrefixHandoffToken ResourcePrefix = "handoff" HandoffTokenExpiration = time.Minute )
const ( PrefixClaim ResourcePrefix = "claim" PrefixClaimChallenge ResourcePrefix = "claim_challenge" )
const ( PrefixSession ResourcePrefix = "sess" PrefixUserAgent ResourcePrefix = "ua" SessionAnonymousTTL = 10 * time.Minute )
const (
FlowDefinitionPrefix ResourcePrefix = "flowdef"
)
const PrefixAuthzAssignment ResourcePrefix = "asgn"
PrefixAuthzAssignment is the dialect-minted ID prefix for authz_assignments (asgn_<opaque>).
const PrefixBranding ResourcePrefix = "brnd"
const (
PrefixEncryptionKey ResourcePrefix = "enc_key"
)
const (
PrefixEnvironment ResourcePrefix = "env"
)
const PrefixEvent ResourcePrefix = "evt"
const PrefixEventSink ResourcePrefix = "sink"
const PrefixFlow ResourcePrefix = "flow"
PrefixFlow is the error-code namespace for flow *runtime* (cookie, state machine, submit/get step). Flow *definition* CRUD uses PrefixFlowDefinition.
const PrefixFlowDefinition ResourcePrefix = "flowdef"
const PrefixGrant ResourcePrefix = "grant"
PrefixGrant is the public error-code prefix for the grants HTTP API (grant.not_found). Assignment IDs stay PrefixAuthzAssignment (asgn_<opaque>).
const (
PrefixJSONSchema ResourcePrefix = "sch"
)
const (
PrefixProject ResourcePrefix = "proj"
)
const (
PrefixSigningKey ResourcePrefix = "sig_key"
)
const (
PrefixTeam ResourcePrefix = "team"
)
const (
PrefixUser ResourcePrefix = "user"
)
const PrefixUserPasskey ResourcePrefix = "upk"
const PrefixUserPassword ResourcePrefix = "upw"
const PrefixUserRecoveryCodes ResourcePrefix = "urc"
const PrefixUserTOTP ResourcePrefix = "utotp"
var TokenPrefix ResourcePrefix = "tkn"
func (ResourcePrefix) ErrorCodePrefix ¶
func (p ResourcePrefix) ErrorCodePrefix(code string) string
func (ResourcePrefix) IDPrefix ¶
func (p ResourcePrefix) IDPrefix(id string) string
func (ResourcePrefix) Matches ¶
func (p ResourcePrefix) Matches(id string) bool
Matches reports whether id is well-formed under this prefix: the registered prefix, then "_", then a non-empty body (e.g. "proj_01H..." / "proj_platform").
type ResourceScope ¶
type ResourceScope struct {
ResourceID string
ResourceKind ResourceKind
ProjectID string
TeamID *string
CreatedAt time.Time
UpdatedAt time.Time
}
ResourceScope maps a globally addressable resource id to project/team scope (resource_scope_index). Answers "where does this path.id live?" for middleware and the future resolver — not a permission grant.
func NewProjectResourceScope ¶
func NewProjectResourceScope(projectID string) *ResourceScope
func NewResourceScope ¶
func NewResourceScope(kind ResourceKind, projectID, resourceID string) *ResourceScope
NewResourceScope builds a project-scoped RSI row (no team).
func NewTeamResourceScope ¶
func NewTeamResourceScope(projectID, teamID string) *ResourceScope
func NewUserResourceScope ¶
func NewUserResourceScope(projectID, userID string) *ResourceScope
type SchemaCreatedPayload ¶
type SchemaCreatedPayload struct {
Kind string `json:"kind,omitempty"`
ObjectType string `json:"object_type,omitempty"`
}
SchemaCreatedPayload is the allowlisted snapshot for schema.created. The document itself is omitted — it is customer-authored and unbounded, and the event's entity_id already identifies which schema this was.
func SchemaCreatedPayloadSnapshot ¶
func SchemaCreatedPayloadSnapshot(schema *JSONSchema) SchemaCreatedPayload
SchemaCreatedPayloadSnapshot builds the schema.created payload.
type SchemaFieldResolver ¶
type SchemaFieldResolver struct{}
SchemaFieldResolver is the production FlowFieldResolver. It is a stateless translator from a loaded user schema to FlowField payloads — schema loading is the caller's responsibility (see SchemaResolver).
Translation map (user meta-schema → FlowField):
- `type` + `format` → FlowFieldType
- `required` membership at every level of the field's path → FlowField.Required
- `minLength`, `maxLength`, `format` → FlowFieldValidation
- `x-unique` (non-empty) → FlowField.Unique
- the schema-root `x-identifier` designation → the designated field carries FlowFieldChallengeIdentifier + FlowImplicitOutcomeUserNotFound + FlowImplicitOutcomeUserAlreadyExists
- `x-auth-methods#<method>` field name → credential challenge for that method (e.g. `x-auth-methods#password` → password)
func NewSchemaFieldResolver ¶
func NewSchemaFieldResolver() *SchemaFieldResolver
NewSchemaFieldResolver returns a stateless FlowFieldResolver.
func (*SchemaFieldResolver) MissingRequired ¶
func (r *SchemaFieldResolver) MissingRequired(fields FlowResolvedFields, values map[string]any) FlowFieldValidationErrors
MissingRequired reports a required violation for every declared required field absent from values — the unset controls clients omit (e.g. an unselected select) that SchemaFieldResolver.Validate never sees. Apply on field-collecting actions (submit, passkey-register issue leg); skip it where actions send a subset or none. Returns nil when none are missing.
func (*SchemaFieldResolver) Resolve ¶
func (r *SchemaFieldResolver) Resolve(schema *jsonschema.Schema, stepName string, fieldNames []Field) (FlowResolvedFields, error)
func (*SchemaFieldResolver) Validate ¶
func (r *SchemaFieldResolver) Validate(fields FlowResolvedFields, values map[string]any) error
Validate applies the rules carried by a previously resolved field set to the submitted values. Pure: no I/O, no schema loading.
Per-value checks (in order):
- name not in fields → FlowFieldValidationRuleUnknown
- checkbox field: non-bool value → FlowFieldValidationRuleFormat
- non-string value (non-checkbox) → FlowFieldValidationRuleFormat
- empty string + FlowField.Required → FlowFieldValidationRuleRequired
- value differs from a pinned FlowFieldValidation.Const → FlowFieldValidationRuleFormat
- rules in FlowField.Validation (MinLength, MaxLength, Format)
Validate only visits submitted fields; an omitted required field is not its concern — the submit action pairs this with SchemaFieldResolver.MissingRequired to catch omissions.
Caller is responsible for resolving the field set first (via FlowFieldResolver.Resolve); that is where schema loading and the "unknown property in schema" check happen.
type SchemaResolver ¶
type SchemaResolver interface {
Resolve(ctx context.Context, store JSONSchemaStore, projectID, schemaURL string, rootSchema []byte) (*jsonschema.Schema, error)
}
SchemaResolver loads a compiled JSON schema by URL. It is the loader FlowStateMachineRuntime depends on for runtime schema access; SchemaFieldResolver is the translator that runs on top of the loaded schema.
type SchemaValidator ¶
type SchemaValidator struct {
// contains filtered or unexported fields
}
SchemaValidator validates a tenant schema document against the server-owned meta-schema for its declared kind.
func NewSchemaValidator ¶
func NewSchemaValidator(builtinPublicBase string) (*SchemaValidator, error)
NewSchemaValidator compiles the meta-schemas for the tenant schema kinds into memory and returns a SchemaValidator instance. The builtinPublicBase is used to construct canonical URLs for the built-in meta-schemas. It must be an absolute URL with a host (e.g. "https://raw.githubusercontent.com/zitadel/nextgen/refs/tags/v1.2.3/api/openapi/endpoints/schemas").
func (*SchemaValidator) GetBuiltinSchema ¶
func (v *SchemaValidator) GetBuiltinSchema(uri string) (*jsonschema.Schema, error)
GetBuiltinSchema returns a clone of the compiled meta-schema for the given kind. The returned schema has all $refs resolved.
Example usage:
flowDefSchema, err := validator.GetBuiltinSchema(SchemaKindFlowDefinition)
if err != nil {
return err
}
if err := flowDefSchema.Validate(flowDefinition); err != nil {
return fmt.Errorf("flow definition invalid: %w", err)
}
todo: support fetching compiled schema by version as well when multiple versions of the meta-schemas are available.
func (*SchemaValidator) LatestSchemaURI ¶
func (v *SchemaValidator) LatestSchemaURI(kind KnownSchemaKind) (string, error)
LatestSchemaURI returns the canonical URI of the latest registered version for the given kind stem (e.g. "flow-definition", "user-schema"). This is useful for fetching the latest version of a schema when it's optional to provide a version.
func (*SchemaValidator) ValidateAgainstMetaSchema ¶
func (v *SchemaValidator) ValidateAgainstMetaSchema(schemaBs []byte) error
ValidateAgainstMetaSchema validates the given tenant schema document against the appropriate meta-schema based on its declared "kind" property. At the moment, only "user-schema" and "flow-definition" are supported.
type Session ¶
type Session struct {
// ProjectID links to [Project].
ProjectID string
// ID is the unique identifier for the session within the project and user.
ID string
// CreatedAt is the time when the session was created, it must be set by the storage and is read only.
CreatedAt time.Time
// UpdatedAt is the time when the session was last updated, it must be set by the storage and is read only.
UpdatedAt time.Time
// ExpiresAt is the time when the session expires. Is used for garbage collection.
ExpiresAt time.Time
// TimeToLive is the duration after which the session expires.
TimeToLive time.Duration
// TokenID is the id of the token that was generated for the session. The token must be generated by the storage and its id must be set to the session.
TokenID string
// UserID links to the [User] the session belongs to once associated.
// A user may have multiple sessions (e.g. from different devices or browsers), and UserID may be nil during some lifecycle stages.
UserID *string
// User is the linked user's resolved reference (ADR 058 §3), derived
// from the schema's x-identifier/x-display designations. Only populated
// on identity-hydrating reads; nil for anonymous sessions.
User *UserRef
// UserAgent contains information about the user's device and browser.
UserAgent *UserAgent
// AssuranceLevels are computed at runtime and therefore not stored in the database.
AssuranceLevels []string
// Factors contain the authentication factors that were used to verify the session.
// There is one factor per [AuthCheckType].
// The factors must be verified using [AuthAttempt]s before being added to the session, and the VerifiedAt field must be set to the time of verification.
// The factors are stored in the database.
Factors []AuthFactor
}
Session represents the object defined [here](https://github.com/zitadel/nextgen/blob/main/docs/design/api/resource-map.md#sessions-durable-post-auth-only)
func (*Session) State ¶
func (s *Session) State() SessionState
type SessionDeletedPayload ¶
type SessionDeletedPayload struct {
Reason string `json:"reason,omitempty"`
}
type SessionEstablishedPayload ¶
type SessionEstablishedPayload struct {
UserID string `json:"user_id,omitempty"`
}
type SessionExpiredPayload ¶
type SessionExpiredPayload struct{}
type SessionField ¶
type SessionField uint8
SessionField enumerates the fields of Session which can be used for filtering and ordering in list operations.
const ( SessionFieldUnspecified SessionField = iota SessionFieldProjectID SessionFieldID SessionFieldCreatedAt SessionFieldUpdatedAt SessionFieldExpiresAt SessionFieldTimeToLive SessionFieldTokenID SessionFieldUserID // SessionFieldHasVerifiedFactors is computed, not stored: it reflects // whether the session has verified factors, the test State() uses to // separate building from active. Filter only; not sortable. SessionFieldHasVerifiedFactors // SessionFieldLifecycleOwnerTeamID is computed, not stored: a session // belongs to the team that owns its bound user's lifecycle (ADR 024, // ADR 060). A user has at most one lifecycle owner, so a session matches // at most one team; a self-owned user's session and a session with no user // match none. It is filter only; not sortable — a team matches many // sessions, and the value lives on another table. SessionFieldLifecycleOwnerTeamID )
type SessionState ¶
type SessionState uint8
const ( SessionStateUnspecified SessionState = iota SessionStateBuilding SessionStateActive SessionStateExpired )
type SetUserPassword ¶
type SetUserPassword struct {
// ID is the password row id. Dialects mint on create and overwrite with the
// persisted id on upsert (RETURNING / equivalent) so emitters can set
// entity_id / factor_id.
ID string
ProjectID string
UserID string
EncodedHash string
ChangeRequired bool
VerificationID *string
}
type SigningKey ¶
type SigningKey struct {
ID string
ProjectID string
Purpose SigningKeyPurpose
Key string
Algorithm jose.SignatureAlgorithm
State KeyState
CreatedAt time.Time
ActivatedAt *time.Time
RetiredAt *time.Time
}
func NewSigningKey ¶
func NewSigningKey( projectID string, purpose SigningKeyPurpose, algorithm jose.SignatureAlgorithm, kek crypto.Crypter, ) (*SigningKey, error)
func (*SigningKey) Activate ¶
func (k *SigningKey) Activate(currentKey *SigningKey)
func (*SigningKey) IsActive ¶
func (k *SigningKey) IsActive() bool
func (*SigningKey) IsRemoved ¶
func (k *SigningKey) IsRemoved() bool
type SigningKeyField ¶
type SigningKeyField uint8
const ( SigningKeyFieldUnspecified SigningKeyField = iota SigningKeyFieldID SigningKeyFieldProjectID SigningKeyFieldKey SigningKeyFieldAlgorithm SigningKeyFieldState SigningKeyFieldCreatedAt SigningKeyFieldActivatedAt SigningKeyFieldRetiredAt SigningKeyFieldPurpose )
type SigningKeyPurpose ¶
type SigningKeyPurpose string
const (
SigningKeyPurposeToken SigningKeyPurpose = "token"
)
type Team ¶
type Team struct {
// ProjectID links to [Project].
ProjectID string
// ID is the unique identifier for the team within the project.
ID string
Name string
Status TeamStatus
CreatedAt time.Time
UpdatedAt time.Time
}
Team represents the object defined [here](https://github.com/zitadel/nextgen/blob/main/docs/design/api/resource-map.md#teams) It is hardly ever modified but read a lot therefore it should be stored in global tables.
type TeamCreatedPayload ¶
type TeamCreatedPayload = TeamPayload
type TeamDeactivatedPayload ¶
type TeamDeactivatedPayload struct{}
type TeamField ¶
type TeamField uint8
TeamField enumerates the fields of Team which can be used for filtering and ordering.
type TeamMembership ¶
type TeamMembership struct {
ProjectID string
TeamID string
UserID string
Status MembershipStatus
CreatedAt time.Time
UpdatedAt time.Time
}
TeamMembership is the canonical N:N roster between users and teams.
type TeamMembershipField ¶
type TeamMembershipField uint8
TeamMembershipField enumerates the fields of TeamMembership which can be used for filtering and ordering in list operations.
const ( TeamMembershipFieldUnspecified TeamMembershipField = iota TeamMembershipFieldProjectID TeamMembershipFieldTeamID TeamMembershipFieldUserID TeamMembershipFieldStatus TeamMembershipFieldCreatedAt TeamMembershipFieldUpdatedAt )
type TeamPayload ¶
type TeamPayload struct {
Name string `json:"name,omitempty"`
}
TeamPayload is shared by team.created and team.updated (delta on update).
type TeamStatus ¶
type TeamStatus string
TeamStatus is the lifecycle state of a team within a project.
const ( TeamStatusActive TeamStatus = "active" TeamStatusDeactivated TeamStatus = "deactivated" TeamStatusPendingPurge TeamStatus = "pending_purge" )
func (TeamStatus) String ¶
func (s TeamStatus) String() string
type TeamUpdatedPayload ¶
type TeamUpdatedPayload = TeamPayload
type Token ¶
type Token struct {
ProjectID string
TokenID string
UserID string
Type TokenType
// SessionID is set for [TokenTypeSessionToken] only.
SessionID *string
// OIDCSessionID is set for [TokenTypeOIDCAccessToken] only.
OIDCSessionID *string
// SAMLSessionID is set for [TokenTypeSAMLAssertion] only.
SAMLSessionID *string
Scope []string
CreatedAt time.Time
ExpiresAt *time.Time
}
Token is a persisted token record (access, session, PAT, etc.).
A revocable token carries its record's id (`TokenID`, the `jti`). The token itself is never stored — only the id, which is not a secret (ADR 029) — and verification resolves that id against the record to decide whether the token is still active. Revocation deletes the record: a token whose record is gone is rejected, and the tokens table does not accumulate rows that grant nothing (ADR 037).
func ParseAndValidateToken ¶
func (*Token) Active ¶
Active reports whether the stored record still grants the token's authority at the given instant. A revoked record is deleted, so reaching this call at all means the token was not revoked; only expiry is left to check.
func (*Token) IsRevocable ¶
IsRevocable reports whether this token's authority is resolved against a stored record. A revocable token must carry a TokenID to be verifiable.
func (*Token) ValidatePersisted ¶
ValidatePersisted checks identifier fields before writing to the tokens table.
type TokenField ¶
type TokenField uint8
TokenField enumerates the fields of Token which can be used for filtering and ordering in list operations.
const ( TokenFieldUnspecified TokenField = iota TokenFieldProjectID TokenFieldTokenID TokenFieldUserID TokenFieldType TokenFieldSessionID TokenFieldOIDCSessionID TokenFieldSAMLSessionID TokenFieldScope TokenFieldExpiresAt TokenFieldCreatedAt )
type TokenType ¶
type TokenType uint8
const ( TokenTypeUnspecified TokenType = iota TokenTypeSessionToken TokenTypeOIDCAccessToken TokenTypeSAMLAssertion TokenTypePersonalAccessToken // TokenTypeFlow is carried in a flow-engine cookie; it is not stored and must not be used as a bearer token. TokenTypeFlow // TokenTypeJWTProfile is a self-signed JWT verified with a stored public key; it is not stored but may be used as a bearer token. TokenTypeJWTProfile // TokenTypeProjectToken is the confidential-plane project secret (ADR 036) TokenTypeProjectToken // TokenTypeProjectPreview is the read-only preview credential issued // alongside the project secret. TokenTypeProjectPreview )
func TokenTypeString ¶
TokenTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func TokenTypeValues ¶
func TokenTypeValues() []TokenType
TokenTypeValues returns all values of the enum
func (TokenType) IsATokenType ¶
IsATokenType returns "true" if the value is listed in the enum definition. "false" otherwise
func (TokenType) IsProjectSecret ¶
IsProjectSecret reports whether t may mint an sk_proj ScopeContext. TokenTypeJWTProfile may be presented as a bearer (see its const comment) but is not a project secret and must not take that path.
func (TokenType) MarshalJSON ¶
MarshalJSON implements the json.Marshaler interface for TokenType
func (TokenType) Persistable ¶
Persistable reports whether t may be written to the tokens table.
func (*TokenType) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unmarshaler interface for TokenType
type User ¶
type User struct {
ProjectID string
SchemaURL string
ID string
// LifecycleOwnerTeamID is set when a team owns this user's lifecycle; nil means self-owned.
LifecycleOwnerTeamID *string
Metadata UserMetadata
// Attributes are populated by user read statements.
Attributes Attributes
// Ref is the derived identity of ADR 058 §3a, resolved live from the
// schema's x-identifier/x-display designations. Populated by service
// reads that resolve it; nil on plain statement-level reads.
Ref *UserRef
// Teams is the user's team memberships, populated only when the read asked
// for it. Nil means it was not asked for; empty means the user has none.
Teams []UserTeam
// TeamsTruncated reports that the user is on more teams than the read's
// cap carries. The whole list is served by ListUserTeams.
TeamsTruncated bool
// LifecycleOwnerTeam is the team named by LifecycleOwnerTeamID, populated
// only when the read asked for it. Nil alone is ambiguous — a self-owned
// user has no owner to load — so LifecycleOwnerTeamLoaded is what says the
// read looked.
LifecycleOwnerTeam *Team
// LifecycleOwnerTeamLoaded reports that the read resolved the owner team.
// It is the to-one counterpart of Teams being non-nil: it separates "not
// asked for" from "asked for, and the user is self-owned".
LifecycleOwnerTeamLoaded bool
}
User is a hydrated user projection (header + optional EAV joins).
func (*User) IsSelfOwned ¶
IsSelfOwned reports whether the user owns their own lifecycle.
func (*User) IsTeamOwned ¶
IsTeamOwned reports whether a team owns this user's lifecycle.
func (*User) OwningTeamID ¶
OwningTeamID returns the lifecycle owner team id when team-owned.
func (*User) StringAttribute ¶
func (u *User) StringAttribute(key AttributeKey) string
StringAttribute returns the value of the attribute with the given key when it is a non-empty string, and "" otherwise (absent key or non-string value).
type UserCreateFailedPayload ¶
type UserCreateFailedPayload struct {
KeyName string `json:"key_name,omitempty"`
}
type UserCreatedPayload ¶
type UserCreatedPayload struct {
SchemaID string `json:"schema_id,omitempty"`
AttributeKeys []string `json:"attribute_keys,omitempty"`
Attributes map[string]any `json:"attributes,omitempty"`
}
UserCreatedPayload omits user_id (envelope entity_id). Attribute values appear only for schema fields marked x-audit.
type UserDeactivatedPayload ¶
type UserDeactivatedPayload struct {
Reason string `json:"reason,omitempty"`
}
type UserDeletedPayload ¶
type UserDeletedPayload struct{}
type UserField ¶
type UserField uint8
UserField enumerates the fields of User which can be used for filtering and ordering in list operations.
type UserMetadata ¶
type UserMetadata struct {
Status UserStatus
CreatedAt time.Time
UpdatedAt time.Time
}
type UserPasskey ¶
type UserPasskey struct {
ID string
ProjectID string
UserID string
CredentialID string
PublicKey []byte
AAGUID []byte
AttestationType *string
Transports []string
SignCount int64
BackupEligible bool
BackupState bool
Name string
VerifiedAt *time.Time
LastUsedAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
type UserPasskeyAttestationTypeUpdate ¶
type UserPasskeyAttestationTypeUpdate struct {
AttestationType string
}
type UserPasskeyBackupEligibleUpdate ¶
type UserPasskeyBackupEligibleUpdate struct {
BackupEligible bool
}
type UserPasskeyBackupStateUpdate ¶
type UserPasskeyBackupStateUpdate struct {
BackupState bool
}
type UserPasskeyField ¶
type UserPasskeyField uint8
UserPasskeyField enumerates the fields of UserPasskey which can be used for filtering and ordering in list operations.
const ( UserPasskeyFieldUnspecified UserPasskeyField = iota UserPasskeyFieldID UserPasskeyFieldProjectID UserPasskeyFieldUserID UserPasskeyFieldCredentialID UserPasskeyFieldSignCount UserPasskeyFieldBackupEligible UserPasskeyFieldBackupState UserPasskeyFieldName UserPasskeyFieldVerifiedAt UserPasskeyFieldLastUsedAt UserPasskeyFieldCreatedAt UserPasskeyFieldUpdatedAt )
type UserPasskeySignCountUpdate ¶
type UserPasskeySignCountUpdate struct {
SignCount int64
}
type UserPasskeyTransportsUpdate ¶
type UserPasskeyTransportsUpdate struct {
Transports []string
}
type UserPasskeyUpdate ¶
type UserPasskeyUpdate interface {
// contains filtered or unexported methods
}
type UserPassword ¶
type UserPassword struct {
ID string
ProjectID string
UserID string
EncodedHash string
ChangeRequired bool
ChangedAt time.Time
VerificationID *string
LastSuccessfulCheck *time.Time
FailedAttempts int16
CreatedAt time.Time
UpdatedAt time.Time
}
func (*UserPassword) Verify ¶
func (u *UserPassword) Verify(password string, verifier crypto.HashVerifier) error
type UserPasswordChangeRequiredUpdate ¶
type UserPasswordChangeRequiredUpdate struct {
ChangeRequired bool
}
type UserPasswordEncodedHashUpdate ¶
type UserPasswordEncodedHashUpdate struct {
EncodedHash string
}
type UserPasswordField ¶
type UserPasswordField uint8
UserPasswordField enumerates the fields of UserPassword which can be used for filtering and ordering in storage statements.
const ( UserPasswordFieldUnspecified UserPasswordField = iota UserPasswordFieldID UserPasswordFieldProjectID UserPasswordFieldUserID UserPasswordFieldEncodedHash UserPasswordFieldChangeRequired UserPasswordFieldChangedAt UserPasswordFieldVerificationID UserPasswordFieldLastSuccessfulCheck UserPasswordFieldFailedAttempts UserPasswordFieldCreatedAt UserPasswordFieldUpdatedAt )
type UserPasswordIncrementFailedAttemptsUpdate ¶
type UserPasswordIncrementFailedAttemptsUpdate struct {
Delta uint8
}
type UserPasswordResetFailedAttemptsUpdate ¶
type UserPasswordResetFailedAttemptsUpdate struct{}
type UserPasswordUpdate ¶
type UserPasswordUpdate interface {
// contains filtered or unexported methods
}
type UserPasswordVerificationIDUpdate ¶
type UserPasswordVerificationIDUpdate struct {
VerificationID string
}
type UserRecoveryCodes ¶
type UserRecoveryCodesCodesUpdate ¶
type UserRecoveryCodesCodesUpdate struct {
Codes []string
}
type UserRecoveryCodesField ¶
type UserRecoveryCodesField uint8
UserRecoveryCodesField enumerates the fields of UserRecoveryCodes which can be used for filtering and ordering in list operations.
const ( UserRecoveryCodesFieldUnspecified UserRecoveryCodesField = iota UserRecoveryCodesFieldID UserRecoveryCodesFieldProjectID UserRecoveryCodesFieldUserID UserRecoveryCodesFieldRecoveryCodes UserRecoveryCodesFieldLastSuccessfulCheck UserRecoveryCodesFieldFailedAttempts UserRecoveryCodesFieldCreatedAt UserRecoveryCodesFieldUpdatedAt )
type UserRecoveryCodesIncrementFailedAttemptsUpdate ¶
type UserRecoveryCodesIncrementFailedAttemptsUpdate struct {
Delta uint8
}
type UserRecoveryCodesResetFailedAttemptsUpdate ¶
type UserRecoveryCodesResetFailedAttemptsUpdate struct{}
type UserRecoveryCodesUpdate ¶
type UserRecoveryCodesUpdate interface {
// contains filtered or unexported methods
}
type UserRef ¶
type UserRef struct {
UserID string
// Identifier is the current value of the schema's designated identifier
// (x-identifier). Empty when the schema designates nothing or the user
// lacks the value.
Identifier string
// IdentifierProperty names the schema property Identifier came from, so
// clients can reach the property's schema for semantics instead of
// guessing from the value. Set exactly when Identifier is.
IdentifierProperty string
// Display is the x-display rendering: the designated properties' values
// joined in list order. Purely presentational — no source attribution.
Display string
}
UserRef is the resolved reference to a user carried by user-linked resources (ADR 058 §3). Fields are role-named, not property-named, so responses can mix users from different schemas. An empty field means absent on the wire; Identifier and Display resolve independently of each other, and clients render Display → Identifier → UserID.
func ResolveUserRef ¶
ResolveUserRef derives the user's reference from their schema document's designations. Attribute values are read from the user's loaded attributes: designation paths are dot-joined leaf paths, matching the EAV flattening of AttributeKey, so entries address attribute keys verbatim. The user's attributes must be hydrated with at least the designated keys (see DesignatedAttributeKeys).
type UserSchemaUnknownDetails ¶
type UserSchemaUnknownDetails struct {
Schema string `json:"schema"`
}
UserSchemaUnknownDetails names the schema a create referenced that the project does not have.
type UserStatus ¶
type UserStatus string
UserStatus is the lifecycle state of a user identity within a project.
const ( UserStatusActive UserStatus = "active" UserStatusSuspended UserStatus = "suspended" UserStatusDeactivated UserStatus = "deactivated" UserStatusPendingPurge UserStatus = "pending_purge" )
func (UserStatus) String ¶
func (s UserStatus) String() string
type UserTOTPField ¶
type UserTOTPField uint8
UserTOTPField enumerates the fields of UserTOTP which can be used for filtering and ordering in list operations.
const ( UserTOTPFieldUnspecified UserTOTPField = iota UserTOTPFieldID UserTOTPFieldProjectID UserTOTPFieldUserID UserTOTPFieldSecret UserTOTPFieldVerifiedAt UserTOTPFieldLastSuccessfulCheck UserTOTPFieldFailedAttempts UserTOTPFieldCreatedAt UserTOTPFieldUpdatedAt )
type UserTOTPIncrementFailedAttemptsUpdate ¶
type UserTOTPIncrementFailedAttemptsUpdate struct {
Delta uint8
}
type UserTOTPResetFailedAttemptsUpdate ¶
type UserTOTPResetFailedAttemptsUpdate struct{}
type UserTOTPSecretUpdate ¶
type UserTOTPSecretUpdate struct {
Secret []byte
}
type UserTOTPUpdate ¶
type UserTOTPUpdate interface {
// contains filtered or unexported methods
}
type UserTeam ¶
type UserTeam struct {
ProjectID string
UserID string
TeamID string
TeamName string
// Status is the roster participation state, not the team's own status.
Status MembershipStatus
CreatedAt time.Time
UpdatedAt time.Time
}
UserTeam is one entry of a user's team roster: the membership joined to the team it points at, so a reader gets the team's name without a second lookup.
The roster is not lifecycle ownership. A user can sit on many team rosters while still owning their own lifecycle — see User.LifecycleOwnerTeamID and ADR 024.
type UserTeamField ¶
type UserTeamField uint8
UserTeamField enumerates the fields of UserTeam which can be used for filtering and ordering in list operations.
const ( UserTeamFieldUnspecified UserTeamField = iota UserTeamFieldProjectID UserTeamFieldUserID UserTeamFieldTeamID UserTeamFieldTeamName UserTeamFieldStatus UserTeamFieldCreatedAt UserTeamFieldUpdatedAt )
type UserUpdatedPayload ¶
type UserUpdatedPayload struct {
AttributeKeys []string `json:"attribute_keys,omitempty"`
Attributes map[string]any `json:"attributes,omitempty"`
}
UserUpdatedPayload lists keys touched; values only for x-audit fields.
Source Files
¶
- attribute.go
- auth.go
- auth_attempt.go
- auth_check.go
- auth_check_type_passkey.go
- auth_check_type_password.go
- auth_check_type_user.go
- authchecktype_enumer.go
- authz.go
- branding.go
- branding_validator.go
- claim.go
- encryption_key.go
- environment.go
- error.go
- event.go
- event_payload.go
- event_sink.go
- flow_auth_attempt.go
- flow_definition.go
- flow_definition_errors.go
- flow_definition_validator.go
- flow_errors.go
- flow_field_resolver.go
- flow_field_resolver_schema.go
- flow_field_validation.go
- flow_on_success.go
- flow_state.go
- flow_state_machine.go
- flowactionkind_enumer.go
- flowdefinitionpurpose_enumer.go
- flowdefinitionstatus_enumer.go
- flowdefinitiontransitionaction_enumer.go
- flowgatekind_enumer.go
- flowonsuccess_enumer.go
- flowstepcomplete_enumer.go
- grant.go
- handoff_token.go
- json_schema.go
- jsonschemakind_enumer.go
- project.go
- resource.go
- schema_annotations.go
- schema_designation.go
- schema_validator.go
- session.go
- signing_key.go
- team.go
- team_membership.go
- token.go
- token_type.go
- tokentype_enumer.go
- user.go
- user_passkey.go
- user_passkey_update.go
- user_passkeys.go
- user_password.go
- user_password_update.go
- user_recover_codes.go
- user_recovery_codes_update.go
- user_ref.go
- user_team.go
- user_totp.go
- user_totp_update.go