Documentation
¶
Overview ¶
Package axiam — OIDC / SSO relying-party helpers (CONTRACT.md §12, contract 1.4).
The nine canonical §12 operations, under the exact §12.2 Go names, as methods on the existing *Client: OidcDiscover, OidcBegin, OidcExchange, OidcRefresh, LoginClientCredentials, Introspect, Revoke, SsoStart, SsoComplete.
Everything besides the PKCE/CSPRNG primitives (oidc_pkce.go) and the issuer/audience/time/nonce checklist (oidc_idtoken.go) is reuse, not reimplementation (§12 forbids forking):
- transport + §2 error mapping + §3 CSRF + §4 cookie jar + §5 tenant header + §6 TLS -> the SAME *http.Client / doRequest/newRequest choke point client.go already built;
- §12.4 signature verification -> internal/jwks.Verifier, extended (never forked) with a raw-payload entry point;
- §7/§12.5 redaction -> the existing Sensitive type.
Index ¶
- Constants
- Variables
- func RevocationEntryFor(sid string) string
- func UmaChallengeHeader(realm, asURI string, ticket Sensitive) string
- func WebauthnErrorMessage(failure WebauthnFailure) string
- type APIProviderConfig
- type AccessCheck
- type AccessResult
- type ActorType
- type AddMemberRequest
- type AddServiceAccountMemberRequest
- type AppliedStep
- type ApplyReport
- type AssignRoleToGroupRequest
- type AssignRoleToServiceAccountRequest
- type AssignRoleToUserRequest
- type AttestationMode
- type AuditAPI
- func (a *AuditAPI) List(ctx context.Context, filter AuditListFilter, page PageRequest) (Page[AuditLogEntry], error)
- func (a *AuditAPI) ListAll(ctx context.Context, filter AuditListFilter, start PageRequest) ([]AuditLogEntry, error)
- func (a *AuditAPI) ListSystem(ctx context.Context, filter AuditListSystemFilter, page PageRequest) (Page[AuditLogEntry], error)
- func (a *AuditAPI) ListSystemAll(ctx context.Context, filter AuditListSystemFilter, start PageRequest) ([]AuditLogEntry, error)
- type AuditListFilter
- type AuditListSystemFilter
- type AuditLogEntry
- type AuditOutcome
- type AuthError
- type AuthnRequestParamsMode
- type AuthorizationRequest
- type AuthzError
- type BindCertificate
- type CACertificate
- type CACertificatesAPI
- func (a *CACertificatesAPI) Generate(ctx context.Context, body CreateCACertificateRequest) (GeneratedCACertificate, error)
- func (a *CACertificatesAPI) GenerateSigningCA(ctx context.Context, tenantID uuid.UUID, body CreateIntermediateCARequest) (GeneratedCACertificate, error)
- func (a *CACertificatesAPI) Get(ctx context.Context, id uuid.UUID) (CACertificate, error)
- func (a *CACertificatesAPI) ImportCA(ctx context.Context, body ImportCACertificateRequest) (CACertificate, error)
- func (a *CACertificatesAPI) InOrg(orgID uuid.UUID) *CACertificatesAPI
- func (a *CACertificatesAPI) List(ctx context.Context, page PageRequest) (Page[CACertificate], error)
- func (a *CACertificatesAPI) ListAll(ctx context.Context, start PageRequest) ([]CACertificate, error)
- func (a *CACertificatesAPI) ListSigningCas(ctx context.Context, tenantID uuid.UUID, page PageRequest) (Page[CACertificate], error)
- func (a *CACertificatesAPI) ListSigningCasAll(ctx context.Context, tenantID uuid.UUID, start PageRequest) ([]CACertificate, error)
- func (a *CACertificatesAPI) MigrateCustody(ctx context.Context, id uuid.UUID) (MigrateCustodyResponse, error)
- func (a *CACertificatesAPI) Revoke(ctx context.Context, id uuid.UUID) error
- func (a *CACertificatesAPI) SetMTLSTrustAnchor(ctx context.Context, id uuid.UUID, body SetMTLSTrustAnchor) (MTLSTrustAnchorResponse, error)
- func (a *CACertificatesAPI) SignSigningCACSR(ctx context.Context, tenantID uuid.UUID, body SignIntermediateCSRRequest) (CACertificate, error)
- type Certificate
- type CertificatePolicy
- type CertificateStatus
- type CertificateType
- type CertificatesAPI
- func (a *CertificatesAPI) Generate(ctx context.Context, body CreateCertificateRequest) (GeneratedCertificate, error)
- func (a *CertificatesAPI) Get(ctx context.Context, id uuid.UUID) (Certificate, error)
- func (a *CertificatesAPI) List(ctx context.Context, page PageRequest) (Page[Certificate], error)
- func (a *CertificatesAPI) ListAll(ctx context.Context, start PageRequest) ([]Certificate, error)
- func (a *CertificatesAPI) Revoke(ctx context.Context, id uuid.UUID) error
- type CertificationLevel
- type Change
- type Client
- func (c *Client) Audit() *AuditAPI
- func (c *Client) BatchCheck(ctx context.Context, reqs []AccessCheck) ([]AccessResult, error)
- func (c *Client) CACertificates() *CACertificatesAPI
- func (c *Client) Can(ctx context.Context, action, resourceID string, scope ...string) (bool, error)
- func (c *Client) Certificates() *CertificatesAPI
- func (c *Client) CheckAccess(ctx context.Context, action, resourceID string, scope ...string) (bool, string, error)
- func (c *Client) CheckAccessAs(ctx context.Context, subjectID, action, resourceID string, scope ...string) (bool, string, error)
- func (c *Client) CheckAccessDecision(ctx context.Context, subjectID, action, resourceID string, scope ...string) (AccessResult, error)
- func (c *Client) Close() error
- func (c *Client) ConfirmPasswordReset(ctx context.Context, confirmation PasswordResetConfirmation) error
- func (c *Client) DeviceAuthorize(ctx context.Context, params DeviceAuthorizeParams) (DeviceAuthorization, error)
- func (c *Client) DeviceLogin(ctx context.Context, params DeviceLoginParams) (OidcTokenSet, error)
- func (c *Client) DevicePoll(ctx context.Context, params DevicePollParams) (OidcTokenSet, error)
- func (c *Client) EmailConfig() *EmailConfigAPI
- func (c *Client) Federation() *FederationAPI
- func (c *Client) Groups() *GroupsAPI
- func (c *Client) Introspect(ctx context.Context, params IntrospectParams) (IntrospectionResult, error)
- func (c *Client) Login(ctx context.Context, email, password string) (LoginResult, error)
- func (c *Client) LoginClientCredentials(ctx context.Context, params LoginClientCredentialsParams) (OidcTokenSet, error)
- func (c *Client) LoginOpaque(ctx context.Context, usernameOrEmail, password string) (LoginResult, error)
- func (c *Client) Logout(ctx context.Context) error
- func (c *Client) LogoutURL(ctx context.Context, params LogoutURLParams) (string, error)
- func (c *Client) Manifest() *ManifestAPI
- func (c *Client) MfaConfirm(ctx context.Context, totpCode string) (bool, error)
- func (c *Client) MfaEnroll(ctx context.Context) (MfaEnrollment, error)
- func (c *Client) MfaSetupConfirm(ctx context.Context, setupToken Sensitive, totpCode string) (LoginResult, error)
- func (c *Client) MfaSetupEnroll(ctx context.Context, setupToken Sensitive) (MfaEnrollment, error)
- func (c *Client) NotificationRules() *NotificationRulesAPI
- func (c *Client) OAuth2Clients() *OAuth2ClientsAPI
- func (c *Client) OidcBegin(configuration OidcConfiguration, params OidcBeginParams) (AuthorizationRequest, error)
- func (c *Client) OidcDiscover(ctx context.Context) (OidcConfiguration, error)
- func (c *Client) OidcExchange(ctx context.Context, params OidcExchangeParams) (OidcTokenSet, error)
- func (c *Client) OidcPar(ctx context.Context, params OidcParParams) (PushedAuthorizationRequest, error)
- func (c *Client) OidcRefresh(ctx context.Context, params OidcRefreshParams) (OidcTokenSet, error)
- func (c *Client) OpaqueAvailable() bool
- func (c *Client) OpaqueEnrollment(ctx context.Context, password string) (*OpaqueEnrollment, error)
- func (c *Client) OpaqueEnrollmentForSelf(ctx context.Context, password string) (*OpaqueEnrollment, error)
- func (c *Client) Organizations() *OrganizationsAPI
- func (c *Client) PGPKeys() *PGPKeysAPI
- func (c *Client) PasswordResetContext(ctx context.Context, token Sensitive) (PasswordResetContext, error)
- func (c *Client) Permissions() *PermissionsAPI
- func (c *Client) Platform() *PlatformAPI
- func (c *Client) Privacy() *PrivacyAPI
- func (c *Client) Reactors() *ReactorsAPI
- func (c *Client) Refresh(ctx context.Context) error
- func (c *Client) RequestPasswordReset(ctx context.Context, request PasswordResetRequest) error
- func (c *Client) ResendOwnVerification(ctx context.Context) error
- func (c *Client) ResendVerification(ctx context.Context, email, tenantID string) error
- func (c *Client) ResolvedOrgID() (uuid.UUID, bool)
- func (c *Client) ResolvedTenantID() (uuid.UUID, bool)
- func (c *Client) Resources() *ResourcesAPI
- func (c *Client) Revoke(ctx context.Context, params RevokeParams) error
- func (c *Client) Roles() *RolesAPI
- func (c *Client) SCIMTokens() *SCIMTokensAPI
- func (c *Client) Scopes() *ScopesAPI
- func (c *Client) ServiceAccounts() *ServiceAccountsAPI
- func (c *Client) Settings() *SettingsAPI
- func (c *Client) SsoComplete(ctx context.Context, params SsoCompleteParams) (SsoCompleteResult, error)
- func (c *Client) SsoCompleteHandoff(ctx context.Context, params SsoCompleteHandoffParams) (SsoCompleteResult, error)
- func (c *Client) SsoCompleteOauth2(ctx context.Context, params SsoCompleteOauth2Params) (SsoCompleteResult, error)
- func (c *Client) SsoProviders(ctx context.Context, params SsoProvidersParams) (FederationProviderList, error)
- func (c *Client) SsoStart(ctx context.Context, params SsoStartParams) (SsoStartResult, error)
- func (c *Client) SsoStartOauth2(ctx context.Context, params SsoStartOauth2Params) (SsoStartResult, error)
- func (c *Client) Tenants() *TenantsAPI
- func (c *Client) TokenExchange(ctx context.Context, params TokenExchangeParams) (ExchangedToken, error)
- func (c *Client) UmaDeleteResource(ctx context.Context, pat Sensitive, id string) error
- func (c *Client) UmaExchangeTicket(ctx context.Context, params UmaExchangeTicketParams) (RequestingPartyToken, error)
- func (c *Client) UmaListResources(ctx context.Context, pat Sensitive) ([]string, error)
- func (c *Client) UmaReadResource(ctx context.Context, pat Sensitive, id string) (ResourceSet, error)
- func (c *Client) UmaRegisterResource(ctx context.Context, pat Sensitive, resource ResourceSet) (ResourceSet, error)
- func (c *Client) UmaRequestTicket(ctx context.Context, pat Sensitive, permissions []RequestedPermission) (Sensitive, error)
- func (c *Client) UmaUpdateResource(ctx context.Context, pat Sensitive, id string, resource ResourceSet) (ResourceSet, error)
- func (c *Client) Users() *UsersAPI
- func (c *Client) VerifyEmail(ctx context.Context, token Sensitive, tenantID string) error
- func (c *Client) VerifyLogoutToken(ctx context.Context, token string, configuration *OidcConfiguration) (VerifiedLogoutToken, error)
- func (c *Client) VerifyMfa(ctx context.Context, mfaToken Sensitive, code string) (LoginResult, error)
- func (c *Client) WebauthnAuthenticateFinish(ctx context.Context, stateToken Sensitive, response any) (WebauthnLoginResult, error)
- func (c *Client) WebauthnAuthenticateStart(ctx context.Context, challengeToken Sensitive) (WebauthnChallenge, error)
- func (c *Client) WebauthnDiscoverableFinish(ctx context.Context, stateToken Sensitive, response any) (WebauthnLoginResult, error)
- func (c *Client) WebauthnDiscoverableStart(ctx context.Context, workspace *WebauthnWorkspace) (WebauthnChallenge, error)
- func (c *Client) WebauthnPolicy() *WebauthnPolicyAPI
- func (c *Client) WebauthnRegisterFinish(ctx context.Context, stateToken Sensitive, credentialName string, response any) (WebauthnCredential, error)
- func (c *Client) WebauthnRegisterStart(ctx context.Context) (WebauthnChallenge, error)
- func (c *Client) Webhooks() *WebhooksAPI
- type ClientAuthMethod
- type ClientProfile
- type ComplianceReportEntry
- type ConfigClampedEvent
- type Confirmation
- type ConflictError
- type ConsentView
- type CreateCACertificateRequest
- type CreateCertificateRequest
- type CreateFederationConfigRequest
- type CreateGroupRequest
- type CreateIntermediateCARequest
- type CreateNotificationRuleRequest
- type CreateOAuth2ClientRequest
- type CreatePGPKeyRequest
- type CreatePermissionRequest
- type CreateReactorRequest
- type CreateResourceRequest
- type CreateRoleRequest
- type CreateSCIMTokenRequest
- type CreateSCIMTokenResponse
- type CreateScopeRequest
- type CreateServiceAccountRequest
- type CreateTenantRequest
- type CreateUserRequest
- type CreateWebhookRequest
- type DPoPJtiStore
- type DPoPRequest
- type DeviceAuthorization
- type DeviceAuthorizeParams
- type DeviceLoginParams
- type DevicePollParams
- type EmailConfig
- type EmailConfigAPI
- func (a *EmailConfigAPI) DeleteOrg(ctx context.Context) error
- func (a *EmailConfigAPI) DeleteTenant(ctx context.Context) error
- func (a *EmailConfigAPI) ForTenant(tenantID uuid.UUID) *EmailConfigAPI
- func (a *EmailConfigAPI) GetOrg(ctx context.Context) (EmailConfig, error)
- func (a *EmailConfigAPI) GetTenant(ctx context.Context) (EmailConfigOverride, error)
- func (a *EmailConfigAPI) InOrg(orgID uuid.UUID) *EmailConfigAPI
- func (a *EmailConfigAPI) SetOrg(ctx context.Context, body SetOrgEmailConfig) (EmailConfig, error)
- func (a *EmailConfigAPI) SetTenant(ctx context.Context, body EmailConfigOverride) (EmailConfigOverride, error)
- func (a *EmailConfigAPI) TestOrg(ctx context.Context) (EmailTestResult, error)
- func (a *EmailConfigAPI) TestTenant(ctx context.Context) (EmailTestResult, error)
- type EmailConfigOverride
- type EmailTestResult
- type EmailVerificationPolicy
- type EncryptRequest
- type EncryptedExport
- type ExchangedToken
- type FailurePolicy
- type FederationAPI
- func (a *FederationAPI) CreateConfig(ctx context.Context, body CreateFederationConfigRequest) (FederationConfigResponse, error)
- func (a *FederationAPI) DeleteConfig(ctx context.Context, id uuid.UUID) error
- func (a *FederationAPI) DeleteLink(ctx context.Context, id uuid.UUID) error
- func (a *FederationAPI) GetConfig(ctx context.Context, id uuid.UUID) (FederationConfigResponse, error)
- func (a *FederationAPI) ListConfigs(ctx context.Context, page PageRequest) (Page[FederationConfigResponse], error)
- func (a *FederationAPI) ListConfigsAll(ctx context.Context, start PageRequest) ([]FederationConfigResponse, error)
- func (a *FederationAPI) ListUserLinks(ctx context.Context, userID uuid.UUID) ([]FederationLinkResponse, error)
- func (a *FederationAPI) OIDCAuthorize(ctx context.Context, body OIDCAuthorizeRequest) (OIDCAuthorizeResponse, error)
- func (a *FederationAPI) OIDCCallback(ctx context.Context, body OIDCCallbackRequest) (OIDCCallbackResponse, error)
- func (a *FederationAPI) UpdateConfig(ctx context.Context, id uuid.UUID, body UpdateFederationConfigRequest) (FederationConfigResponse, error)
- type FederationConfigResponse
- type FederationLinkResponse
- type FederationProvider
- type FederationProviderList
- type FieldError
- type GeneratedCACertificate
- type GeneratedCertificate
- type GeneratedPGPKey
- type GrantPermissionRequest
- type GrantScopeConsent
- type GrantSpec
- type GrantedScope
- type Group
- type GroupSpec
- type GroupsAPI
- func (a *GroupsAPI) AddMember(ctx context.Context, groupID uuid.UUID, body AddMemberRequest) error
- func (a *GroupsAPI) AddServiceAccount(ctx context.Context, groupID uuid.UUID, body AddServiceAccountMemberRequest) error
- func (a *GroupsAPI) Create(ctx context.Context, body CreateGroupRequest) (Group, error)
- func (a *GroupsAPI) Delete(ctx context.Context, groupID uuid.UUID) error
- func (a *GroupsAPI) Get(ctx context.Context, groupID uuid.UUID) (Group, error)
- func (a *GroupsAPI) List(ctx context.Context, page PageRequest) (Page[Group], error)
- func (a *GroupsAPI) ListAll(ctx context.Context, start PageRequest) ([]Group, error)
- func (a *GroupsAPI) ListMembers(ctx context.Context, groupID uuid.UUID, page PageRequest) (Page[UserResponse], error)
- func (a *GroupsAPI) ListMembersAll(ctx context.Context, groupID uuid.UUID, start PageRequest) ([]UserResponse, error)
- func (a *GroupsAPI) ListRoles(ctx context.Context, groupID uuid.UUID) ([]RoleAssignment, error)
- func (a *GroupsAPI) ListServiceAccounts(ctx context.Context, groupID uuid.UUID, page PageRequest) (Page[ServiceAccountResponse], error)
- func (a *GroupsAPI) ListServiceAccountsAll(ctx context.Context, groupID uuid.UUID, start PageRequest) ([]ServiceAccountResponse, error)
- func (a *GroupsAPI) RemoveMember(ctx context.Context, groupID uuid.UUID, userID uuid.UUID) error
- func (a *GroupsAPI) RemoveServiceAccount(ctx context.Context, groupID uuid.UUID, serviceAccountID uuid.UUID) error
- func (a *GroupsAPI) Update(ctx context.Context, groupID uuid.UUID, body UpdateGroup) (Group, error)
- type HealthResponse
- type IDTokenClaims
- type IDTokenFailureReason
- type ImportCACertificateRequest
- type IntrospectParams
- type IntrospectionResult
- type JWKSVerifier
- type KeyAlgorithm
- type LockoutPolicy
- type LoginClientCredentialsParams
- type LoginResult
- type LogoutURLParams
- type MDSRefreshOutcome
- type MDSStatusResponse
- type MFAMethodResponse
- type MFAMethodType
- type MFAPolicy
- type MTLSTrustAnchorResponse
- type ManagementManifest
- type ManagementPlan
- type ManifestAPI
- type ManifestBuilder
- func (b *ManifestBuilder) AddToGroup(userKey, groupKey string) *ManifestBuilder
- func (b *ManifestBuilder) AssignRole(userKey, roleKey string) *ManifestBuilder
- func (b *ManifestBuilder) Build() (ManagementManifest, error)
- func (b *ManifestBuilder) ChildResource(key, name, resourceType, parentKey string) *ManifestBuilder
- func (b *ManifestBuilder) GlobalRole(key, name, description string) *ManifestBuilder
- func (b *ManifestBuilder) Grant(roleKey, permissionKey, effect string, scopeKeys ...string) *ManifestBuilder
- func (b *ManifestBuilder) Group(key, name, description string, roleKeys ...string) *ManifestBuilder
- func (b *ManifestBuilder) Permission(key, action, description string) *ManifestBuilder
- func (b *ManifestBuilder) Resource(key, name, resourceType string) *ManifestBuilder
- func (b *ManifestBuilder) Role(key, name, description string) *ManifestBuilder
- func (b *ManifestBuilder) Scope(resourceKey, key, name, description string) *ManifestBuilder
- func (b *ManifestBuilder) User(key, username, email string, initialPassword Sensitive) *ManifestBuilder
- type ManifestFailure
- type MemoryOidcStateStore
- type MfaEnrollment
- type MigrateCustodyResponse
- type MtlsEndpointAliases
- type NetworkError
- type NotFoundError
- type NotificationEventType
- type NotificationPolicy
- type NotificationRuleResponse
- type NotificationRulesAPI
- func (a *NotificationRulesAPI) Create(ctx context.Context, body CreateNotificationRuleRequest) (NotificationRuleResponse, error)
- func (a *NotificationRulesAPI) Delete(ctx context.Context, id uuid.UUID) error
- func (a *NotificationRulesAPI) Get(ctx context.Context, id uuid.UUID) (NotificationRuleResponse, error)
- func (a *NotificationRulesAPI) List(ctx context.Context, page PageRequest) (Page[NotificationRuleResponse], error)
- func (a *NotificationRulesAPI) ListAll(ctx context.Context, start PageRequest) ([]NotificationRuleResponse, error)
- func (a *NotificationRulesAPI) Update(ctx context.Context, id uuid.UUID, body UpdateNotificationRuleRequest) (NotificationRuleResponse, error)
- type OAuth2ClientCreatedResponse
- type OAuth2ClientResponse
- type OAuth2ClientsAPI
- func (a *OAuth2ClientsAPI) Create(ctx context.Context, body CreateOAuth2ClientRequest) (OAuth2ClientCreatedResponse, error)
- func (a *OAuth2ClientsAPI) Delete(ctx context.Context, id uuid.UUID) error
- func (a *OAuth2ClientsAPI) Get(ctx context.Context, id uuid.UUID) (OAuth2ClientResponse, error)
- func (a *OAuth2ClientsAPI) List(ctx context.Context, page PageRequest) (Page[OAuth2ClientResponse], error)
- func (a *OAuth2ClientsAPI) ListAll(ctx context.Context, start PageRequest) ([]OAuth2ClientResponse, error)
- func (a *OAuth2ClientsAPI) Update(ctx context.Context, id uuid.UUID, body UpdateOAuth2ClientRequest) (OAuth2ClientResponse, error)
- type OAuthProtocolError
- type OIDCAuthorizeRequest
- type OIDCAuthorizeResponse
- type OIDCCallbackRequest
- type OIDCCallbackResponse
- type OIDCPolicy
- type OidcBeginParams
- type OidcConfiguration
- type OidcExchangeParams
- type OidcParParams
- type OidcRefreshParams
- type OidcStateEntry
- type OidcStateStore
- type OidcTokenSet
- type OpaqueEnrollment
- type OpaqueEnrollmentPayload
- type OpaqueKsfParams
- type OpaquePolicy
- type Option
- func WithClientCertificate(certPEM, keyPEM []byte) Option
- func WithCustomCA(pem []byte) Option
- func WithDecisionMemoTTL(ttl time.Duration) Option
- func WithHTTPClient(hc *http.Client) Option
- func WithLogger(logger *slog.Logger) Option
- func WithOidcClientID(clientID string) Option
- func WithOidcClientSecret(clientSecret string) Option
- func WithOidcClockSkew(seconds int) Option
- func WithOidcDiscoveryTTL(ttl time.Duration) Option
- func WithOrgID(id uuid.UUID) Option
- func WithOrgSlug(slug string) Option
- func WithRetryDisabled() Option
- func WithTelemetryHook(hook TelemetryHook) Option
- func WithTimeout(d time.Duration) Option
- type Organization
- type OrganizationsAPI
- func (a *OrganizationsAPI) Get(ctx context.Context) (Organization, error)
- func (a *OrganizationsAPI) InOrg(orgID uuid.UUID) *OrganizationsAPI
- func (a *OrganizationsAPI) List(ctx context.Context, page PageRequest) (Page[Organization], error)
- func (a *OrganizationsAPI) ListAll(ctx context.Context, start PageRequest) ([]Organization, error)
- func (a *OrganizationsAPI) Update(ctx context.Context, body UpdateOrganizationRequest) (Organization, error)
- type Outcome
- type PGPKey
- type PGPKeyAlgorithm
- type PGPKeyPurpose
- type PGPKeyStatus
- type PGPKeysAPI
- func (a *PGPKeysAPI) Encrypt(ctx context.Context, id uuid.UUID, body EncryptRequest) (EncryptedExport, error)
- func (a *PGPKeysAPI) Generate(ctx context.Context, body CreatePGPKeyRequest) (GeneratedPGPKey, error)
- func (a *PGPKeysAPI) Get(ctx context.Context, id uuid.UUID) (PGPKey, error)
- func (a *PGPKeysAPI) List(ctx context.Context, page PageRequest) (Page[PGPKey], error)
- func (a *PGPKeysAPI) ListAll(ctx context.Context, start PageRequest) ([]PGPKey, error)
- func (a *PGPKeysAPI) Revoke(ctx context.Context, id uuid.UUID) error
- func (a *PGPKeysAPI) SignAuditBatch(ctx context.Context, body SignAuditBatchRequest) (SignedAuditBatch, error)
- type Page
- type PageRequest
- type PasswordPolicy
- type PasswordResetConfirmation
- type PasswordResetContext
- type PasswordResetRequest
- type Permission
- type PermissionEffect
- type PermissionSpec
- type PermissionsAPI
- func (a *PermissionsAPI) Create(ctx context.Context, body CreatePermissionRequest) (Permission, error)
- func (a *PermissionsAPI) Delete(ctx context.Context, permissionID uuid.UUID) error
- func (a *PermissionsAPI) Get(ctx context.Context, permissionID uuid.UUID) (Permission, error)
- func (a *PermissionsAPI) List(ctx context.Context, page PageRequest) (Page[Permission], error)
- func (a *PermissionsAPI) ListAll(ctx context.Context, start PageRequest) ([]Permission, error)
- func (a *PermissionsAPI) Update(ctx context.Context, permissionID uuid.UUID, body UpdatePermissionRequest) (Permission, error)
- type PlannedAction
- type PlatformAPI
- func (a *PlatformAPI) Health(ctx context.Context) (HealthResponse, error)
- func (a *PlatformAPI) MDSRefresh(ctx context.Context) (MDSRefreshOutcome, error)
- func (a *PlatformAPI) MDSStatus(ctx context.Context) (MDSStatusResponse, error)
- func (a *PlatformAPI) Ready(ctx context.Context) (ReadyResponse, error)
- type PolicyResponse
- type PresentedProofs
- type PrivacyAPI
- func (a *PrivacyAPI) CancelDelete(ctx context.Context, token string) error
- func (a *PrivacyAPI) DownloadExport(ctx context.Context, token string) error
- func (a *PrivacyAPI) GrantScopeConsent(ctx context.Context, body GrantScopeConsent) error
- func (a *PrivacyAPI) ListConsents(ctx context.Context) ([]ConsentView, error)
- func (a *PrivacyAPI) RequestDelete(ctx context.Context, body any) error
- func (a *PrivacyAPI) RequestExport(ctx context.Context, body any) error
- func (a *PrivacyAPI) WithdrawScopeConsent(ctx context.Context, clientID string) error
- type PrivacyPolicy
- type ProviderConfig
- type PushedAuthorizationRequest
- type ReactorEventDescriptor
- type ReactorMode
- type ReactorResponse
- type ReactorsAPI
- func (a *ReactorsAPI) Create(ctx context.Context, body CreateReactorRequest) (ReactorResponse, error)
- func (a *ReactorsAPI) Delete(ctx context.Context, id uuid.UUID) error
- func (a *ReactorsAPI) Get(ctx context.Context, id uuid.UUID) (ReactorResponse, error)
- func (a *ReactorsAPI) List(ctx context.Context, page PageRequest) (Page[ReactorResponse], error)
- func (a *ReactorsAPI) ListAll(ctx context.Context, start PageRequest) ([]ReactorResponse, error)
- func (a *ReactorsAPI) ListEvents(ctx context.Context) ([]ReactorEventDescriptor, error)
- func (a *ReactorsAPI) Update(ctx context.Context, id uuid.UUID, body UpdateReactorRequest) (ReactorResponse, error)
- type ReadyResponse
- type RefreshEvent
- type RefreshRole
- type RequestEndEvent
- type RequestStartEvent
- type RequestedPermission
- type RequestingPartyToken
- type ResolvedPermissionGrant
- type Resource
- type ResourceSet
- type ResourceSpec
- type ResourcesAPI
- func (a *ResourcesAPI) Create(ctx context.Context, body CreateResourceRequest) (Resource, error)
- func (a *ResourcesAPI) Delete(ctx context.Context, resourceID uuid.UUID) error
- func (a *ResourcesAPI) Get(ctx context.Context, resourceID uuid.UUID) (Resource, error)
- func (a *ResourcesAPI) List(ctx context.Context, page PageRequest) (Page[Resource], error)
- func (a *ResourcesAPI) ListAll(ctx context.Context, start PageRequest) ([]Resource, error)
- func (a *ResourcesAPI) ListAncestors(ctx context.Context, resourceID uuid.UUID) ([]Resource, error)
- func (a *ResourcesAPI) ListChildren(ctx context.Context, resourceID uuid.UUID) ([]Resource, error)
- func (a *ResourcesAPI) Update(ctx context.Context, resourceID uuid.UUID, body UpdateResourceRequest) (Resource, error)
- type RetryEvent
- type RetryPolicy
- type RevocationFeed
- type RevokeParams
- type Role
- type RoleAssignment
- type RoleGroupAssignment
- type RoleServiceAccountAssignment
- type RoleSpec
- type RoleUserAssignment
- type RolesAPI
- func (a *RolesAPI) AssignToGroup(ctx context.Context, roleID uuid.UUID, body AssignRoleToGroupRequest) error
- func (a *RolesAPI) AssignToServiceAccount(ctx context.Context, roleID uuid.UUID, body AssignRoleToServiceAccountRequest) error
- func (a *RolesAPI) AssignToUser(ctx context.Context, roleID uuid.UUID, body AssignRoleToUserRequest) error
- func (a *RolesAPI) Create(ctx context.Context, body CreateRoleRequest) (Role, error)
- func (a *RolesAPI) Delete(ctx context.Context, roleID uuid.UUID) error
- func (a *RolesAPI) Get(ctx context.Context, roleID uuid.UUID) (Role, error)
- func (a *RolesAPI) GrantPermission(ctx context.Context, roleID uuid.UUID, body GrantPermissionRequest) error
- func (a *RolesAPI) List(ctx context.Context, page PageRequest) (Page[Role], error)
- func (a *RolesAPI) ListAll(ctx context.Context, start PageRequest) ([]Role, error)
- func (a *RolesAPI) ListGroups(ctx context.Context, roleID uuid.UUID) ([]RoleGroupAssignment, error)
- func (a *RolesAPI) ListPermissions(ctx context.Context, roleID uuid.UUID) ([]ResolvedPermissionGrant, error)
- func (a *RolesAPI) ListServiceAccounts(ctx context.Context, roleID uuid.UUID) ([]RoleServiceAccountAssignment, error)
- func (a *RolesAPI) ListUsers(ctx context.Context, roleID uuid.UUID) ([]RoleUserAssignment, error)
- func (a *RolesAPI) RevokePermission(ctx context.Context, roleID uuid.UUID, permissionID uuid.UUID) error
- func (a *RolesAPI) UnassignFromGroup(ctx context.Context, roleID uuid.UUID, groupID uuid.UUID, resourceID string) error
- func (a *RolesAPI) UnassignFromServiceAccount(ctx context.Context, roleID uuid.UUID, serviceAccountID uuid.UUID, ...) error
- func (a *RolesAPI) UnassignFromUser(ctx context.Context, roleID uuid.UUID, userID uuid.UUID, resourceID string) error
- func (a *RolesAPI) Update(ctx context.Context, roleID uuid.UUID, body UpdateRole) (Role, error)
- type RotateSecretResponse
- type RptPermission
- type SCIMTokenResponse
- type SCIMTokenStatus
- type SCIMTokensAPI
- type SMTPConfig
- type Scope
- type ScopeSpec
- type ScopesAPI
- func (a *ScopesAPI) Create(ctx context.Context, resourceID uuid.UUID, body CreateScopeRequest) (Scope, error)
- func (a *ScopesAPI) Delete(ctx context.Context, resourceID uuid.UUID, scopeID uuid.UUID) error
- func (a *ScopesAPI) Get(ctx context.Context, resourceID uuid.UUID, scopeID uuid.UUID) (Scope, error)
- func (a *ScopesAPI) List(ctx context.Context, resourceID uuid.UUID) ([]Scope, error)
- func (a *ScopesAPI) Update(ctx context.Context, resourceID uuid.UUID, scopeID uuid.UUID, ...) (Scope, error)
- type SecuritySettings
- type Sensitive
- type ServiceAccountCreatedResponse
- type ServiceAccountResponse
- type ServiceAccountsAPI
- func (a *ServiceAccountsAPI) BindCertificate(ctx context.Context, saID uuid.UUID, body BindCertificate) error
- func (a *ServiceAccountsAPI) Create(ctx context.Context, body CreateServiceAccountRequest) (ServiceAccountCreatedResponse, error)
- func (a *ServiceAccountsAPI) Delete(ctx context.Context, saID uuid.UUID) error
- func (a *ServiceAccountsAPI) Get(ctx context.Context, saID uuid.UUID) (ServiceAccountResponse, error)
- func (a *ServiceAccountsAPI) List(ctx context.Context, page PageRequest) (Page[ServiceAccountResponse], error)
- func (a *ServiceAccountsAPI) ListAll(ctx context.Context, start PageRequest) ([]ServiceAccountResponse, error)
- func (a *ServiceAccountsAPI) ListGroups(ctx context.Context, serviceAccountID uuid.UUID) ([]Group, error)
- func (a *ServiceAccountsAPI) ListRoles(ctx context.Context, serviceAccountID uuid.UUID) ([]RoleAssignment, error)
- func (a *ServiceAccountsAPI) RotateSecret(ctx context.Context, saID uuid.UUID) (RotateSecretResponse, error)
- func (a *ServiceAccountsAPI) Update(ctx context.Context, saID uuid.UUID, body UpdateServiceAccount) (ServiceAccountResponse, error)
- type SessionResponse
- type SetMTLSTrustAnchor
- type SetOrgEmailConfig
- type SetOrgSettings
- type SettingsAPI
- func (a *SettingsAPI) DeleteTenantOverride(ctx context.Context) error
- func (a *SettingsAPI) ForTenant(tenantID uuid.UUID) *SettingsAPI
- func (a *SettingsAPI) GetEffective(ctx context.Context) (SecuritySettings, error)
- func (a *SettingsAPI) GetOrg(ctx context.Context) (SecuritySettings, error)
- func (a *SettingsAPI) GetTenantOverride(ctx context.Context) (TenantSettingsOverride, error)
- func (a *SettingsAPI) InOrg(orgID uuid.UUID) *SettingsAPI
- func (a *SettingsAPI) SetEffective(ctx context.Context, body TenantSettingsOverride) (SecuritySettings, error)
- func (a *SettingsAPI) SetOrg(ctx context.Context, body SetOrgSettings) (SecuritySettings, error)
- func (a *SettingsAPI) SetTenantOverride(ctx context.Context, body TenantSettingsOverride) (TenantSettingsOverride, error)
- type SettingsScope
- type SignAuditBatchRequest
- type SignIntermediateCSRRequest
- type SignedAuditBatch
- type SsoCompleteHandoffParams
- type SsoCompleteOauth2Params
- type SsoCompleteParams
- type SsoCompleteResult
- type SsoProvidersParams
- type SsoStartOauth2Params
- type SsoStartParams
- type SsoStartResult
- type Status
- type StepOutcome
- type Target
- type TelemetryEvent
- type TelemetryHook
- type Tenant
- type TenantKind
- type TenantSettingsOverride
- type TenantStatus
- type TenantsAPI
- func (a *TenantsAPI) Create(ctx context.Context, body CreateTenantRequest) (Tenant, error)
- func (a *TenantsAPI) Delete(ctx context.Context, tenantID uuid.UUID) error
- func (a *TenantsAPI) ExportAudit(ctx context.Context, tenantID uuid.UUID) error
- func (a *TenantsAPI) Get(ctx context.Context, tenantID uuid.UUID) (Tenant, error)
- func (a *TenantsAPI) InOrg(orgID uuid.UUID) *TenantsAPI
- func (a *TenantsAPI) List(ctx context.Context, page PageRequest) (Page[Tenant], error)
- func (a *TenantsAPI) ListAll(ctx context.Context, start PageRequest) ([]Tenant, error)
- func (a *TenantsAPI) Update(ctx context.Context, tenantID uuid.UUID, body UpdateTenant) (Tenant, error)
- type TokenExchangeParams
- type TokenExchangeTrustRequest
- type TokenExchangeTrustResponse
- type TokenPolicy
- type TokenValidationOptions
- type UmaChallenge
- type UmaExchangeTicketParams
- type UnknownAAGUIDAction
- type UpdateFederationConfigRequest
- type UpdateGroup
- type UpdateNotificationRuleRequest
- type UpdateOAuth2ClientRequest
- type UpdateOrganizationRequest
- type UpdatePermissionRequest
- type UpdateReactorRequest
- type UpdateResourceRequest
- type UpdateRole
- type UpdateScopeRequest
- type UpdateServiceAccount
- type UpdateTenant
- type UpdateUserRequest
- type UpdateWebhookRequest
- type UserResponse
- type UserSpec
- type UserStatus
- type UsersAPI
- func (a *UsersAPI) Create(ctx context.Context, body CreateUserRequest) (UserResponse, error)
- func (a *UsersAPI) Delete(ctx context.Context, userID uuid.UUID) error
- func (a *UsersAPI) DeleteMFAMethod(ctx context.Context, userID uuid.UUID, methodID string) error
- func (a *UsersAPI) Get(ctx context.Context, userID uuid.UUID) (UserResponse, error)
- func (a *UsersAPI) List(ctx context.Context, page PageRequest) (Page[UserResponse], error)
- func (a *UsersAPI) ListAll(ctx context.Context, start PageRequest) ([]UserResponse, error)
- func (a *UsersAPI) ListMFAMethods(ctx context.Context, userID uuid.UUID) ([]MFAMethodResponse, error)
- func (a *UsersAPI) ListRoles(ctx context.Context, userID uuid.UUID) ([]RoleAssignment, error)
- func (a *UsersAPI) ListSessions(ctx context.Context, userID uuid.UUID) ([]SessionResponse, error)
- func (a *UsersAPI) ResetMFA(ctx context.Context, userID uuid.UUID) error
- func (a *UsersAPI) Unlock(ctx context.Context, userID uuid.UUID) (UserResponse, error)
- func (a *UsersAPI) Update(ctx context.Context, userID uuid.UUID, body UpdateUserRequest) (UserResponse, error)
- type ValidationError
- type VerifiedLogoutToken
- type WebauthnAttestationPolicy
- type WebauthnChallenge
- type WebauthnCredential
- type WebauthnFailure
- type WebauthnLoginResult
- type WebauthnPolicy
- type WebauthnPolicyAPI
- func (a *WebauthnPolicyAPI) ComplianceReport(ctx context.Context) ([]ComplianceReportEntry, error)
- func (a *WebauthnPolicyAPI) ForTenant(tenantID uuid.UUID) *WebauthnPolicyAPI
- func (a *WebauthnPolicyAPI) Get(ctx context.Context) (PolicyResponse, error)
- func (a *WebauthnPolicyAPI) Set(ctx context.Context, body WebauthnAttestationPolicy) (WebauthnAttestationPolicy, error)
- type WebauthnWorkspace
- type WebhookResponse
- type WebhooksAPI
- func (a *WebhooksAPI) Create(ctx context.Context, body CreateWebhookRequest) (WebhookResponse, error)
- func (a *WebhooksAPI) Delete(ctx context.Context, id uuid.UUID) error
- func (a *WebhooksAPI) Get(ctx context.Context, id uuid.UUID) (WebhookResponse, error)
- func (a *WebhooksAPI) List(ctx context.Context, page PageRequest) (Page[WebhookResponse], error)
- func (a *WebhooksAPI) ListAll(ctx context.Context, start PageRequest) ([]WebhookResponse, error)
- func (a *WebhooksAPI) Update(ctx context.Context, id uuid.UUID, body UpdateWebhookRequest) (WebhookResponse, error)
Constants ¶
const ( // ReasonCodeAllowed: an allow grant matched and no deny did. ReasonCodeAllowed = "allowed" // ReasonCodeNoGrant: nothing matched — default deny. Ask an admin for // access. ReasonCodeNoGrant = "no_grant" // ReasonCodeDeniedByRule: an explicit deny rule matched and overrode any // allow. An admin has already decided. ReasonCodeDeniedByRule = "denied_by_rule" )
The three reason_code values CONTRACT.md §11 rule 9 defines.
Untyped string constants rather than a named type, so an unrecognised server value is still a valid AccessResult.ReasonCode and reaches the caller — a closed type would tempt the SDK to drop what it cannot name.
const ( // RevocationFeedMinPollInterval is the shortest interval a caller may // configure; a smaller one is clamped up to it, never refused (§10.4 // rule 2). RevocationFeedMinPollInterval = revocation.MinPollInterval // RevocationFeedDefaultPollInterval is the interval §10.4 recommends. RevocationFeedDefaultPollInterval = revocation.DefaultPollInterval // RevocationFeedMaxEntries bounds the cached set. An over-sized document // is treated as unusable rather than truncated: a truncated set is a guard // that admits some revoked sessions and reports none. RevocationFeedMaxEntries = revocation.MaxEntries )
const ( // DefaultDevicePollInterval is the polling interval used when the // authorization response omits `interval` (RFC 8628 §3.2, §14.2 rule 2). // An SDK MUST NOT hard-code a faster floor. DefaultDevicePollInterval = 5 * time.Second // SlowDownIncrement is added to the polling interval on each `slow_down` // (§14.2 rule 1). The increase is permanent and cumulative. SlowDownIncrement = 5 * time.Second )
const ( // SubjectTokenTypeAccessToken is an AXIAM-issued access token — the // same-domain exchange of §15.1. Name it explicitly; there is no default. SubjectTokenTypeAccessToken = "urn:ietf:params:oauth:token-type:access_token" // SubjectTokenTypeJWT is a JWT from a trusted external issuer — the // cross-domain exchange of §15.7. AXIAM also accepts // SubjectTokenTypeAccessToken for an external issuer. SubjectTokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt" )
The subject_token_type values AXIAM accepts, for TokenExchangeParams.SubjectTokenType (CONTRACT.md §15.7).
Named constants because the difference between these two URNs and a typo'd one is an invalid_request the caller has to go read RFC 8693 to decode.
const ( // ProtocolOidcConnect selects SsoStart. ProtocolOidcConnect = "OidcConnect" // ProtocolOAuth2 selects SsoStartOauth2. ProtocolOAuth2 = "OAuth2" // ProtocolSaml selects the SAML login endpoint, which is NOT a §12 // vocabulary operation. ProtocolSaml = "Saml" )
Protocol values a FederationProvider may carry (CONTRACT.md §12.1 note 10). The value — not ProviderKind, which is branding — selects which start operation to call.
const ( // MaxAttempts is the §16.1 attempt cap: 1 initial + 2 retries. MaxAttempts = 3 // BaseDelay is the §16.1 first backoff step. BaseDelay = 200 * time.Millisecond // MaxDelay is the §16.1 ceiling on any single computed backoff. MaxDelay = 5 * time.Second )
const ClockSkewLeeway = jwks.ClockSkewLeeway
ClockSkewLeeway is the named, bounded clock-skew allowance this SDK applies to the exp and nbf checks (CONTRACT.md §10.1 rule 7). It is a constant and is deliberately NOT operator-configurable.
const DPoPIatLeeway = dpop.IatLeeway
DPoPIatLeeway is the "iat" freshness window, applied in both directions.
const HandoffCodeTTL = 60 * time.Second
HandoffCodeTTL is how long a handoff code is valid (§12.1 note 12). It exists to survive one redirect. Redeem it immediately, once.
const HandoffQueryParam = "axiam_handoff"
HandoffQueryParam is the query parameter the server delivers a handoff code in, on the SPA's own callback URL (CONTRACT.md §12.1 note 12).
const MaxIDTokenClockSkewSec = 60
MaxIDTokenClockSkewSec is the CONTRACT.md §12.4 rule 5 ceiling for permitted ID-token clock skew: 60 seconds. WithOidcClockSkew clamps any larger configured value down to this ceiling; it is also the default when unconfigured.
const MaxMemoTTL = 5 * time.Second
MaxMemoTTL is the §17.1 rule 2 ceiling. A configured TTL above this is clamped, not rejected: a caller who asked for a minute wants caching, and silently giving them the maximum safe value beats failing construction.
const MinGoVersion = "1.26"
MinGoVersion is the minimum Go language version this module supports, as major.minor.
It mirrors the `go` directive in go.mod. Go's toolchain enforces that directive at build time, but a consumer has no way to read it back at run time — `debug.ReadBuildInfo` reports the toolchain that produced the binary and the module graph, never a dependency's declared language version. This constant is the readable half, so a deployment preflight or a startup assertion can compare the two without hardcoding a number that goes stale.
The value is verified against go.mod by version_policy_test.go, so the two cannot drift.
The module is built and tested against this version and against the current Go release; Go supports exactly the two most recent majors, so that pair is the whole supported range. See examples/version-compatibility.
const MinOidcDiscoveryTTL = 5 * time.Minute
MinOidcDiscoveryTTL is the CONTRACT.md §12.3 rule 6 FLOOR for the OIDC discovery-document cache TTL: 5 minutes. WithOidcDiscoveryTTL raises any smaller configured value up to this floor; it is also the default when unconfigured.
const OidcStateTTL = 10 * time.Minute
OidcStateTTL is the contract-mandated MAXIMUM TTL for stored login state: 10 minutes, matching the server's federation_login_state row lifetime (D-22, CONTRACT.md §12.3 rule 1).
const ( // UmaProtectionScope is the scope a PAT must carry (§20.2 rule 1) — for // callers minting one through LoginClientCredentials. UmaProtectionScope = "uma_protection" )
Variables ¶
var ( ErrAuth = errors.New("axiam: authentication error") ErrAuthz = errors.New("axiam: authorization error") ErrNetwork = errors.New("axiam: network error") )
Sentinel errors for errors.Is-based discrimination convenience (CONTRACT.md §2, D-04). These are never returned directly — only *AuthError/*AuthzError/*NetworkError instances are, each of which implements Is(target) to match the corresponding sentinel.
var ( ErrUnverifiableConfirmation = jwks.ErrUnverifiableConfirmation ErrNoClientCertificate = jwks.ErrNoClientCertificate ErrCertificateBindingMismatch = jwks.ErrCertificateBindingMismatch ErrNoDPoPProof = jwks.ErrNoDPoPProof ErrDPoPBindingMismatch = jwks.ErrDPoPBindingMismatch )
Rule 9 sentinel errors, for guards that distinguish "nothing was presented" from "what was presented was wrong".
var ( // ErrNotFound matches any *NotFoundError. Also matches ErrAuthz. ErrNotFound = fmt.Errorf("axiam: management resource not found") // ErrConflict matches any *ConflictError. Also matches ErrAuthz. ErrConflict = fmt.Errorf("axiam: management conflict") // ErrValidation matches any *ValidationError. Also matches ErrNetwork. ErrValidation = fmt.Errorf("axiam: management request rejected") )
Sentinel errors for the §27 sub-types, for errors.Is discrimination alongside the §2 sentinels they also match.
var CertificateThumbprintS256 = jwks.CertificateThumbprintS256
CertificateThumbprintS256 computes the RFC 8705 §3.1 "x5t#S256" of a DER client certificate.
var NewInMemoryDPoPJtiStore = dpop.NewInMemoryJtiStore
NewInMemoryDPoPJtiStore returns a single-process replay guard. Per-process, therefore per-instance: a multi-replica deployment needs a shared store.
var VerifyCertificateBinding = jwks.VerifyCertificateBinding
VerifyCertificateBinding applies rule 9 for certificate-bound tokens only.
It REFUSES a DPoP-bound or both-bound token rather than ignoring the half it cannot check — that refusal is what lets this narrower entry point stay in the API without becoming a downgrade path.
var VerifyDPoPProof = dpop.VerifyProof
VerifyDPoPProof performs all ten §21.7.2 checks and returns the proof key's RFC 7638 thumbprint — exactly the value PresentedProofs.DPoPThumbprint expects, so a guard can only pass on a thumbprint that came from a proof which actually verified.
var VerifyTokenBinding = jwks.VerifyTokenBinding
VerifyTokenBinding applies §10.1 rule 9 in full — the token's sender constraint against every proof the caller presented.
Prefer this over VerifyCertificateBinding unless the transport genuinely cannot produce a DPoP thumbprint. An unbound token is accepted with no proofs at all, so adopting it breaks no existing deployment.
Functions ¶
func RevocationEntryFor ¶
RevocationEntryFor is the feed entry for a sid, as the server computes it: base64url without padding over the SHA-256 of the claim's EXACT string.
Never a parsed-and-re-rendered UUID — the answer would then depend on this SDK's UUID parser rather than on the feed.
func UmaChallengeHeader ¶
UmaChallengeHeader formats a `WWW-Authenticate: UMA` header value (§20.3, emit half) — for a resource server that has just minted a ticket and wants to tell the caller where to redeem it.
func WebauthnErrorMessage ¶
func WebauthnErrorMessage(failure WebauthnFailure) string
WebauthnErrorMessage returns copy for a failure, safe to show a user.
The cancelled string deliberately does not accuse anyone of cancelling: the same classification covers a silent timeout, and the spec will not say which happened.
Types ¶
type APIProviderConfig ¶
type APIProviderConfig struct {
// APIURL Override base URL (useful for testing / self-hosted instances).
APIURL *string `json:"api_url,omitempty"`
}
APIProviderConfig API-based provider configuration (SendGrid, Postmark, Resend, Brevo). `api_key` follows the same write-only + omit-preserving contract as [`SmtpConfig::password`] (D-01/D-02).
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type AccessCheck ¶
type AccessCheck struct {
Action string `json:"action"`
ResourceID string `json:"resource_id"`
Scope string `json:"scope,omitempty"`
// SubjectID is optional and, when set, asks the server to evaluate the
// check for this subject rather than the caller's own session
// (CONTRACT.md §11.2 — declarative authorization helpers pass the
// request's authenticated user_id here so the check runs for the end
// user, not the application's own service-account session). Omitted
// from the wire payload when empty, preserving today's request shape
// for CheckAccess/Can/BatchCheck callers that never set it.
SubjectID string `json:"subject_id,omitempty"`
}
AccessCheck is a single access check request (CONTRACT.md §1). ResourceID is a string (server-side UUID) rather than a typed UUID so callers can pass either a UUID string or, in future, other resource-id encodings without a breaking type change; the server is the source of truth for validation.
type AccessResult ¶
type AccessResult struct {
// Allowed reports whether the checked action is permitted.
//
// THIS FIELD ALONE CARRIES THE OUTCOME. ReasonCode explains it and never
// contradicts it.
Allowed bool `json:"allowed"`
// Reason is the server's human-readable explanation, when it sent one.
Reason string `json:"reason,omitempty"`
// ReasonCode is the machine-readable decision reason (CONTRACT.md §11
// rule 9, B1 deny-override): ReasonCodeAllowed, ReasonCodeNoGrant or
// ReasonCodeDeniedByRule.
//
// THE TWO REFUSALS MEAN OPPOSITE THINGS to the person on the other end.
// no_grant says "ask an admin for access"; denied_by_rule says "an admin
// has already decided". An application that cannot tell them apart sends
// users to raise tickets that will be refused — which is why the contract
// forbids collapsing them into a bare false.
//
// Empty when the server omits the field: a newer SDK against an older
// server treats it as absent, never as an error. An unrecognised value is
// surfaced verbatim and never changes Allowed — which is why this is a
// plain string rather than a defined type with a closed set of constants.
ReasonCode string `json:"reason_code,omitempty"`
}
AccessResult is the outcome of a single access check (mirrors CheckAccessResponse).
type ActorType ¶
type ActorType string
ActorType is a ActorType value from the server's schema.
const ( ActorTypeUser ActorType = "User" ActorTypeServiceAccount ActorType = "ServiceAccount" ActorTypeSystem ActorType = "System" )
The ActorType values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type AddMemberRequest ¶
type AddMemberRequest struct {
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
AddMemberRequest is the AddMemberRequest schema from the server's OpenAPI document.
type AddServiceAccountMemberRequest ¶
type AddServiceAccountMemberRequest struct {
// ServiceAccountID carries the server's service_account_id field.
ServiceAccountID uuid.UUID `json:"service_account_id"`
}
AddServiceAccountMemberRequest is the AddServiceAccountMemberRequest schema from the server's OpenAPI document.
type AppliedStep ¶
type AppliedStep struct {
// Action is the step, exactly as Plan reported it.
Action PlannedAction
// Outcome is what actually happened when it ran — or did not.
Outcome StepOutcome
}
AppliedStep is one planned step paired with what became of it.
type ApplyReport ¶
type ApplyReport struct {
// Steps is each planned step paired with what became of it, in plan order.
Steps []AppliedStep
}
ApplyReport is the result of applying a manifest.
THERE IS NO TRANSACTION HERE AND THIS TYPE DOES NOT PRETEND THERE IS (§27.6 rule 7). These are independent HTTP endpoints; nothing spans them. If step 12 of 30 fails, steps 1–11 have happened and will not be undone — so every step's outcome is reported, execution stops at the first failure rather than continuing blindly, and there is no Rollback because this SDK could not honour one. Fix the cause and re-apply: rule 6's idempotence is what makes that safe.
func (ApplyReport) ChangedCount ¶
func (r ApplyReport) ChangedCount() int
ChangedCount reports how many steps actually changed something.
func (ApplyReport) Failure ¶
func (r ApplyReport) Failure() (ManifestFailure, bool)
Failure returns the failing step, if the apply stopped early.
func (ApplyReport) IsComplete ¶
func (r ApplyReport) IsComplete() bool
IsComplete reports whether every step that was meant to run did.
type AssignRoleToGroupRequest ¶
type AssignRoleToGroupRequest struct {
// GroupID carries the server's group_id field.
GroupID uuid.UUID `json:"group_id"`
// ResourceID carries the server's resource_id field.
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// TenantScope The tenants this assignment reaches. Only meaningful for an assignment
// made in an organization's scope, whose global roles otherwise reach
// every tenant of the organization; naming tenants here confines the
// assignment to those and to nothing else, the organization's own scope
// included. Omitted — the default — reaches wherever the role does.
// Refused with 400 outside an organization scope, when empty, and when it
// names a tenant of another organization or the organization's own scope
// tenant.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
}
AssignRoleToGroupRequest is the AssignRoleToGroupRequest schema from the server's OpenAPI document.
type AssignRoleToServiceAccountRequest ¶
type AssignRoleToServiceAccountRequest struct {
// ResourceID carries the server's resource_id field.
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// ServiceAccountID carries the server's service_account_id field.
ServiceAccountID uuid.UUID `json:"service_account_id"`
// TenantScope The tenants this assignment reaches. Only meaningful for an assignment
// made in an organization's scope, whose global roles otherwise reach
// every tenant of the organization; naming tenants here confines the
// assignment to those and to nothing else, the organization's own scope
// included. Omitted — the default — reaches wherever the role does.
// Refused with 400 outside an organization scope, when empty, and when it
// names a tenant of another organization or the organization's own scope
// tenant.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
}
AssignRoleToServiceAccountRequest is the AssignRoleToServiceAccountRequest schema from the server's OpenAPI document.
type AssignRoleToUserRequest ¶
type AssignRoleToUserRequest struct {
// ResourceID carries the server's resource_id field.
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// TenantScope The tenants this assignment reaches. Only meaningful for an assignment
// made in an organization's scope, whose global roles otherwise reach
// every tenant of the organization; naming tenants here confines the
// assignment to those and to nothing else, the organization's own scope
// included. Omitted — the default — reaches wherever the role does.
// Refused with 400 outside an organization scope, when empty, and when it
// names a tenant of another organization or the organization's own scope
// tenant.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
AssignRoleToUserRequest is the AssignRoleToUserRequest schema from the server's OpenAPI document.
type AttestationMode ¶
type AttestationMode string
AttestationMode What attestation conveyance a registration ceremony requests, and whether the policy is enforced at all. `None` is the default and reproduces today's behavior byte-for-byte: `evaluate` allows every registration unconditionally, with no MDS lookup (D8 step 1).
const ( AttestationModeNone AttestationMode = "none" AttestationModeIndirect AttestationMode = "indirect" AttestationModeDirectRequired AttestationMode = "direct_required" )
The AttestationMode values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type AuditAPI ¶
type AuditAPI struct {
// contains filtered or unexported fields
}
AuditAPI is the audit namespace handle.
Append-only audit log, read-only by construction.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*AuditAPI) List ¶
func (a *AuditAPI) List(ctx context.Context, filter AuditListFilter, page PageRequest) (Page[AuditLogEntry], error)
List issues GET /api/v1/audit-logs.
func (*AuditAPI) ListAll ¶
func (a *AuditAPI) ListAll(ctx context.Context, filter AuditListFilter, start PageRequest) ([]AuditLogEntry, error)
ListAll walks audit.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*AuditAPI) ListSystem ¶
func (a *AuditAPI) ListSystem(ctx context.Context, filter AuditListSystemFilter, page PageRequest) (Page[AuditLogEntry], error)
ListSystem issues GET /api/v1/audit-logs/system.
func (*AuditAPI) ListSystemAll ¶
func (a *AuditAPI) ListSystemAll(ctx context.Context, filter AuditListSystemFilter, start PageRequest) ([]AuditLogEntry, error)
ListSystemAll walks audit.list_system to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
type AuditListFilter ¶
type AuditListFilter struct {
// ActorID filters on actor_id. Empty means unset.
ActorID string
// Action filters on action. Empty means unset.
Action string
// Outcome filters on outcome. Empty means unset.
Outcome string
// ResourceID filters on resource_id. Empty means unset.
ResourceID string
// From filters on from. Empty means unset.
From string
// To filters on to. Empty means unset.
To string
}
AuditListFilter holds the optional filters for audit.list.
Six loose optional string arguments is a call site a reader cannot check and a refactor silently reorders, so they travel as one struct. A zero field is not sent.
type AuditListSystemFilter ¶
type AuditListSystemFilter struct {
// ActorID filters on actor_id. Empty means unset.
ActorID string
// Action filters on action. Empty means unset.
Action string
// Outcome filters on outcome. Empty means unset.
Outcome string
// ResourceID filters on resource_id. Empty means unset.
ResourceID string
// From filters on from. Empty means unset.
From string
// To filters on to. Empty means unset.
To string
}
AuditListSystemFilter holds the optional filters for audit.list_system.
Six loose optional string arguments is a call site a reader cannot check and a refactor silently reorders, so they travel as one struct. A zero field is not sent.
type AuditLogEntry ¶
type AuditLogEntry struct {
// Action carries the server's action field.
Action string `json:"action"`
// ActorID carries the server's actor_id field.
ActorID uuid.UUID `json:"actor_id"`
// ActorType carries the server's actor_type field.
ActorType ActorType `json:"actor_type"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IPAddress carries the server's ip_address field.
IPAddress *string `json:"ip_address,omitempty"`
// Metadata carries the server's metadata field.
Metadata any `json:"metadata"`
// Outcome carries the server's outcome field.
Outcome AuditOutcome `json:"outcome"`
// ResourceID carries the server's resource_id field.
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// Timestamp carries the server's timestamp field.
Timestamp string `json:"timestamp"`
}
AuditLogEntry is the AuditLogEntry schema from the server's OpenAPI document.
type AuditOutcome ¶
type AuditOutcome string
AuditOutcome is a AuditOutcome value from the server's schema.
const ( AuditOutcomeSuccess AuditOutcome = "Success" AuditOutcomeFailure AuditOutcome = "Failure" AuditOutcomeDenied AuditOutcome = "Denied" )
The AuditOutcome values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type AuthError ¶
type AuthError struct {
Message string
// Reason is an OPTIONAL stable, machine-readable failure code. It is
// populated for CONTRACT.md §12.4 ID-token validation failures — one of
// invalid_alg, unknown_kid, invalid_signature, invalid_issuer,
// invalid_audience, token_expired, nonce_mismatch (§12 T1 reference
// judgment call 2: the reason code rides on the EXISTING AuthError type
// via this additive field, rather than a second error class) — and left
// "" for every pre-existing AuthError construction site, which is fully
// backward compatible (§12 port addendum item 17).
Reason string
}
AuthError represents an authentication failure: wrong credentials, expired session, MFA failure, or a 401 on refresh (CONTRACT.md §2).
type AuthnRequestParamsMode ¶
type AuthnRequestParamsMode string
AuthnRequestParamsMode Whether this client's authorization requests may carry OpenID Connect's authentication-request parameters, or whether they are ignored (X7.1). The bundle this governs is `prompt`, `max_age`, `acr_values`, `claims`, `id_token_hint`, `login_hint`, `display`, `ui_locales` and `claims_locales`. It is **one** field rather than nine booleans for the same reason [`ClientProfile`] is one field rather than a dozen: a client that honours `max_age` but ignores `prompt=none` is not "mostly conformant", it is a client a relying party cannot reason about. [`Ignore`](Self::Ignore) is the serde default and is exactly what AXIAM has always done — unknown authorization-request parameters are dropped by the query deserialiser and never reach a decision. Every row written before schema v54 therefore decodes to the behaviour it already had.
const ( AuthnRequestParamsModeIgnore AuthnRequestParamsMode = "ignore" AuthnRequestParamsModeHonour AuthnRequestParamsMode = "honour" )
The AuthnRequestParamsMode values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type AuthorizationRequest ¶
type AuthorizationRequest struct {
// URL is the fully-built authorization URL to redirect the browser to.
URL string
// State is a CSPRNG CSRF value (>=128 bits, base64url unpadded) to
// compare against the `state` the IdP returns. Not a secret.
State string
// Nonce is a CSPRNG replay-protection value (>=128 bits) that must equal
// the ID token's `nonce` claim. Not a secret.
Nonce string
// CodeVerifier is the PKCE verifier, secret for its whole lifetime
// (§12.5). Pass it back into OidcExchange.
CodeVerifier Sensitive
}
AuthorizationRequest is the result of OidcBegin — everything the caller needs to start an authorization-code + PKCE login (CONTRACT.md §12.1).
The caller owns this state (§12.3 rule 1). The SDK stores nothing: persist State, Nonce and CodeVerifier in your own HTTP session (or via an OidcStateStore), redirect the browser to URL, and pass Nonce and CodeVerifier back into OidcExchange when the code arrives.
type AuthzError ¶
AuthzError represents an authorization failure: the caller is authenticated but lacks permission for the requested operation (CONTRACT.md §2). Action/ResourceID are optional and populated when known from the response body.
func (*AuthzError) Error ¶
func (e *AuthzError) Error() string
func (*AuthzError) Is ¶
func (e *AuthzError) Is(target error) bool
Is reports whether target is the ErrAuthz sentinel, enabling errors.Is(err, ErrAuthz) to match any *AuthzError.
type BindCertificate ¶
type BindCertificate struct {
// CertificateID carries the server's certificate_id field.
CertificateID uuid.UUID `json:"certificate_id"`
}
BindCertificate Request to bind a certificate to a service account.
type CACertificate ¶
type CACertificate struct {
// ChainPEM The issuers above [`Self::public_cert_pem`], concatenated PEM, nearest
// issuer first and the root last. `None` for a CA that is its own root,
// which is every CA AXIAM generated before Vault's PKI engine was an
// option. Present for a `vault_pki` CA, where it is the only copy of the
// root certificate anything outside Vault will ever see — a relying
// party cannot validate an AXIAM-issued leaf without it, and
// `root/generate/internal` returns it exactly once.
ChainPEM *string `json:"chain_pem,omitempty"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint SHA-256 fingerprint of the certificate.
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// KeyCustody Which custodian holds this CA's signing key. Recorded per CA rather
// than read from configuration, so adopting a new custodian does not
// strand the CAs that already exist. Not secret — an operator needs to
// see it, and it discloses only where a key is kept.
KeyCustody *string `json:"key_custody,omitempty"`
// KeyLocator Where the custodian put the key. A Vault path under its mount; `None`
// for database custody, whose locator is the row itself.
KeyLocator *string `json:"key_locator,omitempty"`
// MTLSTrustAnchor Whether this CA is offered as a trust anchor for mutual TLS. When set,
// the server exports this CA's **public** certificate to the bundle named
// by `AXIAM__SERVER__TLS__CLIENT_CA_BUNDLE_PATH` at startup and turns
// client-certificate authentication on (`optional`) if the operator has
// not configured it explicitly. A client presenting a certificate that
// chains to this CA is then verified by the TLS layer itself, which is
// what `axiam_pki::mtls` needs to authenticate an IoT device or a service
// account by certificate rather than by secret. # What is and is not
// copied Only `public_cert_pem` — the certificate. The **private key
// stays where its custodian put it** (Vault, or sealed into the row) and
// is never written to the server volume. A trust anchor is public by
// construction: it is what the server hands every client during the TLS
// handshake, and every device that has to validate the chain already
// holds a copy. # Why a restart rustls builds its `RootCertStore` once,
// when the listener is constructed, and actix-web binds that config for
// the process's life. Toggling this changes what the *next* boot trusts,
// and the API says so in its response rather than pretending the change
// took effect. Defaults to `false`, so a deployment that never touches
// this keeps exactly the TLS posture it has today.
MTLSTrustAnchor *bool `json:"mtls_trust_anchor,omitempty"`
// NotAfter Validity end.
NotAfter string `json:"not_after"`
// NotBefore Validity start.
NotBefore string `json:"not_before"`
// OrganizationID The organization this CA belongs to.
OrganizationID uuid.UUID `json:"organization_id"`
// ParentCAID The CA in this organization that signed this one. `None` for an
// organization-level CA, which is either self-signed or imported and has
// no parent inside AXIAM.
ParentCAID *uuid.UUID `json:"parent_ca_id,omitempty"`
// PublicCertPEM PEM-encoded public certificate. The certificate that *signs*, which
// under `vault_pki` custody is the intermediate rather than the root
// beneath which it was created.
PublicCertPEM string `json:"public_cert_pem"`
// Status carries the server's status field.
Status CertificateStatus `json:"status"`
// Subject The certificate subject (e.g., `CN=ACME Corp Root CA`).
Subject string `json:"subject"`
// TenantID The tenant this CA signs for, when it is a tenant signing CA. `None`
// for an organization-level CA — the trust anchor, and the only kind
// that existed before tenant signing CAs. `Some` for an intermediate
// created under one, which exists so a tenant's user, service and device
// certificates chain through a CA that can be revoked and replaced
// without touching the anchor the rest of the estate trusts.
TenantID *uuid.UUID `json:"tenant_id,omitempty"`
}
CACertificate A CA (Certificate Authority) certificate at the organization level. CA certificates are the root of trust for all tenant certificates within the organization. Private keys for signing CAs are encrypted with AES-256-GCM and stored separately; non-signing CAs only store the public certificate.
type CACertificatesAPI ¶
type CACertificatesAPI struct {
// contains filtered or unexported fields
}
CACertificatesAPI is the ca_certificates namespace handle.
Organization CAs and the per-tenant signing CAs chained beneath them.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*CACertificatesAPI) Generate ¶
func (a *CACertificatesAPI) Generate(ctx context.Context, body CreateCACertificateRequest) (GeneratedCACertificate, error)
Generate issues POST /api/v1/organizations/{org_id}/ca-certificates.
Returns secret material, once. private_key_pem is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) GenerateSigningCA ¶
func (a *CACertificatesAPI) GenerateSigningCA(ctx context.Context, tenantID uuid.UUID, body CreateIntermediateCARequest) (GeneratedCACertificate, error)
GenerateSigningCA issues POST /api/v1/organizations/{org_id}/tenants/{tenant_id}/signing-cas.
Returns secret material, once. private_key_pem is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) Get ¶
func (a *CACertificatesAPI) Get(ctx context.Context, id uuid.UUID) (CACertificate, error)
Get issues GET /api/v1/organizations/{org_id}/ca-certificates/{id}.
func (*CACertificatesAPI) ImportCA ¶
func (a *CACertificatesAPI) ImportCA(ctx context.Context, body ImportCACertificateRequest) (CACertificate, error)
ImportCA issues POST /api/v1/organizations/{org_id}/ca-certificates/import.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) InOrg ¶
func (a *CACertificatesAPI) InOrg(orgID uuid.UUID) *CACertificatesAPI
InOrg addresses a different organization than the client's own.
§27.4 rule 3: the client's organization is the default, and a platform-admin token legitimately overrides it. Returns a new handle; the original is unchanged.
func (*CACertificatesAPI) List ¶
func (a *CACertificatesAPI) List(ctx context.Context, page PageRequest) (Page[CACertificate], error)
List issues GET /api/v1/organizations/{org_id}/ca-certificates.
func (*CACertificatesAPI) ListAll ¶
func (a *CACertificatesAPI) ListAll(ctx context.Context, start PageRequest) ([]CACertificate, error)
ListAll walks ca_certificates.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*CACertificatesAPI) ListSigningCas ¶
func (a *CACertificatesAPI) ListSigningCas(ctx context.Context, tenantID uuid.UUID, page PageRequest) (Page[CACertificate], error)
ListSigningCas issues GET /api/v1/organizations/{org_id}/tenants/{tenant_id}/signing-cas.
func (*CACertificatesAPI) ListSigningCasAll ¶
func (a *CACertificatesAPI) ListSigningCasAll(ctx context.Context, tenantID uuid.UUID, start PageRequest) ([]CACertificate, error)
ListSigningCasAll walks ca_certificates.list_signing_cas to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*CACertificatesAPI) MigrateCustody ¶
func (a *CACertificatesAPI) MigrateCustody(ctx context.Context, id uuid.UUID) (MigrateCustodyResponse, error)
MigrateCustody issues POST /api/v1/organizations/{org_id}/ca-certificates/{id}/migrate-custody.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) Revoke ¶
Revoke issues POST /api/v1/organizations/{org_id}/ca-certificates/{id}/revoke.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) SetMTLSTrustAnchor ¶
func (a *CACertificatesAPI) SetMTLSTrustAnchor(ctx context.Context, id uuid.UUID, body SetMTLSTrustAnchor) (MTLSTrustAnchorResponse, error)
SetMTLSTrustAnchor issues PUT /api/v1/organizations/{org_id}/ca-certificates/{id}/mtls-trust-anchor.
This is a REPLACEMENT, not a patch (§27.4 rule 5). Every field of the body is required, and what you do not carry over from a prior read is not preserved — it is overwritten. Read first, change the field you mean, send the whole thing back.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CACertificatesAPI) SignSigningCACSR ¶
func (a *CACertificatesAPI) SignSigningCACSR(ctx context.Context, tenantID uuid.UUID, body SignIntermediateCSRRequest) (CACertificate, error)
SignSigningCACSR issues POST /api/v1/organizations/{org_id}/tenants/{tenant_id}/signing-cas/sign-csr.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type Certificate ¶
type Certificate struct {
// CertType carries the server's cert_type field.
CertType CertificateType `json:"cert_type"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint SHA-256 fingerprint of the certificate.
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IssuerCAID The CA certificate that signed this certificate.
IssuerCAID uuid.UUID `json:"issuer_ca_id"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// Metadata Arbitrary key-value metadata (e.g., device serial, user ID binding).
Metadata any `json:"metadata"`
// NotAfter Validity end.
NotAfter string `json:"not_after"`
// NotBefore Validity start.
NotBefore string `json:"not_before"`
// PublicCertPEM PEM-encoded public certificate.
PublicCertPEM string `json:"public_cert_pem"`
// Status carries the server's status field.
Status CertificateStatus `json:"status"`
// Subject The certificate subject (e.g., `CN=device-001`).
Subject string `json:"subject"`
// TenantID The tenant this certificate belongs to.
TenantID uuid.UUID `json:"tenant_id"`
// BoundServiceAccountID Resolved by the list projection only. The server resolves this for a
// whole page in one query, so it is populated by the List operation and
// is nil on Get (CONTRACT §27.11 rule 4). Nil there means "this read
// does not carry it", not "there is nothing bound" — the SDK does not
// issue a second request to fill it in.
BoundServiceAccountID *uuid.UUID `json:"bound_service_account_id,omitempty"`
}
Certificate A tenant-level certificate for users, services, or IoT devices. Certificates are signed by the organization's CA. The private key is returned once on generation and never stored by AXIAM.
type CertificatePolicy ¶
type CertificatePolicy struct {
// DefaultCertValidityDays carries the server's default_cert_validity_days field.
DefaultCertValidityDays int `json:"default_cert_validity_days"`
// MaxCertValidityDays carries the server's max_cert_validity_days field.
MaxCertValidityDays int `json:"max_cert_validity_days"`
}
CertificatePolicy Certificate issuance constraints.
type CertificateStatus ¶
type CertificateStatus string
CertificateStatus Status of a certificate in its lifecycle.
const ( CertificateStatusActive CertificateStatus = "Active" CertificateStatusRevoked CertificateStatus = "Revoked" CertificateStatusExpired CertificateStatus = "Expired" )
The CertificateStatus values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type CertificateType ¶
type CertificateType string
CertificateType The purpose for which a certificate was issued.
const ( CertificateTypeUser CertificateType = "User" CertificateTypeService CertificateType = "Service" CertificateTypeDevice CertificateType = "Device" )
The CertificateType values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type CertificatesAPI ¶
type CertificatesAPI struct {
// contains filtered or unexported fields
}
CertificatesAPI is the certificates namespace handle.
End-entity X.509 certificates -- the ones issued to users, services and IoT devices.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*CertificatesAPI) Generate ¶
func (a *CertificatesAPI) Generate(ctx context.Context, body CreateCertificateRequest) (GeneratedCertificate, error)
Generate issues POST /api/v1/certificates.
Returns secret material, once. private_key_pem is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*CertificatesAPI) Get ¶
func (a *CertificatesAPI) Get(ctx context.Context, id uuid.UUID) (Certificate, error)
Get issues GET /api/v1/certificates/{id}.
func (*CertificatesAPI) List ¶
func (a *CertificatesAPI) List(ctx context.Context, page PageRequest) (Page[Certificate], error)
List issues GET /api/v1/certificates.
func (*CertificatesAPI) ListAll ¶
func (a *CertificatesAPI) ListAll(ctx context.Context, start PageRequest) ([]Certificate, error)
ListAll walks certificates.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
type CertificationLevel ¶
type CertificationLevel string
CertificationLevel FIDO certification level, as recorded in an MDS `statusReports` entry's `FIDO_CERTIFIED*` status. Variant order is significant: `derive(PartialOrd, Ord)` gives `L1 < L1Plus < L2 < L2Plus < L3 < L3Plus`, which `WebauthnAttestationPolicy::evaluate` (D8 step 9) relies on directly for the `min_certification` boundary check (`entry_level >= policy_min`).
const ( CertificationLevelL1 CertificationLevel = "L1" CertificationLevelL1Plus CertificationLevel = "L1Plus" CertificationLevelL2 CertificationLevel = "L2" CertificationLevelL2Plus CertificationLevel = "L2Plus" CertificationLevelL3 CertificationLevel = "L3" CertificationLevelL3Plus CertificationLevel = "L3Plus" )
The CertificationLevel values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type Change ¶
type Change string
Change says whether reconciling one spec would create, update, or do nothing.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the AXIAM SDK's REST entry point (CONTRACT.md §1-§10). See NewClient.
func NewClient ¶
NewClient constructs a Client. baseURL and tenantSlug are positional and required (D-03): an empty tenantSlug returns an *AuthError — AXIAM is multi-tenant and there is no default tenant, so this can never be a silent default (CONTRACT.md §5, SC#1).
The returned Client always owns a per-instance cookiejar and a TLS-1.3-minimum transport; WithHTTPClient may override the Transport/timeout, but the SDK re-applies its own jar and TLS config over any supplied client afterward (D-09) so neither can be silently dropped or bypassed.
func (*Client) Audit ¶
Audit returns the audit management namespace handle.
Append-only audit log, read-only by construction.
func (*Client) BatchCheck ¶
func (c *Client) BatchCheck(ctx context.Context, reqs []AccessCheck) ([]AccessResult, error)
BatchCheck performs POST /api/v1/authz/check/batch (CONTRACT.md §1), evaluating an ordered list of checks; results are returned in the same order as reqs. Eligible for CF-01's bounded retry (read-only).
func (*Client) CACertificates ¶
func (c *Client) CACertificates() *CACertificatesAPI
CACertificates returns the ca_certificates management namespace handle.
Organization CAs and the per-tenant signing CAs chained beneath them.
func (*Client) Can ¶
Can is an alias for CheckAccess targeting browser/UI scenarios (CONTRACT.md §1 note) — returns only the allowed boolean.
func (*Client) Certificates ¶
func (c *Client) Certificates() *CertificatesAPI
Certificates returns the certificates management namespace handle.
End-entity X.509 certificates -- the ones issued to users, services and IoT devices.
func (*Client) CheckAccess ¶
func (c *Client) CheckAccess(ctx context.Context, action, resourceID string, scope ...string) (bool, string, error)
CheckAccess performs POST /api/v1/authz/check (CONTRACT.md §1), evaluating a single authorization check for the given action/ resourceID/scope. This is a read-only, idempotent operation eligible for CF-01's bounded retry on transient NetworkError.
func (*Client) CheckAccessAs ¶
func (c *Client) CheckAccessAs(ctx context.Context, subjectID, action, resourceID string, scope ...string) (bool, string, error)
CheckAccessAs performs POST /api/v1/authz/check (CONTRACT.md §1) on behalf of subjectID rather than this Client's own session (CONTRACT.md §11.2). This is additive alongside CheckAccess — existing callers/signatures are unchanged — and exists specifically so declarative authorization helpers (middleware.RequireAccess) can evaluate the check for the request's authenticated user_id instead of the application's own (typically service-account) session. A blank subjectID behaves exactly like CheckAccess (the subject_id field is omitted from the wire request).
func (*Client) CheckAccessDecision ¶
func (c *Client) CheckAccessDecision(ctx context.Context, subjectID, action, resourceID string, scope ...string) (AccessResult, error)
CheckAccessDecision performs the same check as CheckAccess but returns the FULL AccessResult, including the §11 rule 9 ReasonCode.
It exists because CheckAccess's (bool, string, error) tuple predates that field and cannot carry it without a breaking signature change. The distinction it surfaces is not cosmetic: no_grant means "ask an admin for access", denied_by_rule means "an admin has already decided", and an application that cannot tell them apart sends users to raise tickets that will be refused.
subjectID may be blank, in which case the check evaluates against this Client's own session exactly as CheckAccess does; a non-blank value behaves like CheckAccessAs (§11.2).
func (*Client) Close ¶
Close releases this Client's local resources (CONTRACT.md §18).
It is idempotent — calling it twice is not an error. Cleanup runs from error paths, and an error path that itself fails hides the original problem. It returns error only to satisfy io.Closer; the error is always nil.
CLOSE DOES NOT LOG OUT. §18.1 rule 5: shutting down a client releases LOCAL resources and never reaches the network. The server-side session deliberately outlives the Client value, which is what lets a process restart and resume; a Close that logged out would silently end every user's session on each deploy. Call Logout first if ending the session is what you want.
After Close returns, every operation on this Client fails with *NetworkError rather than silently reconnecting.
func (*Client) ConfirmPasswordReset ¶
func (c *Client) ConfirmPasswordReset(ctx context.Context, confirmation PasswordResetConfirmation) error
ConfirmPasswordReset performs POST /api/v1/auth/reset/confirm (CONTRACT.md §25.1) — set the new password.
func (*Client) DeviceAuthorize ¶
func (c *Client) DeviceAuthorize(ctx context.Context, params DeviceAuthorizeParams) (DeviceAuthorization, error)
DeviceAuthorize performs `POST /oauth2/device_authorization` (CONTRACT.md §14.1) — start the device grant and obtain the code pair.
UNAUTHENTICATED BY DESIGN. A device that cannot show a browser also cannot hold a client secret, so this never sends client_secret and never refuses a Client built without one (§14.1).
Returns an *AuthError when the discovery document advertises no device_authorization_endpoint. The URL is never built by concatenation onto the issuer: that works against AXIAM and breaks against every other OP the same code is pointed at.
func (*Client) DeviceLogin ¶
func (c *Client) DeviceLogin(ctx context.Context, params DeviceLoginParams) (OidcTokenSet, error)
DeviceLogin is the composed §14.3 helper: start the grant, hand the caller the user code, poll to completion.
params.OnUserCode is called BEFORE the first poll — §14.3 rule 2 requires the caller to have had the chance to display the code before polling begins. The SDK never prints it: what the device does with it (screen, QR code, e-ink panel) is the application's decision. An error from OnUserCode aborts without polling.
Per §14.3 rule 4 (contract 1.7 errata) the token set is RETURNED; whether it is adopted is params.AdoptAsCredential, the same opt-in flag LoginClientCredentials uses in this SDK.
Polling follows §14.2: the interval comes from the response; slow_down adds 5 s PERMANENTLY; authorization_pending loops; access_denied and expired_token raise distinct errors; polling stops at ExpiresIn even if the server has not yet said expired_token. A 5xx or transport failure mid-poll is NOT terminal (rule 6) — the loop absorbs it and tries again, bounded by the same deadline, because a server restart must not lose a grant the user has already approved.
ctx cancellation is honoured between polls: a device powering down should not have to wait out the interval.
func (*Client) DevicePoll ¶
func (c *Client) DevicePoll(ctx context.Context, params DevicePollParams) (OidcTokenSet, error)
DevicePoll performs ONE `POST /oauth2/token` with the device-code grant (CONTRACT.md §14.1).
The raw single call, so an application driving its own loop (a UI rendering a countdown, say) can. All five RFC 8628 §3.5 answers surface as *OAuthProtocolError — authorization_pending and slow_down included — so a hand-rolled loop sees exactly what DeviceLogin sees. Most callers want DeviceLogin.
func (*Client) EmailConfig ¶
func (c *Client) EmailConfig() *EmailConfigAPI
EmailConfig returns the email_config management namespace handle.
Transactional-mail transport, configurable at organization level and overridable per tenant.
func (*Client) Federation ¶
func (c *Client) Federation() *FederationAPI
Federation returns the federation management namespace handle.
Upstream IdP configuration and the per-user links it produces.
func (*Client) Groups ¶
Groups returns the groups management namespace handle.
Named collections of users. Roles assigned to a group are inherited by every member.
func (*Client) Introspect ¶
func (c *Client) Introspect(ctx context.Context, params IntrospectParams) (IntrospectionResult, error)
Introspect performs `POST /oauth2/introspect` (RFC 7662, CONTRACT.md §12.1) — ask the server whether a token is active and, if so, for its metadata.
Requires confidential-client credentials (§12.1 note 4). A 401 here is a CLIENT-CREDENTIAL failure surfaced as *OAuthProtocolError; it never enters the §9 refresh guard, because refreshing the session cannot fix a bad client_secret (§12.3 rule 3) — Introspect never touches Client.guard or the oidc_refresh guard at all.
func (*Client) Login ¶
Login performs POST /api/v1/auth/login (CONTRACT.md §1). On success (no MFA), tokens are already present in the cookie jar and the org_id claim has been resolved+cached. When the server signals MFA is required, returns LoginResult{MFARequired: true, ...} — this is an expected outcome, not an error.
func (*Client) LoginClientCredentials ¶
func (c *Client) LoginClientCredentials(ctx context.Context, params LoginClientCredentialsParams) (OidcTokenSet, error)
LoginClientCredentials performs `POST /oauth2/token` with `grant_type=client_credentials` (CONTRACT.md §12.1) — service-account machine-to-machine login.
Requests no "openid" scope, so the response carries no id_token. Pass params.AdoptAsCredential = true to additionally use the returned access token as this Client's bearer credential for subsequent REST calls (§12.1, a MAY).
Returns *AuthError, client-side with no wire call, when the Client was not constructed with WithOidcClientSecret — this grant cannot be performed by a public client.
func (*Client) LoginOpaque ¶
func (c *Client) LoginOpaque(ctx context.Context, usernameOrEmail, password string) (LoginResult, error)
LoginOpaque performs a full OPAQUE login (CONTRACT.md §23).
Returns the same LoginResult as Login, including the MFA-challenge case, so a caller needs one result handler for both.
What this does that Login does not ¶
The password never leaves this process. What crosses the wire is a blinded group element and a MAC, neither useful without the account's record AND the tenant's OPRF seed — so a TLS-terminating proxy, an accidentally verbose request log or a heap dump on the server cannot capture a plaintext password, because the server never has one. It also means a stolen record database is not offline-crackable on its own, which is the property SRP could not offer.
It does NOT protect against a compromised AXIAM server.
What a caller no longer has to do ¶
Under SRP this returned only after verifying the server's M2, and §23.3 rule 6 had to mandate that in capitals because skipping it kept only the half of the protocol that authenticates the client. RFC 9807's AKE authenticates the server during the handshake — opening KE2 IS the proof that the server holds the record — so there is no separate check and no way for a caller to omit one.
Errors ¶
- *NetworkError when the tenant has OPAQUE disabled (the endpoint answers 404 — a property of the tenant, not of any user), and when this SDK cannot perform the KSF the server named. These are client-side or configuration faults, deliberately not *AuthError: reporting them as a credential failure would send a user off to reset a password that works, and would stop a caller falling back to Login.
- *AuthError for a wrong password, an account that does not exist, and a server that does not hold the record — indistinguishable by design. Nothing is sent to login/finish in that case (§23.4 rule 7).
When a failed exchange falls back to Login (§23.4 rule 7) ¶
A failure to open KE2 ends the OPAQUE exchange — no KE3 is ever sent — but it is not always the end of the login. The login/start response carries the tenant's mode, and that alone decides:
- "optional": this call retries the same credentials over Login before reporting anything, and returns that call's result or its error. Under optional an account with no registration record is the ordinary case, not a failure — every account has none until its password is next set — so reporting the failed exchange would lock out every user of a tenant part-way through a migration.
- "required", an unrecognised value, or no mode field at all (a server older than contract 1.29): *AuthError, and Login is NOT tried. Such a tenant refuses /auth/login for every principal anyway, so the retry would only put a plaintext password on the wire.
The mode field is NOT downgrade protection and must not be read as such: a hostile server that wanted the plaintext could answer 404 and get the caller's own fallback regardless of what it puts here. What closes that is server-side — required refuses /auth/login before examining any credential.
Cost ¶
Runs the tenant's key-stretching function: Argon2id at 19 MiB by default, tens to hundreds of milliseconds of CPU and the memory to go with it. That cost is the point — it is what makes a stolen record expensive to attack even by someone holding the OPRF seed.
func (*Client) Logout ¶
Logout performs POST /api/v1/auth/logout (CONTRACT.md §1) and clears in-memory token state.
func (*Client) LogoutURL ¶
LogoutURL builds the RP-initiated logout URL to redirect the user agent to (CONTRACT.md §12.7.2).
Performs NO network I/O beyond the discovery fetch the SDK caches anyway, and does NOT clear this Client's own session: whether the local session ends is the application's decision — a backend holding a service-account session must not lose it because a USER logged out.
end_session_endpoint is read from discovery and never synthesised from the issuer (rule 1). Code that concatenates works against AXIAM and breaks against every other OP the same application is pointed at.
PostLogoutRedirectURI is passed through UNVALIDATED against any local list (rule 3): the allow-list lives in the client's server-side registration, and a client-side copy would drift and reject a URI an operator had just registered.
func (*Client) Manifest ¶
func (c *Client) Manifest() *ManifestAPI
Manifest returns the §27.6 declarative-management handle.
Acquiring it performs no I/O, exactly as the namespace handles do not.
func (*Client) MfaConfirm ¶
MfaConfirm performs POST /api/v1/auth/mfa/confirm (CONTRACT.md §25.1) — activate the factor MfaEnroll offered, by proving a code derived from its secret.
func (*Client) MfaEnroll ¶
func (c *Client) MfaEnroll(ctx context.Context) (MfaEnrollment, error)
MfaEnroll performs POST /api/v1/auth/mfa/enroll (CONTRACT.md §25.1) — start voluntary TOTP enrolment for the signed-in user.
Changes nothing about the current session. In particular it does NOT clear the §17 decision memo: the subject has not changed, and discarding a warm memo on an unrelated profile action costs a round trip on every check that follows (§25.2 rule 3).
func (*Client) MfaSetupConfirm ¶
func (c *Client) MfaSetupConfirm(ctx context.Context, setupToken Sensitive, totpCode string) (LoginResult, error)
MfaSetupConfirm performs POST /api/v1/auth/mfa/setup/confirm (CONTRACT.md §25.1) — finish forced enrolment and, with it, the login that was interrupted.
Adopts credentials exactly as Login does, because it IS the completion of a login (§25.2 rule 2).
func (*Client) MfaSetupEnroll ¶
MfaSetupEnroll performs POST /api/v1/auth/mfa/setup/enroll (CONTRACT.md §25.1) — start the enrolment a Login demanded.
Reached when Login returns MFASetupRequired: the tenant requires MFA and this account has none. There is no session yet — the setup token IS the credential.
func (*Client) NotificationRules ¶
func (c *Client) NotificationRules() *NotificationRulesAPI
NotificationRules returns the notification_rules management namespace handle.
Which events raise a notification, and to whom.
func (*Client) OAuth2Clients ¶
func (c *Client) OAuth2Clients() *OAuth2ClientsAPI
OAuth2Clients returns the oauth2_clients management namespace handle.
Registered OAuth2/OIDC clients -- the registration half of what §12, §21 and §26 then speak to.
func (*Client) OidcBegin ¶
func (c *Client) OidcBegin(configuration OidcConfiguration, params OidcBeginParams) (AuthorizationRequest, error)
OidcBegin builds an authorization request (CONTRACT.md §12.1) — PURE LOCAL COMPUTATION, no network I/O.
Generates a 32-byte CSPRNG State and Nonce (base64url, unpadded) and a fresh PKCE verifier/challenge pair using S256 ONLY — "plain" is not implemented anywhere in this SDK. The URL is built from configuration's AuthorizationEndpoint with exactly the eight parameters §12.1 rule 5 mandates, plus any ExtraParams the caller adds.
Nothing is stored: persist the returned State, Nonce and CodeVerifier yourself (§12.3 rule 1).
Returns a plain (non-taxonomy) error — deliberately NOT *AuthError — when ExtraParams tries to override one of the eight SDK-owned parameters: this is a programming error caught at call time (§12 port addendum item 9).
func (*Client) OidcDiscover ¶
func (c *Client) OidcDiscover(ctx context.Context) (OidcConfiguration, error)
OidcDiscover performs `GET /.well-known/openid-configuration` (CONTRACT.md §12.1) — fetch and cache the OIDC discovery document, with a >=5-minute TTL and single-flight de-duplication of concurrent calls (§12.3 rule 6).
The document's own Issuer is authoritative for ID-token validation and may legitimately differ from the Client's base URL behind a proxy, so a mismatch is never treated as an error.
func (*Client) OidcExchange ¶
func (c *Client) OidcExchange(ctx context.Context, params OidcExchangeParams) (OidcTokenSet, error)
OidcExchange performs `POST /oauth2/token` with `grant_type=authorization_code` (CONTRACT.md §12.1) — exchange an authorization code for a token set, validating the returned ID token in full before returning.
params.Nonce is mandatory: this grant always requests the "openid" scope, so §12.4 rule 6 always applies. If ANY §12.4 rule fails, the whole token set is discarded and *AuthError is raised with the matching Reason code — the access and refresh tokens from the same response are never returned (§12.4 rule 7).
func (*Client) OidcPar ¶
func (c *Client) OidcPar(ctx context.Context, params OidcParParams) (PushedAuthorizationRequest, error)
OidcPar performs POST /oauth2/par (CONTRACT.md §26.1) — push the authorization request over the back channel and get an opaque handle to redirect with.
REQUIRED FOR A FAPI 2.0 CLIENT: profile: "fapi2" refuses a registration that does not set require_par, so such a client cannot authorize any other way (§21.1).
Not retried on a 5xx or a transport failure — it is a POST that creates server state, so it falls outside §16.2's read-only eligibility exactly as OidcExchange does. The safe recovery is a fresh push, which costs one round trip and cannot double-consume anything (§26.2 rule 4).
Returns an *AuthError when the discovery document advertises no pushed_authorization_request_endpoint. The URL is never built by concatenation onto the issuer.
func (*Client) OidcRefresh ¶
func (c *Client) OidcRefresh(ctx context.Context, params OidcRefreshParams) (OidcTokenSet, error)
OidcRefresh performs `POST /oauth2/token` with `grant_type=refresh_token` (CONTRACT.md §12.1) under a single-flight refresh guard (§9): concurrent callers collapse into ONE HTTP request and all receive the same OidcTokenSet (or the same failure), with no retry loop on failure (§9.3).
This is a DISTINCT operation from Client.Refresh, which drives the cookie/opaque-token session path at POST /api/v1/auth/refresh (§5.1). The two are never merged, aliased, or made to fall back to one another (§12.1 "oidc_refresh vs refresh").
This method uses its OWN single-flight guard (oidcState.pendingRefresh) — a SEPARATE instance from the cookie-session Client.guard (internal/refreshguard.Guard). That type's RefreshIfNeeded API compares an "observed" axiam_access cookie value against its own cache, which has no meaning for an OAuth2 refresh_token grant operating on an entirely different, cookie-independent token namespace; reusing the literal same Guard instance for both would corrupt its cookie-session comparison state with an unrelated token stream. A dedicated guard, built from the exact mechanism CONTRACT.md §9 prescribes for Go (a mutex plus a channel carrying the shared result), still satisfies §9's actual requirement for THIS operation — exactly one in-flight refresh, waiters share the outcome, no retry on failure — without that cross-talk. (Documented deviation from the literal wording of the TypeScript reference, which shares one generic mutex-based guard across both operations because its guard has no token-comparison state to corrupt in the first place.)
An id_token in the response is validated against §12.4 rules 1-5 and 7; rule 6 (nonce) is skipped, since OIDC Core §12.2 does not require a nonce in a refresh-issued ID token.
func (*Client) OpaqueAvailable ¶
OpaqueAvailable reports whether this build can perform OPAQUE (§23.2).
Always true for the Go SDK, which compiles the implementation in. It exists because §23.2 puts it in the locked method vocabulary for every SDK, and in the SDKs that load a native library or a WebAssembly module it genuinely answers false when that artifact is absent.
func (*Client) OpaqueEnrollment ¶
OpaqueEnrollment builds a registration record for password, to send with any request that sets one (user creation, change-password, reset completion).
This performs a register/start round trip, which the SRP verifier it replaces did not need: OPAQUE's envelope is sealed under the server's oblivious PRF, so there is no offline computation that produces a valid record.
Note the absence of an identity argument. The SRP version required the account's canonical username, and passing an email produced a verifier no login could ever satisfy. A record binds to a credential identifier the server chooses, so there is nothing here to get wrong — and a later rename cannot invalidate it.
Errors ¶
*NetworkError when the tenant has OPAQUE disabled or this SDK cannot perform the KSF the server named.
func (*Client) OpaqueEnrollmentForSelf ¶
func (c *Client) OpaqueEnrollmentForSelf(ctx context.Context, password string) (*OpaqueEnrollment, error)
OpaqueEnrollmentForSelf builds a registration record for the CALLER'S OWN new password, sealed against the tenant the caller's account lives in.
CONTRACT.md §5.2.2 rule 2. POST /auth/password/change and the record that accompanies it are about the account, not about whatever tenant the client is currently pointed at, and a record sealed against the acting tenant is refused with "the OPAQUE session was issued for a different tenant".
The distinction only bites for an organization-level principal that has selected another tenant to act on; for everyone else the two tenants are the same value and this behaves identically to OpaqueEnrollment. It is still the method to call for a self-service password change, because which principal is signed in is not something the call site usually knows.
Returns a NetworkError when no login has completed on this client yet — the principal tenant is reported by the login response, so there is nothing to seal against before then.
func (*Client) Organizations ¶
func (c *Client) Organizations() *OrganizationsAPI
Organizations returns the organizations management namespace handle.
Organizations an SDK client may read and configure. Creation and deletion are outside the SDK boundary (§27.0).
func (*Client) PGPKeys ¶
func (c *Client) PGPKeys() *PGPKeysAPI
PGPKeys returns the pgp_keys management namespace handle.
OpenPGP keys used for audit signing and encrypted data export.
func (*Client) PasswordResetContext ¶
func (c *Client) PasswordResetContext(ctx context.Context, token Sensitive) (PasswordResetContext, error)
PasswordResetContext performs GET /api/v1/auth/reset/context (CONTRACT.md §25.1) — the OPAQUE policy for the account a reset token belongs to.
Call this before ConfirmPasswordReset on any tenant that might have §23 enabled: the client has to build a registration record, and building one needs parameters it cannot know before it has a token to ask with. Sending a plaintext password to a tenant in opaque_mode: required is refused, and refused late (§25.4 rule 1).
A 404 means unknown, expired OR already-consumed, deliberately without distinguishing them; this SDK does not distinguish them either (§25.4 rule 3).
func (*Client) Permissions ¶
func (c *Client) Permissions() *PermissionsAPI
Permissions returns the permissions management namespace handle.
Permissions -- an action on a resource, optionally narrowed by a scope.
func (*Client) Platform ¶
func (c *Client) Platform() *PlatformAPI
Platform returns the platform management namespace handle.
Deployment-level probes and FIDO metadata state. Unauthenticated where the server leaves them so.
func (*Client) Privacy ¶
func (c *Client) Privacy() *PrivacyAPI
Privacy returns the privacy management namespace handle.
GDPR self-service: the authenticated account's own export and erasure. Scoped to the caller, never to another user.
func (*Client) Reactors ¶
func (c *Client) Reactors() *ReactorsAPI
Reactors returns the reactors management namespace handle.
Registration of §22 AMQP extension actors -- the admin surface §22.9 describes, which no SDK could previously reach.
func (*Client) Refresh ¶
Refresh performs POST /api/v1/auth/refresh (CONTRACT.md §1), routed through the sync.Mutex single-flight guard (§9) so concurrent 401s share exactly one in-flight refresh call. A 401 on the refresh call itself is AuthError with no retry (§9.3).
func (*Client) RequestPasswordReset ¶
func (c *Client) RequestPasswordReset(ctx context.Context, request PasswordResetRequest) error
RequestPasswordReset performs POST /api/v1/auth/reset (CONTRACT.md §25.1) — ask for a reset mail.
RETURNS NIL WHETHER OR NOT THE ADDRESS EXISTS, and this SDK exposes no way to tell the two apart. That is not an omission to improve on: a client that surfaced a "no such user" state — even one inferred from timing — would turn the endpoint into the account enumeration oracle its uniform response exists to prevent (§25.4).
func (*Client) ResendOwnVerification ¶
ResendOwnVerification performs POST /api/v1/users/me/resend-verification (CONTRACT.md §25.1, §25.7) — resends the SIGNED-IN CALLER'S OWN verification mail, and says what happened.
Takes no address. The server reads it off the caller's own record, and this signature deliberately offers no way to name a different one: a parameter here would let an authenticated session mail an arbitrary address.
Unlike ResendVerification this reports the outcome, because the caller is signed in to the account it is asking about and none of the outcomes tells it anything it did not already know:
- nil — a token was minted and the mail ENQUEUED. Delivery is asynchronous and can still fail at the provider; a queue that accepts everything in front of one that rejects it looks exactly like this succeeding.
- *AuthzError (from 409) — already verified, or the account is in a state that must not be sent a live token.
- *NetworkError (from 429) — the daily resend limit.
§25.7 rule 2 forbids falling back to the unauthenticated endpoint on either of those, and this SDK does not: the fallback would turn both failures back into a nil error and restore the bug this operation exists to fix, with an extra round-trip.
func (*Client) ResendVerification ¶
ResendVerification performs POST /api/v1/auth/resend-verification (CONTRACT.md §25.1) — the UNAUTHENTICATED resend, for a caller with no session.
Returns nil whatever the outcome. The address may not exist, may already be verified, or may be over the daily limit, and this answers identically in all of them, because it takes an address from an anonymous caller and anything else is an oracle for which addresses have accounts (§25.7).
A caller that IS signed in wants ResendOwnVerification, which says which of those happened. Do not reach for this one because it is the name you already knew.
func (*Client) ResolvedOrgID ¶
ResolvedOrgID returns the organization UUID this client will use, and whether one is available: the explicitly configured WithOrgID value if present, otherwise the value resolved from the access token's org_id claim after a login.
Exported for the same reason as ResolvedTenantID: §27 callers outside this package legitimately need to know which organization a management call will address before making it.
func (*Client) ResolvedTenantID ¶
ResolvedTenantID returns the tenant UUID resolved from the access token's tenant_id claim, and whether one is available.
The exported twin of ResolvedOrgID, and symmetric with it for the same reason: this client is constructed with a tenant slug, so the UUID only exists after a login has decoded it. CONTRACT.md §27 routes that name a tenant explicitly — the signing CAs under CaCertificates, and the Tenants namespace itself — take that UUID as an ordinary argument rather than defaulting it (§27.4 rule 3, because there it names the object being acted on rather than the context), so a caller outside this package needs a way to read the one the session already knows instead of re-deriving it.
func (*Client) Resources ¶
func (c *Client) Resources() *ResourcesAPI
Resources returns the resources management namespace handle.
The resource hierarchy role assignments cascade down.
func (*Client) Revoke ¶
func (c *Client) Revoke(ctx context.Context, params RevokeParams) error
Revoke performs `POST /oauth2/revoke` (RFC 7009, CONTRACT.md §12.1) — revoke an access or refresh token.
Per RFC 7009 the server answers 200 for unknown, expired and already-revoked tokens alike, so revocation is IDEMPOTENT: any 2xx is success and no error is raised for a token the server has never seen. Only a 401 (client authentication failed) is an error, surfaced as *OAuthProtocolError (§12.1 note 5, §12.3 rule 3); a 5xx is still a *NetworkError (revoke returning void does not make a server error "success").
Returns *AuthError, client-side with no wire call, when the Client was not constructed with WithOidcClientSecret.
func (*Client) Roles ¶
Roles returns the roles management namespace handle.
Roles, their permission sets, and their assignment to users and groups.
func (*Client) SCIMTokens ¶
func (c *Client) SCIMTokens() *SCIMTokensAPI
SCIMTokens returns the scim_tokens management namespace handle.
Bearer tokens for the SCIM 2.0 provisioning endpoint.
func (*Client) Scopes ¶
Scopes returns the scopes management namespace handle.
Sub-resource granularity, always addressed under their resource.
func (*Client) ServiceAccounts ¶
func (c *Client) ServiceAccounts() *ServiceAccountsAPI
ServiceAccounts returns the service_accounts management namespace handle.
Machine identities, their secrets, and the certificate a device-bound one authenticates with.
func (*Client) Settings ¶
func (c *Client) Settings() *SettingsAPI
Settings returns the settings management namespace handle.
Effective settings, and the organization/tenant layers they resolve from.
func (*Client) SsoComplete ¶
func (c *Client) SsoComplete(ctx context.Context, params SsoCompleteParams) (SsoCompleteResult, error)
SsoComplete performs `POST /api/v1/auth/federation/oidc/callback` (CONTRACT.md §12.1) — step 2 of upstream SSO: consumes the single-use state, provisions or links the user, and establishes the session.
The session arrives as Set-Cookie, NOT in the response body (§12.1 note 6), so this call goes through the SAME §4 cookie-jar path every other authenticated call already uses — no separate wiring needed. On success the session is marked authenticated via the same absorption Login/VerifyMfa perform (decode the org_id claim, seed the refresh guard), mirroring the TypeScript reference's onAuthenticated() hook (CONTRACT.md §12 T1 judgment call 16).
§12.4 does not apply here — no ID token ever reaches the SDK on the federation path.
func (*Client) SsoCompleteHandoff ¶
func (c *Client) SsoCompleteHandoff(ctx context.Context, params SsoCompleteHandoffParams) (SsoCompleteResult, error)
SsoCompleteHandoff performs `POST /api/v1/auth/federation/handoff` (CONTRACT.md §12.1) — redeem the single-use code the SAML and Apple flows deliver.
Those two protocols return CROSS-SITE, so the server cannot set SameSite=Strict session cookies on that response. It instead redirects the browser to the SPA's callback URL with a HandoffQueryParam query parameter; this call posts that code back same-origin, and THIS response is the one that carries the cookies (§12.1 note 12).
The code is gone either way ¶
It is valid for HandoffCodeTTL and redeemable ONCE. Redeem it from the same origin, immediately, and never retry a failed redemption — a 401 is terminal, and this method makes exactly one wire call so that it cannot become a retry by accident. Unknown, expired and already-redeemed all answer the same 401, deliberately: telling them apart is not something a caller gets to do.
func (*Client) SsoCompleteOauth2 ¶
func (c *Client) SsoCompleteOauth2(ctx context.Context, params SsoCompleteOauth2Params) (SsoCompleteResult, error)
SsoCompleteOauth2 performs `POST /api/v1/auth/federation/oauth2/callback` (CONTRACT.md §12.1) — step 2 of a plain-OAuth2 login.
The session arrives as Set-Cookie (§12.1 note 6) and is absorbed exactly as SsoComplete absorbs it, so Refresh and Logout work afterwards.
§12.4 does not apply: an OAuth2 provider issues no ID token, so there is nothing to validate. The server authenticated the user by calling a configured userinfo endpoint with the access token it had just received — configuration and transport trust rather than cryptographic trust (§12.1 note 11).
func (*Client) SsoProviders ¶
func (c *Client) SsoProviders(ctx context.Context, params SsoProvidersParams) (FederationProviderList, error)
SsoProviders performs `GET /api/v1/auth/federation/providers` (CONTRACT.md §12.1) — which "Sign in with X" buttons to render for a workspace.
The identifiers travel as QUERY parameters; this is a GET and sends no body. The neighbouring start operations take the same four in a JSON body, and the two are one copy-paste apart.
An empty list is a success ¶
An unknown organization, a known one with nothing configured, and a request naming no workspace at all all answer 200 with an empty providers array (§12.1 note 9). This method returns every one of them as an ordinary result and never synthesises a not-found: the endpoint is deliberately shaped so it cannot be used to enumerate organization or tenant slugs, and an SDK that reintroduced the distinction would reintroduce the oracle. A caller learns it named the workspace wrongly at the start operations, where every failure is a uniform 401.
For the same reason this is the one federation operation that does NOT refuse client-side when no workspace resolves — it sends the request. A client-side refusal would be that same two-valued answer by another route.
func (*Client) SsoStart ¶
func (c *Client) SsoStart(ctx context.Context, params SsoStartParams) (SsoStartResult, error)
SsoStart performs `POST /api/v1/auth/federation/oidc/start` (CONTRACT.md §12.1) — step 1 of first-time SSO against an UPSTREAM IdP. No JWT required.
One tenant form (params.TenantID or params.TenantSlug) and one org form (params.OrgID or params.OrgSlug) must be resolvable, from the arguments or from the Client's own construction options (§5.1) — this Client always has a tenant slug (NewClient requires one), so the tenant form is always resolvable in practice; the organization form still needs WithOrgID/ WithOrgSlug (or an explicit argument) unless the Client already resolved one from a prior Login.
Redirect the browser to the returned AuthorizeURL and round-trip State back into SsoComplete unmodified — the server keeps the nonce to itself (§12.1 note 7).
Returns *AuthError, client-side with no wire call, when tenant or org context cannot be resolved.
func (*Client) SsoStartOauth2 ¶
func (c *Client) SsoStartOauth2(ctx context.Context, params SsoStartOauth2Params) (SsoStartResult, error)
SsoStartOauth2 performs `POST /api/v1/auth/federation/oauth2/start` (CONTRACT.md §12.1) — step 1 of a login through a PLAIN-OAUTH2 upstream (GitHub, Facebook, generic_oauth2).
Call this, rather than SsoStart, exactly when the provider's Protocol is ProtocolOAuth2 (§12.1 note 10). The server refuses a mismatch with 400 rather than accepting it silently, so a client that assumes OIDC fails on every GitHub button.
PKCE is mandatory on this path and is generated and stored SERVER-SIDE; nothing about it appears in the request or the response (§12.1 note 11).
A 400 here can mean the RedirectURI is not on an origin the deployment accepts (§12.1 rule 12a). §2's 400 row makes that a *NetworkError — this taxonomy's configuration/programming-error member, as distinct from the *AuthError a 401 gets. It is not retried; the same origin will be refused again.
func (*Client) Tenants ¶
func (c *Client) Tenants() *TenantsAPI
Tenants returns the tenants management namespace handle.
Tenants within an organization -- the isolation boundary every other namespace is scoped to.
func (*Client) TokenExchange ¶
func (c *Client) TokenExchange(ctx context.Context, params TokenExchangeParams) (ExchangedToken, error)
TokenExchange performs `POST /oauth2/token` with the RFC 8693 grant (CONTRACT.md §15.1) — exchange a token for a NARROWER one.
The exchanging client authenticates (client_secret_post): unlike §14's device, this is a confidential service, so a Client with no secret fails here client-side, with no wire call.
What this method deliberately does NOT do:
- No default ActorToken (§15.2 rule 1). Leaving it zero asks for IMPERSONATION; the SDK will not quietly reuse the client's own session token as the actor and turn that into a delegation.
- No retry or downgrade on unauthorized_client (rule 2) — a registration fact an operator must fix.
- No auto-narrowing on invalid_scope (rule 3). The server refuses instead of silently narrowing precisely so the caller finds out here.
- No adoption (rule 5). The returned token is handed onward in one outbound call; adopting it would silently re-privilege every subsequent call this client makes. A MUST NOT, where LoginClientCredentials adoption is an opt-in MAY.
A cross-tenant subject token answers invalid_grant, identically to an expired one. The SDK does not try to tell them apart (§15.3): the server collapses them because distinguishing them is a tenant-enumeration signal.
func (*Client) UmaDeleteResource ¶
UmaDeleteResource performs `DELETE /uma2/rreg/resource_set/{id}` (§20.1) — deregister a resource set.
func (*Client) UmaExchangeTicket ¶
func (c *Client) UmaExchangeTicket(ctx context.Context, params UmaExchangeTicketParams) (RequestingPartyToken, error)
UmaExchangeTicket performs `POST /oauth2/token` with the UMA ticket grant (§20.1) — redeem a permission ticket for a Requesting Party Token.
Unlike the Protection API above, this is a token-endpoint grant: the CLIENT authenticates through the form body (client_secret_post), so a Client with no secret fails here client-side, with no wire call.
What this method deliberately does NOT do:
- NO RETRY, EVER (§20.2 rule 6) — not on 5xx, not on a timeout, not on invalid_grant. This is the one documented exception to §16, and it is a security rule rather than a performance one: the ticket is consumed BEFORE the request is evaluated, so a failed exchange has already spent it, and a retry is a second redemption — exactly the concurrent redemption a server whose storage engine this SDK cannot attest may admit twice (ilpanich/axiam#302). The property holds structurally here: this call goes straight through doRequest and never touches retry.go's policy.
- No defaulted ClaimToken (rule 2). It is the only channel that names the requesting party; defaulting it to the resource server's own PAT would mint an RPT for the resource server rather than for the user.
- No auto-narrowing on access_denied (rule 3). A partial grant is refused whole, and whether two-of-three permissions is useful is the calling application's judgement, not this SDK's.
- No adoption (rule 4). The RPT is the REQUESTING PARTY's token; adopting it would re-privilege every later call this resource server makes as that user.
- No refresh token (rule 5) — the grant issues none, and RequestingPartyToken has nowhere to put one. Re-run the grant with a new ticket to get a fresh RPT.
The four ticket refusals — unknown, expired, already used, minted by another client — all arrive as one invalid_grant, and this SDK does not guess which (§20.4): the server collapses them because telling them apart lets a caller probe for live ticket handles.
func (*Client) UmaListResources ¶
UmaListResources performs `GET /uma2/rreg/resource_set` (§20.1) — the ids THIS client registered.
Not the tenant's resource tree: the server scopes the listing to the registering client, so a PAT is not an enumeration handle.
func (*Client) UmaReadResource ¶
func (c *Client) UmaReadResource(ctx context.Context, pat Sensitive, id string) (ResourceSet, error)
UmaReadResource performs `GET /uma2/rreg/resource_set/{id}` (§20.1).
func (*Client) UmaRegisterResource ¶
func (c *Client) UmaRegisterResource(ctx context.Context, pat Sensitive, resource ResourceSet) (ResourceSet, error)
UmaRegisterResource performs `POST /uma2/rreg/resource_set` (§20.1) — register a resource set.
The returned ID is THE AXIAM RESOURCE ID, not a parallel identifier: the same UUID is directly usable as RequestedPermission.ResourceID and as the resource id anywhere else in this SDK.
pat is a Protection API Token — an ordinary access token obtained through LoginClientCredentials with the uma_protection scope. §20.2 rule 1: it must be a CLIENT-credentials token, because a minted ticket is bound to the client_id that minted it. This SDK never substitutes the client's own session token when the caller passes none; an empty pat is a client-side error with no wire call.
func (*Client) UmaRequestTicket ¶
func (c *Client) UmaRequestTicket(ctx context.Context, pat Sensitive, permissions []RequestedPermission) (Sensitive, error)
UmaRequestTicket performs `POST /uma2/perm` (§20.1) — mint a permission ticket for the (resource, scopes) pairs a caller lacks.
The ticket comes back wrapped: for its 60-second life it is the credential that converts into an RPT, and a short lifetime is not the same as a harmless one (§20.6).
func (*Client) UmaUpdateResource ¶
func (c *Client) UmaUpdateResource(ctx context.Context, pat Sensitive, id string, resource ResourceSet) (ResourceSet, error)
UmaUpdateResource performs `PUT /uma2/rreg/resource_set/{id}` (§20.1) — replace a resource set's state.
resource.ResourceScopes REPLACES the declared list; it does not merge with it (§20.2 rule 8). This method deliberately performs no read-modify-write: folding the current scopes into the payload as a convenience would make removing a scope impossible through this SDK.
func (*Client) Users ¶
Users returns the users management namespace handle.
Users within the client's tenant, and the administrative side of their second factor and lockout state.
func (*Client) VerifyEmail ¶
VerifyEmail performs POST /api/v1/auth/verify-email (CONTRACT.md §25.1).
Unauthenticated: a user whose address is unverified may have no session at all. tenantID is a BODY field here — this is not an /oauth2/* endpoint, so §12.1 rule 2's query-parameter convention does not reach it.
func (*Client) VerifyLogoutToken ¶
func (c *Client) VerifyLogoutToken(ctx context.Context, token string, configuration *OidcConfiguration) (VerifiedLogoutToken, error)
VerifyLogoutToken verifies a back-channel logout token the OP POSTed to this application's backchannel_logout_uri (CONTRACT.md §12.7.3).
Every check exists because skipping it has a name:
- Signature, through the same §12.4 JWKS verifier the ID-token path uses — no second key-fetching path — which already pins EdDSA and requires a kid, so key rotation cannot be defeated by omitting the header.
- iss/aud: a token minted for another RP is not accepted here.
- `events` carries the back-channel-logout key. This is what distinguishes a logout token from an ID token; skipping it means accepting a replayed ID token as a logout instruction.
- `nonce` is ABSENT. Back-Channel Logout 1.0 §2.4 forbids it, and its presence is the documented signature of an ID token being replayed. Rejected, not ignored.
- At least one of sid/sub — a token naming neither identifies nothing.
- exp in the future, iat recent.
Returns sid/sub/jti — never a bare bool, because the RP has to know WHICH session to end. Dedup on JTI yourself: delivery is at-least-once, so a valid token legitimately arrives twice, and an SDK-side guard would have no durable store and would silently drop a real second logout after a restart.
func (*Client) VerifyMfa ¶
func (c *Client) VerifyMfa(ctx context.Context, mfaToken Sensitive, code string) (LoginResult, error)
VerifyMfa performs POST /api/v1/auth/mfa/verify (CONTRACT.md §1), completing the two-phase flow started by Login when MFARequired was true.
func (*Client) WebauthnAuthenticateFinish ¶
func (c *Client) WebauthnAuthenticateFinish( ctx context.Context, stateToken Sensitive, response any, ) (WebauthnLoginResult, error)
WebauthnAuthenticateFinish performs POST /api/v1/auth/webauthn/authenticate/finish (CONTRACT.md §24.1).
Leaves this client authenticated (§24.3 rule 1). That is not §14.3's "MAY adopt" posture: DeviceLogin mints tokens a caller may want to route elsewhere, and this is the SDK's own primary authentication — returning a token set without adopting it would make a passkey sign-in the one way to log in that does not log you in.
func (*Client) WebauthnAuthenticateStart ¶
func (c *Client) WebauthnAuthenticateStart( ctx context.Context, challengeToken Sensitive, ) (WebauthnChallenge, error)
WebauthnAuthenticateStart performs POST /api/v1/auth/webauthn/authenticate/start (CONTRACT.md §24.1).
The SECOND-FACTOR ceremony: it continues a Login that answered MFARequired with "webauthn" among its AvailableMethods, and challengeToken is that result's MFAToken.
A different flow from WebauthnDiscoverableStart, not the same one with an optional argument — see §24.2 for why they cannot be merged.
func (*Client) WebauthnDiscoverableFinish ¶
func (c *Client) WebauthnDiscoverableFinish( ctx context.Context, stateToken Sensitive, response any, ) (WebauthnLoginResult, error)
WebauthnDiscoverableFinish performs POST /api/v1/auth/webauthn/authenticate/discoverable/finish (CONTRACT.md §24.1).
Leaves this client authenticated (§24.3). Unlike its username-bound twin, this fires the server's login.post_auth reactor hook (§22.5): there was no password step for the event to have been fired at.
func (*Client) WebauthnDiscoverableStart ¶
func (c *Client) WebauthnDiscoverableStart( ctx context.Context, workspace *WebauthnWorkspace, ) (WebauthnChallenge, error)
WebauthnDiscoverableStart performs POST /api/v1/auth/webauthn/authenticate/discoverable/start (CONTRACT.md §24.1).
The PRIMARY-FACTOR ceremony: nothing precedes it, the server sends an empty allowCredentials, and the assertion itself identifies the user.
The workspace still has to be named — a discoverable credential is resolved inside one tenant's isolation boundary — but it comes from this client's own configuration unless overridden, and slugs are accepted. Pass nil for the configured workspace.
func (*Client) WebauthnPolicy ¶
func (c *Client) WebauthnPolicy() *WebauthnPolicyAPI
WebauthnPolicy returns the webauthn_policy management namespace handle.
Per-tenant attestation policy governing the §24 ceremonies, and the compliance report over it.
func (*Client) WebauthnRegisterFinish ¶
func (c *Client) WebauthnRegisterFinish( ctx context.Context, stateToken Sensitive, credentialName string, response any, ) (WebauthnCredential, error)
WebauthnRegisterFinish performs POST /api/v1/auth/webauthn/register/finish (CONTRACT.md §24.1).
response is the authenticator's answer — either a marshalled value or the platform's own JSON string (§24.6a rule 2): Android's registrationResponseJson, a browser's credential.toJSON(). It reaches the server unchanged either way, because it is the input to a signature check over bytes this SDK did not produce.
A 403 is the tenant's attestation policy refusing THIS AUTHENTICATOR — an AAGUID that is not allow-listed, a missing FIDO certification, a revoked status — not a permission problem with the user. The server's message is surfaced verbatim (§24.4 rule 1), because it is the only way the person holding the key learns a different one would work.
func (*Client) WebauthnRegisterStart ¶
func (c *Client) WebauthnRegisterStart(ctx context.Context) (WebauthnChallenge, error)
WebauthnRegisterStart performs POST /api/v1/auth/webauthn/register/start (CONTRACT.md §24.1).
Enrolling a passkey is something a signed-in user does to their own account, so this requires a session and fails client-side with NO wire call when there is none.
A 503 means the tenant's attestation policy requires attestation and the FIDO metadata service has no usable snapshot. That is a server configuration state, not a transient failure, so §24.4 rule 2 deliberately does not retry it.
func (*Client) Webhooks ¶
func (c *Client) Webhooks() *WebhooksAPI
Webhooks returns the webhooks management namespace handle.
Outbound event notifications. Delivery signatures are verified with the §13 helper, which this namespace configures.
type ClientAuthMethod ¶
type ClientAuthMethod string
ClientAuthMethod How a client proves its identity at the token endpoint (RFC 8705 §2, OIDC Core §9 naming). Only the methods AXIAM actually implements are representable. There is deliberately no `none` variant: every AXIAM client is confidential today (see `handle_authorization_code`), and adding a public-client value here before the rest of the server understands one would let an operator register a client whose authentication is silently skipped.
const ( ClientAuthMethodClientSecretPost ClientAuthMethod = "client_secret_post" ClientAuthMethodClientSecretBasic ClientAuthMethod = "client_secret_basic" ClientAuthMethodTLSClientAuth ClientAuthMethod = "tls_client_auth" ClientAuthMethodSelfSignedTLSClientAuth ClientAuthMethod = "self_signed_tls_client_auth" ClientAuthMethodPrivateKeyJWT ClientAuthMethod = "private_key_jwt" )
The ClientAuthMethod values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type ClientProfile ¶
type ClientProfile string
ClientProfile Which security posture a client is registered under (X5.1). This is the FAPI "one switch". FAPI 2.0 is not a single feature but a bundle of constraints — mandatory PAR, mandatory PKCE with `S256`, mandatory strong client authentication, mandatory sender-constrained tokens, and a refusal of every relaxation the base specs permit. Encoding them as one profile rather than a dozen independent booleans means an operator cannot register a client that is *nearly* FAPI, and a reviewer can answer "is this client financial-grade?" by reading one field. The same philosophy as the rate-limit postures: ordinary clients see no behaviour change at all, because [`Standard`](Self::Standard) is the serde default and every row written before schema v38 decodes to it.
const ( ClientProfileStandard ClientProfile = "standard" ClientProfileFapi2 ClientProfile = "fapi2" )
The ClientProfile values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type ComplianceReportEntry ¶
type ComplianceReportEntry struct {
// AAGUID carries the server's aaguid field.
AAGUID *uuid.UUID `json:"aaguid,omitempty"`
// AuthenticatorName carries the server's authenticator_name field.
AuthenticatorName *string `json:"authenticator_name,omitempty"`
// Compliant `false` only for a genuine policy violation
// ([`ComplianceStatus::NonCompliant`]) — a credential with no recorded
// AAGUID ([`ComplianceStatus::Unknown`], D9's pre-X3 case) is always
// `true` here, never reported as a violation.
Compliant bool `json:"compliant"`
// CredentialID carries the server's credential_id field.
CredentialID uuid.UUID `json:"credential_id"`
// Name The credential's user-assigned name (`WebauthnCredential::name`), not
// the owning user's account name.
Name string `json:"name"`
// Reason `None` only when `compliant` and the credential has a recorded AAGUID;
// set for every non-compliant *and* every "unknown" (pre-X3) credential.
Reason *string `json:"reason,omitempty"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
ComplianceReportEntry One credential's compliance outcome (D9).
type ConfigClampedEvent ¶
type ConfigClampedEvent struct {
// Setting is the setting's name, e.g. "WithDecisionMemoTTL".
Setting string
// Requested is the value the caller asked for, rendered.
Requested string
// Effective is the value actually in force, rendered.
Effective string
// ContractReference is the §-reference for the limit, e.g. "§17.1 rule 2".
ContractReference string
}
ConfigClampedEvent is emitted at construction, once per caller-supplied setting the SDK clamped (CONTRACT.md §19.1, §19.2 rule 6).
Two places in the contract require clamping rather than rejecting: §16.1's attempt cap, base delay and delay cap, and §17.1 rule 2's memo TTL. Both clamps are right — rejecting would break a caller whose configuration was merely optimistic, and honoring would let one client become the herd §16 exists to prevent. Doing it SILENTLY is the part that is wrong.
An operator who set a 60-second memo TTL believes they have one. They have five seconds, and their staleness reasoning is off by a factor of twelve with nothing anywhere to say so.
It is NOT emitted for a value already within its limit: an event that fires when nothing happened trains its reader to ignore it.
type Confirmation ¶
type Confirmation = jwks.Confirmation
Confirmation is the RFC 7800 "cnf" claim carried by a sender-constrained token. Its presence changes what the token IS: it is no longer a bearer credential.
type ConflictError ¶
type ConflictError struct {
// Operation is the registry operation that conflicted.
Operation string
// Message is the full, caller-facing description.
Message string
}
ConflictError reports HTTP 409: a uniqueness or state conflict, such as a role name already taken.
Never retried (§27.4 rule 8): a 409 is the server telling the truth, not a transient fault, and a retry produces the identical answer one round-trip later.
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
func (*ConflictError) Is ¶
func (e *ConflictError) Is(target error) bool
Is matches both ErrConflict and the §2 ErrAuthz sentinel.
type ConsentView ¶
type ConsentView struct {
// AcceptedAt carries the server's accepted_at field.
AcceptedAt string `json:"accepted_at"`
// ConsentType What was consented to, e.g. `terms_of_service` or
// `oidc_scope_release:<client_id>`.
ConsentType string `json:"consent_type"`
// Version The document version or, for a scope release, the consented scopes.
Version string `json:"version"`
// Withdrawable Whether this record can be withdrawn here. `false` for
// `terms_of_service`: withdrawing it is not a consent operation but an
// erasure, and it has its own endpoint with its own grace period.
// Reported rather than silently absent so the self-service page can show
// the record and explain it.
Withdrawable bool `json:"withdrawable"`
}
ConsentView One consent record, as the subject sees it.
type CreateCACertificateRequest ¶
type CreateCACertificateRequest struct {
// IntermediateSubject Common name for the signing intermediate — `vault_pki` custody only.
// Under that custodian Vault generates a root and an intermediate beneath
// it, and this names the second. Defaults to the root's subject with
// `Intermediate Authority` appended. Ignored by every other custodian,
// which produces one self-signed CA and has no second certificate to
// name.
IntermediateSubject *string `json:"intermediate_subject,omitempty"`
// IntermediateValidityDays Validity of the signing intermediate, in days. Defaults to the root's.
IntermediateValidityDays *int `json:"intermediate_validity_days,omitempty"`
// IssueFromRoot Issue leaves straight from the generated root instead of creating an
// intermediate. `vault_pki` custody only, and off by default. The default
// is the safer one: a root that signs only an intermediate can have that
// intermediate revoked and replaced without redistributing the trust
// anchor, and a root that signs leaves cannot.
IssueFromRoot *bool `json:"issue_from_root,omitempty"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// Subject carries the server's subject field.
Subject string `json:"subject"`
// ValidityDays Validity duration in days.
ValidityDays int `json:"validity_days"`
}
CreateCACertificateRequest is the CreateCACertificateRequest schema from the server's OpenAPI document.
type CreateCertificateRequest ¶
type CreateCertificateRequest struct {
// CertType carries the server's cert_type field.
CertType CertificateType `json:"cert_type"`
// IssuerCAID carries the server's issuer_ca_id field.
IssuerCAID uuid.UUID `json:"issuer_ca_id"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Subject carries the server's subject field.
Subject string `json:"subject"`
// ValidityDays Validity duration in days.
ValidityDays int `json:"validity_days"`
}
CreateCertificateRequest is the CreateCertificateRequest schema from the server's OpenAPI document.
type CreateFederationConfigRequest ¶
type CreateFederationConfigRequest struct {
// AllowTenantInheritance Whether tenants of this organization may inherit this provider. Only
// meaningful on a config in the organization-scope tenant.
AllowTenantInheritance *bool `json:"allow_tenant_inheritance,omitempty"`
// AllowedAlgorithms Accepted JWT signing algorithms (OIDC) or signature algorithms (SAML).
// Defaults to `["RS256"]` when not provided (CQ-B40/REQ-14 AC-5).
AllowedAlgorithms []string `json:"allowed_algorithms,omitempty"`
// AllowedIssuerTenants External IdP tenant identifiers accepted when the provider publishes a
// templated issuer (Entra ID's `{tenantid}`).
AllowedIssuerTenants []string `json:"allowed_issuer_tenants,omitempty"`
// AppleKeyID Apple Key ID of the `.p8` signing key (10 characters). With both Apple
// identifiers set, `client_secret` is the `.p8` key itself and AXIAM
// mints a fresh five-minute client secret per token exchange.
AppleKeyID *string `json:"apple_key_id,omitempty"`
// AppleTeamID Apple Team ID (10 characters).
AppleTeamID *string `json:"apple_team_id,omitempty"`
// AttributeMap Maps external IdP attributes to AXIAM user fields.
AttributeMap *any `json:"attribute_map,omitempty"`
// AuthorizationEndpoint OAuth2-variant authorization endpoint. Required for `OAuth2`.
AuthorizationEndpoint *string `json:"authorization_endpoint,omitempty"`
// ButtonIcon Sign-in-button icon for a **generic** provider, as a base64 raster data
// URL (`data:image/png;base64,…`), already cropped to
// `PROVIDER_ICON_SIZE_PX` square by the client. Refused for the branded
// kinds: Google, Apple and Microsoft all publish sign-in-button rules
// that require their own mark, so substituting a picture would produce a
// button that breaks the guidelines it exists to follow.
ButtonIcon *string `json:"button_icon,omitempty"`
// ClientID OAuth2 client ID registered with the external IdP.
ClientID string `json:"client_id"`
// ClientSecret OAuth2 client secret registered with the external IdP.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ClientSecret Sensitive `json:"client_secret"`
// IdpSigningCertPEM PEM-encoded X.509 certificate for verifying SAML assertions or OIDC
// signatures (CQ-B40/REQ-14 AC-5). Required for SAML configs.
IdpSigningCertPEM *string `json:"idp_signing_cert_pem,omitempty"`
// MetadataURL OIDC discovery URL or SAML metadata URL.
MetadataURL *string `json:"metadata_url,omitempty"`
// Protocol Federation protocol: "OidcConnect" or "Saml".
Protocol string `json:"protocol"`
// Provider Display name for the identity provider (e.g., "Google", "Okta").
Provider string `json:"provider"`
// ProviderKind Which provider this is: `google`, `github`, `facebook`, `apple`,
// `microsoft`, `generic_oidc`, `generic_oauth2` or `generic_saml`.
// Selects the sign-in button's branding, the per-kind defaults, and the
// key on which a tenant config overrides an inherited organization one.
// Omitted ⇒ derived from `protocol`, which is what every config written
// before this field existed means.
ProviderKind *string `json:"provider_kind,omitempty"`
// ProviderSlug Operator-chosen identifier, **required** for the `generic_*` kinds and
// refused for the branded ones.
ProviderSlug *string `json:"provider_slug,omitempty"`
// RequirePkce Send PKCE on the authorization request. Forced on for `OAuth2`.
RequirePkce *bool `json:"require_pkce,omitempty"`
// Scopes Scopes to request. Omitted or empty ⇒ the per-kind default.
Scopes []string `json:"scopes,omitempty"`
// TokenEndpoint OAuth2-variant token endpoint. Required for `OAuth2`.
TokenEndpoint *string `json:"token_endpoint,omitempty"`
// TokenExchange carries the server's token_exchange field.
TokenExchange *TokenExchangeTrustRequest `json:"token_exchange,omitempty"`
// UserinfoEndpoint OAuth2-variant userinfo endpoint. Required for `OAuth2`.
UserinfoEndpoint *string `json:"userinfo_endpoint,omitempty"`
}
CreateFederationConfigRequest is the CreateFederationConfigRequest schema from the server's OpenAPI document.
type CreateGroupRequest ¶
type CreateGroupRequest struct {
// Description carries the server's description field.
Description string `json:"description"`
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
}
CreateGroupRequest is the CreateGroupRequest schema from the server's OpenAPI document.
type CreateIntermediateCARequest ¶
type CreateIntermediateCARequest struct {
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// ParentCAID The organization CA that signs it.
ParentCAID uuid.UUID `json:"parent_ca_id"`
// Subject Subject for the signing CA, e.g. `CN=ACME R&D Signing CA`.
Subject string `json:"subject"`
// ValidityDays Validity duration in days, capped to the parent's own expiry.
ValidityDays int `json:"validity_days"`
}
CreateIntermediateCARequest Body of `POST .../tenants/{tenant_id}/signing-cas`.
type CreateNotificationRuleRequest ¶
type CreateNotificationRuleRequest struct {
// Description Description of what this rule monitors.
Description string `json:"description"`
// Events Event types that trigger this rule.
Events []NotificationEventType `json:"events"`
// Name Human-readable name for the rule.
Name string `json:"name"`
// RecipientEmails Email addresses to notify.
RecipientEmails []string `json:"recipient_emails"`
}
CreateNotificationRuleRequest is the CreateNotificationRuleRequest schema from the server's OpenAPI document.
type CreateOAuth2ClientRequest ¶
type CreateOAuth2ClientRequest struct {
// AuthnRequestParams X7.1 — whether this client's authorization requests may carry the
// OpenID Connect authentication-request parameters (`prompt`, `max_age`,
// `acr_values`, `claims`, `id_token_hint`, `login_hint`, `display`,
// `ui_locales`, `claims_locales`). `"ignore"` (the default) is what every
// AXIAM client has always done: they are dropped and reach no decision.
// `"honour"` opts in, and is **refused on a `fapi2` client** at both this
// gate and the authorization endpoint — the two are different answers
// to the same question about what a request from this client means.
AuthnRequestParams *AuthnRequestParamsMode `json:"authn_request_params,omitempty"`
// BackchannelLogoutURI B5 — where OIDC back-channel logout tokens are delivered. Omit for a
// client that does not participate.
BackchannelLogoutURI *string `json:"backchannel_logout_uri,omitempty"`
// BrowserSSO X7.3 — whether an unauthenticated authorization request from this
// client may be answered with a redirect to the login page rather than
// the `401` AXIAM answers today. Accepted and stored, but **nothing reads
// it yet**: the login hop it gates is a later wave. Unlike
// `authn_request_params` it is permitted on a `fapi2` client, because it
// relaxes nothing — it decides only how an anonymous browser is
// answered.
BrowserSSO *bool `json:"browser_sso,omitempty"`
// DpopBoundAccessTokens RFC 9449 §5.2 — issue DPoP-bound (sender-constrained) access tokens
// to this client. Independent of both the authentication method and
// `tls_client_certificate_bound_access_tokens`; a client may ask for both
// constraints, and a token carrying both must satisfy both.
DpopBoundAccessTokens *bool `json:"dpop_bound_access_tokens,omitempty"`
// DpopRequireNonce RFC 9449 §8 — require this client's DPoP proofs to carry a
// server-issued nonce. **Not implemented in this build (SEC-097).**
// `true` is refused with `400`; only `false` (the default) is accepted.
// Nothing reads the stored value, so accepting `true` would persist and
// echo back a security switch that does nothing. DPoP proofs are made
// single-use at the token endpoint by `jti` replay detection instead —
// see `docs/security-profiles.md`.
DpopRequireNonce *bool `json:"dpop_require_nonce,omitempty"`
// GrantTypes Grant types this client is authorized to use.
GrantTypes []string `json:"grant_types"`
// JWKS RFC 7591 §2 — the client's public key set, inline, for
// `private_key_jwt`. Exactly one of `jwks` and `jwks_uri` may be set.
JWKS *string `json:"jwks,omitempty"`
// JWKSURI RFC 7591 §2 — where the client publishes its public key set. Must be
// an absolute `https` URL, and is fetched through the SSRF-guarded JWKS
// cache, which refuses private and loopback addresses.
JWKSURI *string `json:"jwks_uri,omitempty"`
// Name Human-readable name for the client.
Name string `json:"name"`
// PostLogoutRedirectUris B5 — allow-list for RP-initiated logout's `post_logout_redirect_uri`.
// Separate from `redirect_uris` on purpose: that list receives
// authorization codes, this one receives a browser after logout.
PostLogoutRedirectUris []string `json:"post_logout_redirect_uris,omitempty"`
// Profile X5.1 — the security posture this client is registered under.
// `"standard"` (the default) is every AXIAM client that has ever existed.
// `"fapi2"` turns on the whole FAPI 2.0 constraint bundle at once, and
// the registration is refused unless it also sets `require_par`, a strong
// `token_endpoint_auth_method` (either mTLS method or `private_key_jwt`),
// and at least one sender-constraining mechanism
// (`tls_client_certificate_bound_access_tokens` or
// `dpop_bound_access_tokens`). See the FAPI operator guide.
Profile *ClientProfile `json:"profile,omitempty"`
// RedirectUris Allowed redirect URIs (must be HTTPS, except localhost for dev).
// SEC-089: this list doubles as the token-exchange audience allow-list
// — adding a URI here also authorises it as a token audience for this
// client, so review additions on exchange-capable clients with that in
// mind (see `docs/api/token-exchange.md#audience`).
RedirectUris []string `json:"redirect_uris"`
// RequirePar B5 — require this client to push its authorization parameters to
// `/oauth2/par` (RFC 9126) rather than sending them through the browser.
RequirePar *bool `json:"require_par,omitempty"`
// Scopes Scopes the client may request.
Scopes []string `json:"scopes"`
// SelfSignedTLSClientAuthThumbprints Accepted certificate thumbprints for `self_signed_tls_client_auth`, as
// base64url-unpadded SHA-256 digests of the DER certificate (the same
// `x5t#S256` encoding as the `cnf` claim). More than one permits an
// overlapping rotation.
SelfSignedTLSClientAuthThumbprints []string `json:"self_signed_tls_client_auth_thumbprints,omitempty"`
// TLSClientAuthSanDns RFC 8705 §2.1.2 — expected `dNSName` SAN.
TLSClientAuthSanDns *string `json:"tls_client_auth_san_dns,omitempty"`
// TLSClientAuthSanURI RFC 8705 §2.1.2 — expected `uniformResourceIdentifier` SAN.
TLSClientAuthSanURI *string `json:"tls_client_auth_san_uri,omitempty"`
// TLSClientAuthSubjectDn RFC 8705 §2.1.2 — expected certificate subject DN, RFC 4514 form.
// Exactly one of the three `tls_client_auth_*` parameters may be set.
TLSClientAuthSubjectDn *string `json:"tls_client_auth_subject_dn,omitempty"`
// TLSClientCertificateBoundAccessTokens RFC 8705 §3.4 — issue certificate-bound (sender-constrained) access
// tokens to this client. Independent of the authentication method.
TLSClientCertificateBoundAccessTokens *bool `json:"tls_client_certificate_bound_access_tokens,omitempty"`
// TokenEndpointAuthMethod X5.1 — how this client authenticates at the token endpoint (RFC 8705
// §2). Defaults to `client_secret_post`.
TokenEndpointAuthMethod *ClientAuthMethod `json:"token_endpoint_auth_method,omitempty"`
}
CreateOAuth2ClientRequest is the CreateOAuth2ClientRequest schema from the server's OpenAPI document.
type CreatePGPKeyRequest ¶
type CreatePGPKeyRequest struct {
// Algorithm carries the server's algorithm field.
Algorithm PGPKeyAlgorithm `json:"algorithm"`
// Email Email for the OpenPGP User ID.
Email string `json:"email"`
// Name carries the server's name field.
Name string `json:"name"`
// Purpose carries the server's purpose field.
Purpose PGPKeyPurpose `json:"purpose"`
}
CreatePGPKeyRequest is the CreatePGPKeyRequest schema from the server's OpenAPI document.
type CreatePermissionRequest ¶
type CreatePermissionRequest struct {
// Action carries the server's action field.
Action string `json:"action"`
// Description carries the server's description field.
Description string `json:"description"`
}
CreatePermissionRequest is the CreatePermissionRequest schema from the server's OpenAPI document.
type CreateReactorRequest ¶
type CreateReactorRequest struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// Events Event names from the registry (`GET /api/v1/reactors/events`).
Events []string `json:"events"`
// FailurePolicy carries the server's failure_policy field.
FailurePolicy *FailurePolicy `json:"failure_policy,omitempty"`
// Mode carries the server's mode field.
Mode ReactorMode `json:"mode"`
// Name carries the server's name field.
Name string `json:"name"`
// Priority carries the server's priority field.
Priority *int `json:"priority,omitempty"`
// TimeoutMs Omit to take the 500 ms default. Capped at 5 000 ms.
TimeoutMs *int `json:"timeout_ms,omitempty"`
}
CreateReactorRequest is the CreateReactorRequest schema from the server's OpenAPI document.
type CreateResourceRequest ¶
type CreateResourceRequest struct {
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
// ParentID carries the server's parent_id field.
ParentID *uuid.UUID `json:"parent_id,omitempty"`
// ResourceType carries the server's resource_type field.
ResourceType string `json:"resource_type"`
}
CreateResourceRequest is the CreateResourceRequest schema from the server's OpenAPI document.
type CreateRoleRequest ¶
type CreateRoleRequest struct {
// Description carries the server's description field.
Description string `json:"description"`
// IsGlobal carries the server's is_global field.
IsGlobal bool `json:"is_global"`
// Name carries the server's name field.
Name string `json:"name"`
}
CreateRoleRequest is the CreateRoleRequest schema from the server's OpenAPI document.
type CreateSCIMTokenRequest ¶
type CreateSCIMTokenRequest struct {
// ExpiresInDays Lifetime in days. Defaults to the deployment maximum, and is refused
// above it.
ExpiresInDays *int64 `json:"expires_in_days,omitempty"`
// Name Operator-facing label, e.g. `"okta-production"`.
Name string `json:"name"`
// UserID The tenant user the token authenticates as. Must already hold
// `scim:provision` — see [`create`].
UserID uuid.UUID `json:"user_id"`
}
CreateSCIMTokenRequest is the CreateSCIMTokenRequest schema from the server's OpenAPI document.
type CreateSCIMTokenResponse ¶
type CreateSCIMTokenResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// CreatedBy carries the server's created_by field.
CreatedBy uuid.UUID `json:"created_by"`
// ExpiresAt carries the server's expires_at field.
ExpiresAt string `json:"expires_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// LastUsedAt carries the server's last_used_at field.
LastUsedAt *string `json:"last_used_at,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
// ProvisioningToken The plaintext handle — shown once, never retrievable again.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ProvisioningToken Sensitive `json:"provisioning_token"`
// RevokedAt carries the server's revoked_at field.
RevokedAt *string `json:"revoked_at,omitempty"`
// Status carries the server's status field.
Status SCIMTokenStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
CreateSCIMTokenResponse The one-time reveal. Same shape as service-account creation: the secret is returned once and only its hash is kept.
type CreateScopeRequest ¶
type CreateScopeRequest struct {
// Description carries the server's description field.
Description string `json:"description"`
// Name carries the server's name field.
Name string `json:"name"`
}
CreateScopeRequest is the CreateScopeRequest schema from the server's OpenAPI document.
type CreateServiceAccountRequest ¶
type CreateServiceAccountRequest struct {
// Description Optional human-readable description of the account's purpose.
Description *string `json:"description,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
}
CreateServiceAccountRequest is the CreateServiceAccountRequest schema from the server's OpenAPI document.
type CreateTenantRequest ¶
type CreateTenantRequest struct {
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
// Slug carries the server's slug field.
Slug string `json:"slug"`
}
CreateTenantRequest Request body for tenant creation (organization_id comes from the URL path).
type CreateUserRequest ¶
type CreateUserRequest struct {
// Email carries the server's email field.
Email string `json:"email"`
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Opaque carries the server's opaque field.
Opaque *OpaqueEnrollmentPayload `json:"opaque,omitempty"`
// Password carries the server's password field.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
Password Sensitive `json:"password"`
// Username carries the server's username field.
Username string `json:"username"`
}
CreateUserRequest is the CreateUserRequest schema from the server's OpenAPI document.
type CreateWebhookRequest ¶
type CreateWebhookRequest struct {
// Events Event types to subscribe to (e.g. `["user.created", "auth.login"]`).
Events []string `json:"events"`
// RetryPolicy carries the server's retry_policy field.
RetryPolicy *RetryPolicy `json:"retry_policy,omitempty"`
// Secret HMAC-SHA256 shared secret for signing payloads.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
Secret Sensitive `json:"secret"`
// URL The HTTPS URL to deliver events to.
URL string `json:"url"`
}
CreateWebhookRequest is the CreateWebhookRequest schema from the server's OpenAPI document.
type DPoPJtiStore ¶
DPoPJtiStore is the §21.7.2 check 8 replay guard.
type DPoPRequest ¶
DPoPRequest carries what VerifyDPoPProof needs about the current request.
type DeviceAuthorization ¶
type DeviceAuthorization struct {
// DeviceCode is the device's polling credential (§14.5 secret).
DeviceCode Sensitive
// UserCode is the short code the human types into the verification page.
UserCode string
// VerificationURI is where the human goes to enter UserCode.
VerificationURI string
// VerificationURIComplete embeds the user code in the URI, when the server
// sent one — prefer it when the device can render a QR code. Never
// synthesised by concatenation when absent (§14.3): its format is the
// server's to choose.
VerificationURIComplete string
// ExpiresIn is the seconds until the grant expires. Polling stops here
// (§14.2 rule 4).
ExpiresIn int
// Interval is the seconds between polls, from the response, defaulted to
// 5 s when the server omitted it (§14.2 rule 2).
Interval int
}
DeviceAuthorization is the DeviceAuthorizationResponse — what the device shows its user, plus the device_code it polls with (§14.1).
DeviceCode is Sensitive (§14.5): a bearer credential for the lifetime of the grant. UserCode deliberately is NOT — it exists to be read aloud and typed by a human, and wrapping it would defeat the one thing it is for. Neither may be logged; displaying UserCode is the caller's job.
type DeviceAuthorizeParams ¶
type DeviceAuthorizeParams struct {
// Scope is the space-separated scope string to request. Omitted when empty.
Scope string
// TenantID supplies the mandatory `tenant_id` query parameter (§12.1
// note 2).
TenantID string
// Configuration is a pre-fetched discovery document; fetched via
// OidcDiscover when zero.
Configuration *OidcConfiguration
}
DeviceAuthorizeParams are the arguments to Client.DeviceAuthorize (CONTRACT.md §14.1).
type DeviceLoginParams ¶
type DeviceLoginParams struct {
// Scope is the space-separated scope string to request.
Scope string
// TenantID supplies the `tenant_id` query parameter.
TenantID string
// Configuration is a pre-fetched discovery document.
Configuration *OidcConfiguration
// OnUserCode is called with the DeviceAuthorization BEFORE the first poll
// (§14.3 rule 2), so the caller can display the code. The SDK never prints
// it: what the device does with it is the application's decision.
//
// Returning an error aborts the login without polling — a device that
// cannot display the code has no reason to wait for an approval nobody can
// give.
OnUserCode func(DeviceAuthorization) error
// AdoptAsCredential mirrors LoginClientCredentialsParams: when true, the
// issued access token becomes this client's Authorization header.
//
// §14.3 rule 4 (contract 1.7) defers to the §12.1 adoption MAY, and this
// SDK's settled posture there is an opt-in flag — so DeviceLogin takes the
// same one rather than inventing a second posture.
AdoptAsCredential bool
}
DeviceLoginParams are the arguments to Client.DeviceLogin (§14.3).
type DevicePollParams ¶
type DevicePollParams struct {
// DeviceCode comes from DeviceAuthorization.
DeviceCode Sensitive
// TenantID supplies the `tenant_id` query parameter.
TenantID string
// Configuration is a pre-fetched discovery document.
Configuration *OidcConfiguration
}
DevicePollParams are the arguments to Client.DevicePoll (§14.1).
type EmailConfig ¶
type EmailConfig struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// FromEmail carries the server's from_email field.
FromEmail string `json:"from_email"`
// FromName carries the server's from_name field.
FromName string `json:"from_name"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Provider carries the server's provider field.
Provider ProviderConfig `json:"provider"`
// ReplyTo carries the server's reply_to field.
ReplyTo *string `json:"reply_to,omitempty"`
// Scope carries the server's scope field.
Scope SettingsScope `json:"scope"`
// ScopeID The org_id or tenant_id this config belongs to.
ScopeID uuid.UUID `json:"scope_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
EmailConfig Fully resolved email configuration (all fields present).
type EmailConfigAPI ¶
type EmailConfigAPI struct {
// contains filtered or unexported fields
}
EmailConfigAPI is the email_config namespace handle.
Transactional-mail transport, configurable at organization level and overridable per tenant.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*EmailConfigAPI) DeleteOrg ¶
func (a *EmailConfigAPI) DeleteOrg(ctx context.Context) error
DeleteOrg issues DELETE /api/v1/organizations/{org_id}/email-config.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*EmailConfigAPI) DeleteTenant ¶
func (a *EmailConfigAPI) DeleteTenant(ctx context.Context) error
DeleteTenant issues DELETE /api/v1/tenants/{tenant_id}/email-config.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*EmailConfigAPI) ForTenant ¶
func (a *EmailConfigAPI) ForTenant(tenantID uuid.UUID) *EmailConfigAPI
ForTenant addresses a different tenant than the client's own (§27.4 rule 3).
Returns a new handle; the original is unchanged.
func (*EmailConfigAPI) GetOrg ¶
func (a *EmailConfigAPI) GetOrg(ctx context.Context) (EmailConfig, error)
GetOrg issues GET /api/v1/organizations/{org_id}/email-config.
func (*EmailConfigAPI) GetTenant ¶
func (a *EmailConfigAPI) GetTenant(ctx context.Context) (EmailConfigOverride, error)
GetTenant issues GET /api/v1/tenants/{tenant_id}/email-config.
func (*EmailConfigAPI) InOrg ¶
func (a *EmailConfigAPI) InOrg(orgID uuid.UUID) *EmailConfigAPI
InOrg addresses a different organization than the client's own.
§27.4 rule 3: the client's organization is the default, and a platform-admin token legitimately overrides it. Returns a new handle; the original is unchanged.
func (*EmailConfigAPI) SetOrg ¶
func (a *EmailConfigAPI) SetOrg(ctx context.Context, body SetOrgEmailConfig) (EmailConfig, error)
SetOrg issues PUT /api/v1/organizations/{org_id}/email-config.
This is a REPLACEMENT, not a patch (§27.4 rule 5). Every field of the body is required, and what you do not carry over from a prior read is not preserved — it is overwritten. Read first, change the field you mean, send the whole thing back.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*EmailConfigAPI) SetTenant ¶
func (a *EmailConfigAPI) SetTenant(ctx context.Context, body EmailConfigOverride) (EmailConfigOverride, error)
SetTenant issues PUT /api/v1/tenants/{tenant_id}/email-config.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*EmailConfigAPI) TestOrg ¶
func (a *EmailConfigAPI) TestOrg(ctx context.Context) (EmailTestResult, error)
TestOrg issues POST /api/v1/organizations/{org_id}/email-config/test.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*EmailConfigAPI) TestTenant ¶
func (a *EmailConfigAPI) TestTenant(ctx context.Context) (EmailTestResult, error)
TestTenant issues POST /api/v1/tenants/{tenant_id}/email-config/test.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type EmailConfigOverride ¶
type EmailConfigOverride struct {
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// FromEmail carries the server's from_email field.
FromEmail *string `json:"from_email,omitempty"`
// FromName carries the server's from_name field.
FromName *string `json:"from_name,omitempty"`
// Provider carries the server's provider field.
Provider *ProviderConfig `json:"provider,omitempty"`
// ReplyTo `Some(None)` explicitly clears reply-to; `None` inherits.
ReplyTo *string `json:"reply_to,omitempty"`
}
EmailConfigOverride Partial tenant overrides for email configuration. `None` = inherit from org baseline.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type EmailTestResult ¶
type EmailTestResult struct {
// MessageID The provider's message id, when it returns one.
MessageID *string `json:"message_id,omitempty"`
// Provider Which provider the effective configuration resolved to.
Provider string `json:"provider"`
// To Where the message went — always the caller's own address.
To string `json:"to"`
}
EmailTestResult What a test send did.
type EmailVerificationPolicy ¶
type EmailVerificationPolicy struct {
// EmailVerificationGracePeriodHours carries the server's email_verification_grace_period_hours field.
EmailVerificationGracePeriodHours int `json:"email_verification_grace_period_hours"`
// EmailVerificationRequired carries the server's email_verification_required field.
EmailVerificationRequired bool `json:"email_verification_required"`
}
EmailVerificationPolicy Email verification requirements.
type EncryptRequest ¶
type EncryptRequest struct {
// DataBase64 Base64-encoded plaintext to encrypt.
DataBase64 string `json:"data_base64"`
}
EncryptRequest Request body for encrypting data.
type EncryptedExport ¶
type EncryptedExport struct {
// CiphertextArmored ASCII-armored PGP encrypted data.
CiphertextArmored string `json:"ciphertext_armored"`
// RecipientKeyID carries the server's recipient_key_id field.
RecipientKeyID uuid.UUID `json:"recipient_key_id"`
}
EncryptedExport Result of encrypting data with a PGP public key.
type ExchangedToken ¶
type ExchangedToken struct {
// AccessToken is the issued token (§15.5 secret).
AccessToken Sensitive
// IssuedTokenType is what the server actually issued. Mandatory in
// RFC 8693 §2.2.1 and surfaced rather than dropped (§15.2 rule 6), so a
// client that asked for one type and got another can tell.
IssuedTokenType string
// TokenType is the token type (Bearer).
TokenType string
// ExpiresIn is the lifetime in seconds — never longer than the subject
// token's remaining life.
ExpiresIn int
// Scope is the GRANTED scope, which may be narrower than requested even on
// success (§15.2 rule 7). Read it rather than assuming the request was
// honoured verbatim.
Scope string
}
ExchangedToken is the result of an exchange (wire schema TokenExchangeResponse, §15.1).
There is NO RefreshToken field, and that is deliberate (§15.2 rule 4). RFC 8693 issues none, so the type cannot represent one: an application that wants a fresh exchanged token re-runs the exchange. This result also never enters the §9 single-flight refresh guard — there is nothing to refresh.
type FailurePolicy ¶
type FailurePolicy string
FailurePolicy What the server does when an interceptor does not produce a usable reply — timeout, transport failure, bad signature, stale nonce, or a patch the allow-list rejects.
const ( FailurePolicyFailClosed FailurePolicy = "fail_closed" FailurePolicyFailOpen FailurePolicy = "fail_open" )
The FailurePolicy values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type FederationAPI ¶
type FederationAPI struct {
// contains filtered or unexported fields
}
FederationAPI is the federation namespace handle.
Upstream IdP configuration and the per-user links it produces.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*FederationAPI) CreateConfig ¶
func (a *FederationAPI) CreateConfig(ctx context.Context, body CreateFederationConfigRequest) (FederationConfigResponse, error)
CreateConfig issues POST /api/v1/federation-configs.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*FederationAPI) DeleteConfig ¶
DeleteConfig issues DELETE /api/v1/federation-configs/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*FederationAPI) DeleteLink ¶
DeleteLink issues DELETE /api/v1/federation-links/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*FederationAPI) GetConfig ¶
func (a *FederationAPI) GetConfig(ctx context.Context, id uuid.UUID) (FederationConfigResponse, error)
GetConfig issues GET /api/v1/federation-configs/{id}.
func (*FederationAPI) ListConfigs ¶
func (a *FederationAPI) ListConfigs(ctx context.Context, page PageRequest) (Page[FederationConfigResponse], error)
ListConfigs issues GET /api/v1/federation-configs.
func (*FederationAPI) ListConfigsAll ¶
func (a *FederationAPI) ListConfigsAll(ctx context.Context, start PageRequest) ([]FederationConfigResponse, error)
ListConfigsAll walks federation.list_configs to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*FederationAPI) ListUserLinks ¶
func (a *FederationAPI) ListUserLinks(ctx context.Context, userID uuid.UUID) ([]FederationLinkResponse, error)
ListUserLinks issues GET /api/v1/federation-links/user/{user_id}.
func (*FederationAPI) OIDCAuthorize ¶
func (a *FederationAPI) OIDCAuthorize(ctx context.Context, body OIDCAuthorizeRequest) (OIDCAuthorizeResponse, error)
OIDCAuthorize issues POST /api/v1/federation/oidc/authorize.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*FederationAPI) OIDCCallback ¶
func (a *FederationAPI) OIDCCallback(ctx context.Context, body OIDCCallbackRequest) (OIDCCallbackResponse, error)
OIDCCallback issues POST /api/v1/federation/oidc/callback.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*FederationAPI) UpdateConfig ¶
func (a *FederationAPI) UpdateConfig(ctx context.Context, id uuid.UUID, body UpdateFederationConfigRequest) (FederationConfigResponse, error)
UpdateConfig issues PUT /api/v1/federation-configs/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type FederationConfigResponse ¶
type FederationConfigResponse struct {
// AllowTenantInheritance Whether tenants of this organization may inherit this provider.
AllowTenantInheritance bool `json:"allow_tenant_inheritance"`
// AllowedAlgorithms Accepted signing algorithms. Returned for OIDC and SAML; meaningless,
// and therefore empty, for the OAuth2 variant.
AllowedAlgorithms []string `json:"allowed_algorithms"`
// AllowedIssuerTenants Accepted external IdP tenants for a templated issuer.
AllowedIssuerTenants []string `json:"allowed_issuer_tenants"`
// AppleKeyID Apple Key ID.
AppleKeyID *string `json:"apple_key_id,omitempty"`
// AppleTeamID Apple Team ID. Not secret — the `.p8` key is, and it is never
// returned.
AppleTeamID *string `json:"apple_team_id,omitempty"`
// AttributeMap carries the server's attribute_map field.
AttributeMap any `json:"attribute_map"`
// AuthorizationEndpoint OAuth2-variant authorization endpoint.
AuthorizationEndpoint *string `json:"authorization_endpoint,omitempty"`
// ButtonIcon Custom sign-in-button icon, when one is set.
ButtonIcon *string `json:"button_icon,omitempty"`
// ClientID carries the server's client_id field.
ClientID string `json:"client_id"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// EffectiveScopes The per-kind default that an empty `scopes` resolves to. Returned so
// the admin UI can show what will actually be requested without
// duplicating the table.
EffectiveScopes []string `json:"effective_scopes"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// HasBundledMark Whether AXIAM ships this provider's own mark. When true the button uses
// it and `button_icon` is refused; when false the button reads "Sign in
// with <provider>" and may carry a custom icon.
HasBundledMark bool `json:"has_bundled_mark"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// MetadataURL carries the server's metadata_url field.
MetadataURL *string `json:"metadata_url,omitempty"`
// MintsClientSecret Whether AXIAM mints this provider's client secret itself, per exchange,
// rather than sending a stored one. True only for an Apple config with
// both identifiers set.
MintsClientSecret bool `json:"mints_client_secret"`
// PkceRequired Whether PKCE is sent on the authorization request. Always true for the
// OAuth2 variant regardless of the stored flag.
PkceRequired bool `json:"pkce_required"`
// Protocol carries the server's protocol field.
Protocol string `json:"protocol"`
// Provider carries the server's provider field.
Provider string `json:"provider"`
// ProviderKind Which provider this is. Derived from `protocol` for a config written
// before the field existed.
ProviderKind string `json:"provider_kind"`
// ProviderSlug Operator-chosen identifier for a `generic_*` kind.
ProviderSlug *string `json:"provider_slug,omitempty"`
// Scopes Scopes as stored. Empty means "use the per-kind default"; see
// `effective_scopes`.
Scopes []string `json:"scopes"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// TokenEndpoint OAuth2-variant token endpoint.
TokenEndpoint *string `json:"token_endpoint,omitempty"`
// TokenExchange X4 external token-exchange trust.
TokenExchange TokenExchangeTrustResponse `json:"token_exchange"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
// UserinfoEndpoint OAuth2-variant userinfo endpoint.
UserinfoEndpoint *string `json:"userinfo_endpoint,omitempty"`
}
FederationConfigResponse Federation config response -- omits client_secret.
type FederationLinkResponse ¶
type FederationLinkResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// ExternalEmail carries the server's external_email field.
ExternalEmail *string `json:"external_email,omitempty"`
// ExternalSubject carries the server's external_subject field.
ExternalSubject string `json:"external_subject"`
// FederationConfigID carries the server's federation_config_id field.
FederationConfigID uuid.UUID `json:"federation_config_id"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
FederationLinkResponse is the FederationLinkResponse schema from the server's OpenAPI document.
type FederationProvider ¶
type FederationProvider struct {
// ID is the config id, to be echoed back to the matching start operation.
//
// Pass it through unmodified: inheritance is resolved server-side (§12.1
// note 13) and this id is how the server is told what resolution produced.
ID string
// ProviderKind is which provider this is, for the button's branding —
// "google", "github", "generic_oidc", … NOT what selects the start
// operation; see Protocol.
ProviderKind string
// DisplayName is the operator's display name for the provider.
DisplayName string
// Protocol is "OidcConnect", "Saml" or "OAuth2" — the value that selects
// which start operation to call (§12.1 note 10). Compare against
// ProtocolOidcConnect, ProtocolOAuth2 and ProtocolSaml.
//
// Kept as the wire string rather than narrowed to a Go enum: the server
// owns this vocabulary, and a value added server-side must not become a
// decode failure for the whole list.
//
// An OAuth2 provider issues NO ID token — the server authenticates by
// calling a configured userinfo endpoint, so there is no signature, no
// nonce and no aud (§12.1 note 11). A surface rendering these buttons
// SHOULD make that distinction visible rather than presenting the two as
// equivalent.
Protocol string
// HasBundledMark reports whether AXIAM ships this provider's own sign-in
// mark, which its button must then use. False for the generic kinds,
// whose buttons read "Sign in with <DisplayName>" and use ButtonIcon
// where the operator uploaded one.
HasBundledMark bool
// Inherited is true when the provider is inherited from the organization
// rather than configured on this tenant (§12.1 note 13). Informational —
// it is not needed to sign in, and nothing in this SDK computes it.
Inherited bool
// ButtonIcon is the operator's uploaded button icon as a bounded raster
// data: URL. Empty for most providers: present only for generic ones
// whose operator uploaded a mark.
ButtonIcon string
}
FederationProvider is one sign-in button (wire schema PublicFederationProvider, CONTRACT.md §12.1).
This is an UNAUTHENTICATED response and carries only what a button needs. There is no client_id, no metadata_url, no endpoint URL and no secret — absent by construction rather than filtered out — and §12.1 note 9 forbids an SDK from expecting one.
type FederationProviderList ¶
type FederationProviderList struct {
// Providers are the providers to offer, in a stable server-defined order.
Providers []FederationProvider
}
FederationProviderList is the result of SsoProviders (wire schema PublicFederationProvidersResponse).
An EMPTY Providers slice is a normal success, never an error (§12.1 note 9).
type FieldError ¶
type FieldError struct {
// Field is the offending field's name, as the server names it.
Field string `json:"field"`
// Message is what is wrong with it.
Message string `json:"message"`
}
FieldError is one field-level complaint inside a *ValidationError.
type GeneratedCACertificate ¶
type GeneratedCACertificate struct {
// ChainPEM The issuers above [`Self::public_cert_pem`], concatenated PEM, nearest
// issuer first and the root last. `None` for a CA that is its own root,
// which is every CA AXIAM generated before Vault's PKI engine was an
// option. Present for a `vault_pki` CA, where it is the only copy of the
// root certificate anything outside Vault will ever see — a relying
// party cannot validate an AXIAM-issued leaf without it, and
// `root/generate/internal` returns it exactly once.
ChainPEM *string `json:"chain_pem,omitempty"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint SHA-256 fingerprint of the certificate.
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// KeyCustody Which custodian holds this CA's signing key. Recorded per CA rather
// than read from configuration, so adopting a new custodian does not
// strand the CAs that already exist. Not secret — an operator needs to
// see it, and it discloses only where a key is kept.
KeyCustody *string `json:"key_custody,omitempty"`
// KeyLocator Where the custodian put the key. A Vault path under its mount; `None`
// for database custody, whose locator is the row itself.
KeyLocator *string `json:"key_locator,omitempty"`
// MTLSTrustAnchor Whether this CA is offered as a trust anchor for mutual TLS. When set,
// the server exports this CA's **public** certificate to the bundle named
// by `AXIAM__SERVER__TLS__CLIENT_CA_BUNDLE_PATH` at startup and turns
// client-certificate authentication on (`optional`) if the operator has
// not configured it explicitly. A client presenting a certificate that
// chains to this CA is then verified by the TLS layer itself, which is
// what `axiam_pki::mtls` needs to authenticate an IoT device or a service
// account by certificate rather than by secret. # What is and is not
// copied Only `public_cert_pem` — the certificate. The **private key
// stays where its custodian put it** (Vault, or sealed into the row) and
// is never written to the server volume. A trust anchor is public by
// construction: it is what the server hands every client during the TLS
// handshake, and every device that has to validate the chain already
// holds a copy. # Why a restart rustls builds its `RootCertStore` once,
// when the listener is constructed, and actix-web binds that config for
// the process's life. Toggling this changes what the *next* boot trusts,
// and the API says so in its response rather than pretending the change
// took effect. Defaults to `false`, so a deployment that never touches
// this keeps exactly the TLS posture it has today.
MTLSTrustAnchor *bool `json:"mtls_trust_anchor,omitempty"`
// NotAfter Validity end.
NotAfter string `json:"not_after"`
// NotBefore Validity start.
NotBefore string `json:"not_before"`
// OrganizationID The organization this CA belongs to.
OrganizationID uuid.UUID `json:"organization_id"`
// ParentCAID The CA in this organization that signed this one. `None` for an
// organization-level CA, which is either self-signed or imported and has
// no parent inside AXIAM.
ParentCAID *uuid.UUID `json:"parent_ca_id,omitempty"`
// PrivateKeyPEM PEM-encoded private key — returned only on generation, and only when
// there is one to return. Absent under `vault_pki` custody, where the key
// was generated inside Vault and no API exports it. The field is omitted
// rather than sent as `null` so a client that has always read it keeps
// working unchanged for every custodian that does produce a key.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
PrivateKeyPEM *Sensitive `json:"private_key_pem,omitempty"`
// PublicCertPEM PEM-encoded public certificate. The certificate that *signs*, which
// under `vault_pki` custody is the intermediate rather than the root
// beneath which it was created.
PublicCertPEM string `json:"public_cert_pem"`
// Status carries the server's status field.
Status CertificateStatus `json:"status"`
// Subject The certificate subject (e.g., `CN=ACME Corp Root CA`).
Subject string `json:"subject"`
// TenantID The tenant this CA signs for, when it is a tenant signing CA. `None`
// for an organization-level CA — the trust anchor, and the only kind
// that existed before tenant signing CAs. `Some` for an intermediate
// created under one, which exists so a tenant's user, service and device
// certificates chain through a CA that can be revoked and replaced
// without touching the anchor the rest of the estate trusts.
TenantID *uuid.UUID `json:"tenant_id,omitempty"`
}
GeneratedCACertificate Response returned when a CA certificate is generated. Includes the private key PEM, which is returned **once** and never stored or retrievable again — when the custodian produced one at all. Under `vault_pki` custody the key was born inside Vault and there is nothing to return, which is the point of that custodian rather than a shortcoming of this response.
type GeneratedCertificate ¶
type GeneratedCertificate struct {
// CertType carries the server's cert_type field.
CertType CertificateType `json:"cert_type"`
// ChainPEM The issuing chain, concatenated PEM, nearest issuer first. Present only
// when the signer returned one — which is the `vault_pki` case, where
// the root's certificate exists nowhere a client could fetch it from. For
// a CA AXIAM signed with itself the chain is the CA certificate, which
// `GET .../ca-certificates/{id}` already serves, so the field is omitted
// rather than restating it.
ChainPEM *string `json:"chain_pem,omitempty"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint SHA-256 fingerprint of the certificate.
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IssuerCAID The CA certificate that signed this certificate.
IssuerCAID uuid.UUID `json:"issuer_ca_id"`
// KeyAlgorithm carries the server's key_algorithm field.
KeyAlgorithm KeyAlgorithm `json:"key_algorithm"`
// Metadata Arbitrary key-value metadata (e.g., device serial, user ID binding).
Metadata any `json:"metadata"`
// NotAfter Validity end.
NotAfter string `json:"not_after"`
// NotBefore Validity start.
NotBefore string `json:"not_before"`
// PrivateKeyPEM PEM-encoded private key — returned only on generation.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
PrivateKeyPEM Sensitive `json:"private_key_pem"`
// PublicCertPEM PEM-encoded public certificate.
PublicCertPEM string `json:"public_cert_pem"`
// Status carries the server's status field.
Status CertificateStatus `json:"status"`
// Subject The certificate subject (e.g., `CN=device-001`).
Subject string `json:"subject"`
// TenantID The tenant this certificate belongs to.
TenantID uuid.UUID `json:"tenant_id"`
}
GeneratedCertificate Response returned when a tenant certificate is generated. Includes the private key PEM, returned **once** and never stored.
type GeneratedPGPKey ¶
type GeneratedPGPKey struct {
// Algorithm carries the server's algorithm field.
Algorithm PGPKeyAlgorithm `json:"algorithm"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint OpenPGP key fingerprint (hex).
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// PrivateKeyArmored ASCII-armored private key — returned only on generation for `Export`
// keys. For `AuditSigning` keys this is `None` (private key is
// server-side only).
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
PrivateKeyArmored *Sensitive `json:"private_key_armored,omitempty"`
// PublicKeyArmored carries the server's public_key_armored field.
PublicKeyArmored string `json:"public_key_armored"`
// Purpose carries the server's purpose field.
Purpose PGPKeyPurpose `json:"purpose"`
// Status carries the server's status field.
Status PGPKeyStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
}
GeneratedPGPKey Response returned when a PGP key is generated.
type GrantPermissionRequest ¶
type GrantPermissionRequest struct {
// Effect B1: `"allow"` (the default) or `"deny"`. A deny grant **overrides every
// allow**, at any depth of the resource hierarchy and at equal
// specificity — it is not most-specific-wins. See
// `claude_dev/deny-override-design.md` for the precedence table and for
// why that trade was made. Omitting the field means `"allow"`, so every
// existing client keeps working unchanged and no migration is required.
Effect *PermissionEffect `json:"effect,omitempty"`
// PermissionID carries the server's permission_id field.
PermissionID uuid.UUID `json:"permission_id"`
// ScopeIDs carries the server's scope_ids field.
ScopeIDs []uuid.UUID `json:"scope_ids,omitempty"`
}
GrantPermissionRequest is the GrantPermissionRequest schema from the server's OpenAPI document.
type GrantScopeConsent ¶
type GrantScopeConsent struct {
// ClientID The relying party the claims would be released to.
ClientID string `json:"client_id"`
// Scopes The sensitive scopes being consented to. Order does not matter; the
// record is written in the canonical order so that the same consent has
// one name.
Scopes []string `json:"scopes"`
}
GrantScopeConsent Body for recording an OIDC scope-release consent.
type GrantSpec ¶
type GrantSpec struct {
// Permission is the Key of the PermissionSpec being granted.
Permission string
// Effect is "allow" or "deny". Empty lets the server default, which is allow.
//
// A deny grant overrides EVERY allow, at any depth of the resource
// hierarchy and at equal specificity — AXIAM's RBAC engine is
// deny-override, not most-specific-wins.
Effect string
// Scopes are the Keys of scopes this grant is narrowed to. Empty means the
// whole resource.
Scopes []string
}
GrantSpec is one permission granted to a role, optionally narrowed to scopes.
type GrantedScope ¶
type GrantedScope struct {
// ID The scope's id, as it appears in the grant's `scope_ids`.
ID uuid.UUID `json:"id"`
// Name The scope's name, e.g. `invoices`.
Name string `json:"name"`
// ResourceID The resource the scope belongs to.
ResourceID uuid.UUID `json:"resource_id"`
}
GrantedScope A scope named by a grant, resolved to something a human can read.
type Group ¶
type Group struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Metadata carries the server's metadata field.
Metadata any `json:"metadata"`
// Name carries the server's name field.
Name string `json:"name"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Group A group of users that can access resources based on their roles and permissions. Groups simplify role management by allowing roles to be assigned to a group rather than individual users.
type GroupSpec ¶
type GroupSpec struct {
// Key is the manifest-local identifier users refer to.
Key string
// Name is the group's name — its natural key within the tenant.
Name string
// Description is human-readable. The server requires one.
Description string
// Roles are the Keys of roles assigned to this group.
Roles []string
}
GroupSpec is a group and the roles its members inherit.
type GroupsAPI ¶
type GroupsAPI struct {
// contains filtered or unexported fields
}
GroupsAPI is the groups namespace handle.
Named collections of users. Roles assigned to a group are inherited by every member.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*GroupsAPI) AddMember ¶
AddMember issues POST /api/v1/groups/{group_id}/members.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*GroupsAPI) AddServiceAccount ¶
func (a *GroupsAPI) AddServiceAccount(ctx context.Context, groupID uuid.UUID, body AddServiceAccountMemberRequest) error
AddServiceAccount issues POST /api/v1/groups/{group_id}/service-accounts.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*GroupsAPI) Create ¶
Create issues POST /api/v1/groups.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*GroupsAPI) Delete ¶
Delete issues DELETE /api/v1/groups/{group_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*GroupsAPI) ListAll ¶
ListAll walks groups.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*GroupsAPI) ListMembers ¶
func (a *GroupsAPI) ListMembers(ctx context.Context, groupID uuid.UUID, page PageRequest) (Page[UserResponse], error)
ListMembers issues GET /api/v1/groups/{group_id}/members.
func (*GroupsAPI) ListMembersAll ¶
func (a *GroupsAPI) ListMembersAll(ctx context.Context, groupID uuid.UUID, start PageRequest) ([]UserResponse, error)
ListMembersAll walks groups.list_members to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*GroupsAPI) ListServiceAccounts ¶
func (a *GroupsAPI) ListServiceAccounts(ctx context.Context, groupID uuid.UUID, page PageRequest) (Page[ServiceAccountResponse], error)
ListServiceAccounts issues GET /api/v1/groups/{group_id}/service-accounts.
func (*GroupsAPI) ListServiceAccountsAll ¶
func (a *GroupsAPI) ListServiceAccountsAll(ctx context.Context, groupID uuid.UUID, start PageRequest) ([]ServiceAccountResponse, error)
ListServiceAccountsAll walks groups.list_service_accounts to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*GroupsAPI) RemoveMember ¶
RemoveMember issues DELETE /api/v1/groups/{group_id}/members/{user_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*GroupsAPI) RemoveServiceAccount ¶
func (a *GroupsAPI) RemoveServiceAccount(ctx context.Context, groupID uuid.UUID, serviceAccountID uuid.UUID) error
RemoveServiceAccount issues DELETE /api/v1/groups/{group_id}/service-accounts/{service_account_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type HealthResponse ¶
type HealthResponse struct {
// Status carries the server's status field.
Status string `json:"status"`
}
HealthResponse is the HealthResponse schema from the server's OpenAPI document.
type IDTokenClaims ¶
type IDTokenClaims struct {
// Iss is the issuer — matched for exact string equality against the
// discovery document's issuer (rule 3).
Iss string
// Sub is the authenticated end user's stable identifier at AXIAM.
Sub string
// Aud is the audience — contains the relying party's client_id (rule 4).
// May hold one or more values on the wire; always normalized to a slice
// here.
Aud []string
// Exp is the expiry time (epoch seconds).
Exp int64
// Iat is the issued-at time (epoch seconds).
Iat int64
// Nbf is the not-before time (epoch seconds), when the server sends one.
Nbf *int64
// Nonce is the nonce echoed back from the authorization request (rule 6).
Nonce string
// Azp is the authorized party — required to equal client_id when Aud
// holds multiple audiences (rule 4).
Azp string
// Extra preserves any claim not already modeled above (nil when none).
Extra map[string]any
}
IDTokenClaims is the decoded, ALREADY-VALIDATED ID-token claim set carried by OidcTokenSet.IDClaims (CONTRACT.md §12.1).
Claim names are kept verbatim in their JWT/OIDC spelling (Iss, Sub, Aud, ...) rather than Go's usual field-name conventions: they are protocol identifiers a caller cross-references against OIDC Core. Extra preserves any further claim the server sends (e.g. email, preferred_username) — the ID token's full claim set is not enumerated by openapi.json, so unknown claims MUST be preserved and MUST NOT be rejected (§12.1).
type IDTokenFailureReason ¶
type IDTokenFailureReason string
IDTokenFailureReason is one of the seven CONTRACT.md §12.3/§12.4 stable, machine-readable ID-token validation failure codes, carried on the resulting *AuthError's Reason field.
const ( ReasonInvalidAlg IDTokenFailureReason = "invalid_alg" ReasonUnknownKid IDTokenFailureReason = "unknown_kid" ReasonInvalidSignature IDTokenFailureReason = "invalid_signature" ReasonInvalidIssuer IDTokenFailureReason = "invalid_issuer" ReasonInvalidAudience IDTokenFailureReason = "invalid_audience" ReasonTokenExpired IDTokenFailureReason = "token_expired" ReasonNonceMismatch IDTokenFailureReason = "nonce_mismatch" )
The seven §12.4 reason codes, used verbatim (contract-fixed spelling).
type ImportCACertificateRequest ¶
type ImportCACertificateRequest struct {
// PrivateKeyPEM PEM-encoded private key, if AXIAM is to take custody of it. Omit it to
// register the certificate as a trust anchor only. Write-only: it goes to
// the configured custodian on the way in and no endpoint returns it.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
PrivateKeyPEM *Sensitive `json:"private_key_pem,omitempty"`
// PublicCertPEM PEM-encoded CA certificate.
PublicCertPEM string `json:"public_cert_pem"`
}
ImportCACertificateRequest Body of `POST /api/v1/organizations/{org_id}/ca-certificates/import`. Deliberately carries no subject, validity window or key algorithm: all three are read out of the certificate itself. A caller that could name them separately could name a subject the certificate does not have, and AXIAM would enforce the claim while every relying party read the certificate.
type IntrospectParams ¶
type IntrospectParams struct {
// Token is the token to introspect.
Token Sensitive
// TokenTypeHint is an optional RFC 7662 token_type_hint (access_token /
// refresh_token).
TokenTypeHint string
// TenantID is the tenant UUID for the tenant_id query parameter (§12.3
// rule 4).
TenantID string
// Configuration is a pre-fetched discovery document. Fetched via
// OidcDiscover when nil.
Configuration *OidcConfiguration
}
IntrospectParams are the arguments to Introspect (RFC 7662). Requires confidential-client credentials (§12.1 note 4).
type IntrospectionResult ¶
type IntrospectionResult struct {
// Active reports whether the token is currently active.
Active bool
// Sub is the subject the token was issued to.
Sub string
// ClientID is the client the token was issued to.
ClientID string
// Scope is the scope granted to the token.
Scope string
// TokenType is the token type ("Bearer").
TokenType string
// Exp is the expiry time, epoch seconds. Zero when absent.
Exp int64
// Iat is the issued-at time, epoch seconds. Zero when absent.
Iat int64
}
IntrospectionResult is the RFC 7662 introspection result (wire schema IntrospectionResponse). Only Active is guaranteed; the server omits the metadata fields for an inactive token (zero values below).
type JWKSVerifier ¶
JWKSVerifier is the public entry point for this SDK's local JWKS verification (CONTRACT.md §10/§10.1, D-06) — the shared local-verify mechanism consumed by the net/http middleware (package middleware). It is a thin re-export of the internal jwks.Verifier so callers outside this module never need to import an internal/ package directly.
Use JWKSVerifier.VerifyAccessToken: it applies the complete §10.1 minimum local-verification set (EdDSA-pinned signature, REQUIRED exp, honoured nbf, asserted tenant_id, conditional iss/aud, bounded clock skew).
JWKSVerifier.VerifySignatureOnlyUnchecked is the raw signature-only primitive §10.1 permits for integrators writing their own policy. It is NOT a guard: it checks no claim at all, so an expired token, a token carrying no exp, or a token minted for a DIFFERENT tenant under the same organization-wide JWKS all verify successfully. Do not build an authentication decision on it.
func NewJWKSVerifier ¶
NewJWKSVerifier constructs a JWKSVerifier bound to {baseURL}/oauth2/jwks (trailing slash on baseURL trimmed before joining). hc may be nil, in which case a default *http.Client is used. The cache is registered but not eagerly populated; the first verification triggers the initial fetch.
This is the exported constructor middleware.Middleware examples wire against — see examples/middleware-guard.
type KeyAlgorithm ¶
type KeyAlgorithm string
KeyAlgorithm The type of key algorithm used for a certificate.
const ( KeyAlgorithmRsa4096 KeyAlgorithm = "Rsa4096" KeyAlgorithmEd25519 KeyAlgorithm = "Ed25519" )
The KeyAlgorithm values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type LockoutPolicy ¶
type LockoutPolicy struct {
// LockoutBackoffMultiplier carries the server's lockout_backoff_multiplier field.
LockoutBackoffMultiplier float64 `json:"lockout_backoff_multiplier"`
// LockoutDurationSecs carries the server's lockout_duration_secs field.
LockoutDurationSecs int64 `json:"lockout_duration_secs"`
// MaxFailedLoginAttempts carries the server's max_failed_login_attempts field.
MaxFailedLoginAttempts int `json:"max_failed_login_attempts"`
// MaxLockoutDurationSecs carries the server's max_lockout_duration_secs field.
MaxLockoutDurationSecs int64 `json:"max_lockout_duration_secs"`
}
LockoutPolicy Account lockout rules.
type LoginClientCredentialsParams ¶
type LoginClientCredentialsParams struct {
// Scope is an optional scope to request. This grant requests no "openid"
// scope and the response carries no id_token (§12.1).
Scope string
// TenantID is the tenant UUID for the tenant_id query parameter (§12.3
// rule 4).
TenantID string
// Configuration is a pre-fetched discovery document. Fetched via
// OidcDiscover when nil.
Configuration *OidcConfiguration
// AdoptAsCredential adopts the returned access_token as this Client's
// bearer credential for subsequent REST calls on the same session — the
// §12.1 "login_client_credentials as a credential source" allowance (a
// MAY, hence opt-in and false by default). The token is held behind
// Sensitive and applied only in decorateRequest (never a public field,
// never the cookie jar, never sent to /oauth2/*).
AdoptAsCredential bool
}
LoginClientCredentialsParams are the arguments to LoginClientCredentials (`grant_type=client_credentials`).
type LoginResult ¶
type LoginResult struct {
// MFARequired is true when the server responded with an MFA challenge
// instead of a completed session; call VerifyMfa next with MFAToken.
MFARequired bool
// MFAToken carries the opaque challenge token when MFARequired is
// true. Treated as sensitive (short-lived bearer of "logging in as
// this user").
MFAToken Sensitive
// AvailableMethods lists MFA methods available to satisfy the
// challenge (only populated when MFARequired is true).
AvailableMethods []string
// MFASetupRequired is true when the tenant requires MFA and this
// account has none — CONTRACT.md §25.2 rule 1.
//
// An OUTCOME, not an error. The server answers 403 here with the token
// to finish, and mapping that through §2 to *AuthzError told the caller
// they lacked permission to log in, when what the server said was
// recoverable and came with the means to recover. Pass SetupToken to
// MfaSetupEnroll, show the user the URI, then MfaSetupConfirm, which
// completes this login.
//
// Additive here rather than a new type, because this result has always
// been one struct with flags rather than a discriminated union — so
// nothing that reads MFARequired today has to change.
MFASetupRequired bool
// SetupToken authorizes the MfaSetupEnroll/MfaSetupConfirm pair, and is
// populated only when MFASetupRequired is true.
SetupToken Sensitive
// SessionID is the server-issued session id (only populated on a
// completed, non-MFA-pending login/verify_mfa).
SessionID string
// ExpiresIn is the access token lifetime in seconds, as reported by
// the server (only populated on a completed login/verify_mfa).
ExpiresIn uint64
// OrganizationLevel reports whether the account that just signed in is
// an ORGANIZATION-LEVEL principal — CONTRACT.md §5.2.
//
// Such a principal's record lives in its organization's reserved tenant,
// so its global grants apply in every tenant of that organization, and
// it can act on a different one by sending a different X-Axiam-Tenant on
// the next request — no re-login, because it already is a principal of
// every tenant there.
//
// An ordinary tenant principal is a principal of exactly one tenant.
// Changing the header for one of those produces a 403, so this flag is
// what an application checks BEFORE offering a tenant switch, rather
// than discovering the answer from a failed request.
//
// False on a completed login against a server older than contract 1.31,
// and false on the two pending outcomes, where no principal has been
// established yet.
//
// Since contract 1.35 that reach can be narrowed per assignment, so this
// flag alone no longer decides what to offer: consult
// ReachableTenantIDs as well (§5.2.3 rule 3).
OrganizationLevel bool
// TenantID is the tenant this login ACTS ON — CONTRACT.md §5.2.2.
// Nil on the two pending outcomes and against a server older than
// contract 1.34.
TenantID *uuid.UUID
// PrincipalTenantID is the tenant this principal's record LIVES IN.
//
// This is where the account's own credentials belong, and what a §23
// registration record for THIS account must be sealed against — see
// Client.OpaqueEnrollmentForSelf.
//
// Falls back to TenantID when the server omits it, which is exactly
// right there: a server older than contract 1.34 cannot switch the
// acting tenant, so the two cannot differ.
PrincipalTenantID *uuid.UUID
// PrincipalTenantSlug is the slug of PrincipalTenantID —
// "organization" for an organization-level principal.
PrincipalTenantSlug *string
// OrgID is the caller's organization as a UUID — CONTRACT.md §5.2.2
// rule 3. Read this rather than resolving a slug through
// GET /api/v1/organizations, which is super-admin-only and returns only
// the caller's own organization.
OrgID *uuid.UUID
// ReachableTenantIDs are the tenants this caller's roles reach, when
// narrowed — CONTRACT.md §5.2.3.
//
// Nil means UNRESTRICTED, which is both the common case and the only
// thing a server older than contract 1.35 can mean. A present slice is a
// deliberately narrowed organization-level account: confine any tenant
// switch to it, because naming anything outside is refused at the
// header.
//
// Note the pairing with OrganizationLevel: a narrowed account still
// reports true there, so gating on that flag alone offers tenants the
// server will refuse.
ReachableTenantIDs []uuid.UUID
}
LoginResult is the outcome of Login/VerifyMfa (CF-04). MFA required is an expected outcome, not an error: check MFARequired before assuming the session is established.
type LogoutURLParams ¶
type LogoutURLParams struct {
// IDToken is a previously-issued ID token, placed in id_token_hint — the
// only AUTHENTICATED statement of which session is being ended.
IDToken Sensitive
// PostLogoutRedirectURI is where the OP sends the browser afterwards.
// Honoured only on exact match against the client's registered allow-list
// — a server-side check the SDK deliberately does not duplicate (§12.7.2
// rule 3).
PostLogoutRedirectURI string
// State is an opaque value echoed back on the redirect. Generated and
// checked by the caller (§12.7.2 rule 2), never by the SDK.
State string
// Configuration is a pre-fetched discovery document.
Configuration *OidcConfiguration
}
LogoutURLParams are the arguments to Client.LogoutURL (§12.7.2).
type MDSRefreshOutcome ¶
type MDSRefreshOutcome struct {
// Outcome is the discriminator: it says which of the fields below are set.
Outcome string `json:"outcome"`
// AttemptedNo carries the server's attempted_no field.
AttemptedNo *int64 `json:"attempted_no,omitempty"`
// EntryCount carries the server's entry_count field.
EntryCount *int `json:"entry_count,omitempty"`
// No carries the server's no field.
No *int64 `json:"no,omitempty"`
// StoredNo carries the server's stored_no field.
StoredNo *int64 `json:"stored_no,omitempty"`
}
MDSRefreshOutcome `POST /api/v1/mds/refresh` response — the outcome of one ingestion attempt (mirrors `axiam_db::mds_ingest::MdsIngestOutcome`).
Go has no sum type, so every arm's fields live on this one struct as pointers and outcome says which are set: outcome="initial" carries entry_count, no. outcome="replaced" carries entry_count, no. outcome="no_op_refresh" carries no. outcome="rollback_rejected" carries attempted_no, stored_no. A field belonging to another arm is nil.
type MDSStatusResponse ¶
type MDSStatusResponse struct {
// EntryCount carries the server's entry_count field.
EntryCount int64 `json:"entry_count"`
// LastRefreshedAt carries the server's last_refreshed_at field.
LastRefreshedAt *string `json:"last_refreshed_at,omitempty"`
// NextUpdate carries the server's next_update field.
NextUpdate *string `json:"next_update,omitempty"`
// No carries the server's no field.
No *int64 `json:"no,omitempty"`
// Stale carries the server's stale field.
Stale bool `json:"stale"`
}
MDSStatusResponse `GET /api/v1/mds/status` response. `no`/`next_update`/`last_refreshed_at` are `None` and `stale` is `false` when MDS has never been ingested — a meaningful, valid answer ("nothing ingested yet"), not an error.
type MFAMethodResponse ¶
type MFAMethodResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// LastUsedAt carries the server's last_used_at field.
LastUsedAt *string `json:"last_used_at,omitempty"`
// MethodID carries the server's method_id field.
MethodID string `json:"method_id"`
// MethodType carries the server's method_type field.
MethodType MFAMethodType `json:"method_type"`
// Name carries the server's name field.
Name string `json:"name"`
}
MFAMethodResponse is the MFAMethodResponse schema from the server's OpenAPI document.
type MFAMethodType ¶
type MFAMethodType string
MFAMethodType Type of MFA method.
const ( MFAMethodTypeTOTP MFAMethodType = "Totp" MFAMethodTypePasskey MFAMethodType = "Passkey" MFAMethodTypeSecurityKey MFAMethodType = "SecurityKey" )
The MFAMethodType values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type MFAPolicy ¶
type MFAPolicy struct {
// MFAChallengeLifetimeSecs carries the server's mfa_challenge_lifetime_secs field.
MFAChallengeLifetimeSecs int64 `json:"mfa_challenge_lifetime_secs"`
// MFAEnforced carries the server's mfa_enforced field.
MFAEnforced bool `json:"mfa_enforced"`
}
MFAPolicy Multi-factor authentication policy.
type MTLSTrustAnchorResponse ¶
type MTLSTrustAnchorResponse struct {
// CACertificateID The CA this is about.
CACertificateID uuid.UUID `json:"ca_certificate_id"`
// Message A sentence an operator can act on, rather than a bare boolean.
Message string `json:"message"`
// MTLSTrustAnchor The flag as now stored.
MTLSTrustAnchor bool `json:"mtls_trust_anchor"`
// RestartRequired Whether the change still needs a restart to take effect. `false` when
// the live listener accepted the new anchor set — the ordinary case on
// a TLS deployment. `true` only when there was no listener to reload into
// (plaintext, or `client_auth = off`), where the flag is stored and
// applies at the next start.
RestartRequired bool `json:"restart_required"`
// TrustedAnchors How many CAs the listener now trusts for client authentication, when it
// was reloaded. `None` when nothing was reloaded.
TrustedAnchors *int `json:"trusted_anchors,omitempty"`
}
MTLSTrustAnchorResponse The acknowledgement, which is mostly about the restart.
type ManagementManifest ¶
type ManagementManifest struct {
// Resources may be in any order — Plan sorts them so a parent precedes its
// children.
Resources []ResourceSpec
// Permissions are tenant-wide actions. What binds one to a resource is the
// scope list on a role's grant.
Permissions []PermissionSpec
// Roles are roles and the permissions granted to them.
Roles []RoleSpec
// Groups are groups and the roles their members inherit.
Groups []GroupSpec
// Users are users, their role assignments and their group memberships.
Users []UserSpec
}
ManagementManifest is the shape a tenant should have.
Deliberately covers only the namespaces that describe a tenant's SHAPE. Certificates, CA certificates, PGP keys and SCIM tokens are absent on purpose (§27.6): they mint one-time secrets, and a declarative layer that "ensures a certificate exists" either re-mints one on every run or silently accepts drift. Both are worse than an imperative call made once, on purpose, whose result the caller stores.
type ManagementPlan ¶
type ManagementPlan struct {
// Actions is every step, including the no-ops.
Actions []PlannedAction
}
ManagementPlan is the ordered set of actions that would reconcile a manifest.
Ordering is derived, not incidental: resources (parents before children), then scopes, permissions, roles, role grants, groups, group bindings, users, and finally the user bindings that need all of the above to exist. Two plans over unchanged state are equal, in the same order (§27.6 rule 8) — a plan that reorders between runs cannot be diffed, and diffing it is most of the reason it exists.
func (ManagementPlan) Changes ¶
func (p ManagementPlan) Changes() []PlannedAction
Changes returns the steps of this plan that would actually change something.
func (ManagementPlan) IsConverged ¶
func (p ManagementPlan) IsConverged() bool
IsConverged reports whether applying this plan would change nothing.
This is the §27.6 rule 6 acceptance test: Apply then Plan must land here, or the SDK has a drift-detection bug.
type ManifestAPI ¶
type ManifestAPI struct {
// contains filtered or unexported fields
}
ManifestAPI is the declarative-management handle, reached as c.Manifest().
func (*ManifestAPI) Apply ¶
func (a *ManifestAPI) Apply(ctx context.Context, m ManagementManifest) (ApplyReport, error)
Apply reconciles the manifest, stopping at the first failure.
Re-running after fixing the cause is the recovery path, and is safe: applying twice converges (§27.6 rule 6).
func (*ManifestAPI) Plan ¶
func (a *ManifestAPI) Plan(ctx context.Context, m ManagementManifest) (ManagementPlan, error)
Plan reports what reconciling the manifest would do. It issues NO writes.
type ManifestBuilder ¶
type ManifestBuilder struct {
// contains filtered or unexported fields
}
ManifestBuilder assembles a ManagementManifest fluently.
The struct-literal form is fine for a small manifest and gets unreadable for a real one — nested slices of slices, counting closing braces. This is the same value, built a line at a time. Build validates on the way out, exactly as a hand-built manifest is validated by Plan, so a dangling key or a cycle in the resource parents is caught where the manifest is WRITTEN.
shape, err := NewManifest().
Resource("docs", "documents", "collection").
Scope("docs", "draft", "draft", "Unpublished").
Permission("read", "document:read", "Read a document").
Role("editor", "Editor", "Edits documents").
Grant("editor", "read", "", "draft").
Build()
func (*ManifestBuilder) AddToGroup ¶
func (b *ManifestBuilder) AddToGroup(userKey, groupKey string) *ManifestBuilder
AddToGroup puts the user named by userKey into the group named by groupKey.
func (*ManifestBuilder) AssignRole ¶
func (b *ManifestBuilder) AssignRole(userKey, roleKey string) *ManifestBuilder
AssignRole assigns a role directly to the user named by userKey.
func (*ManifestBuilder) Build ¶
func (b *ManifestBuilder) Build() (ManagementManifest, error)
Build returns the assembled manifest, or the reason it cannot be reconciled.
Validated here rather than at Plan time: a dangling key, a duplicate, or a cycle in the resource parents is a mistake in the declaration, and hearing about it at the declaration is what makes this form worth having.
func (*ManifestBuilder) ChildResource ¶
func (b *ManifestBuilder) ChildResource(key, name, resourceType, parentKey string) *ManifestBuilder
ChildResource declares a resource beneath the resource named by parentKey.
func (*ManifestBuilder) GlobalRole ¶
func (b *ManifestBuilder) GlobalRole(key, name, description string) *ManifestBuilder
GlobalRole declares a tenant-wide role.
func (*ManifestBuilder) Grant ¶
func (b *ManifestBuilder) Grant(roleKey, permissionKey, effect string, scopeKeys ...string) *ManifestBuilder
Grant grants a permission to the role named by roleKey.
effect is "allow", "deny", or empty for the server's default. scopeKeys narrows the grant; passing none grants it across the whole resource.
func (*ManifestBuilder) Group ¶
func (b *ManifestBuilder) Group(key, name, description string, roleKeys ...string) *ManifestBuilder
Group declares a group and the roles its members inherit.
func (*ManifestBuilder) Permission ¶
func (b *ManifestBuilder) Permission(key, action, description string) *ManifestBuilder
Permission declares a permission.
func (*ManifestBuilder) Resource ¶
func (b *ManifestBuilder) Resource(key, name, resourceType string) *ManifestBuilder
Resource declares a root resource.
func (*ManifestBuilder) Role ¶
func (b *ManifestBuilder) Role(key, name, description string) *ManifestBuilder
Role declares a resource-scoped role.
func (*ManifestBuilder) Scope ¶
func (b *ManifestBuilder) Scope(resourceKey, key, name, description string) *ManifestBuilder
Scope declares a scope beneath the resource named by resourceKey.
func (*ManifestBuilder) User ¶
func (b *ManifestBuilder) User(key, username, email string, initialPassword Sensitive) *ManifestBuilder
User declares a user. initialPassword is used only if the user has to be created; it is never sent for one that already exists.
type ManifestFailure ¶
type ManifestFailure struct {
// Action is the step that failed. Everything before it has happened.
Action PlannedAction
// Message is the error the server or transport gave.
Message string
}
ManifestFailure is the step that stopped an apply, and why.
type MemoryOidcStateStore ¶
type MemoryOidcStateStore struct {
// contains filtered or unexported fields
}
MemoryOidcStateStore is an in-memory reference implementation of OidcStateStore (CONTRACT.md §12.3 rule 1): per-instance (never process-global), single-use, TTL-bounded. Expired entries are dropped lazily on Save/Consume — there is NO background timer/goroutine, since a library must not keep the host process alive on its own.
Suitable for a single-process app and for tests. A multi-instance deployment needs a shared store (Redis, a database) — implement OidcStateStore directly for that; nothing in this SDK assumes this type.
func NewMemoryOidcStateStore ¶
func NewMemoryOidcStateStore(ttl time.Duration) *MemoryOidcStateStore
NewMemoryOidcStateStore constructs a MemoryOidcStateStore. ttl is the entry lifetime; zero, negative, or greater than OidcStateTTL is CLAMPED to OidcStateTTL (10 minutes) — CONTRACT.md §12.3 rule 1 fixes that as the maximum, while a shorter TTL is honoured verbatim (useful in tests).
func (*MemoryOidcStateStore) Consume ¶
func (s *MemoryOidcStateStore) Consume(state string) (OidcStateEntry, bool)
Consume atomically returns and deletes the entry for state. Deletion happens BEFORE the expiry check, so even an expired hit is removed rather than left to accumulate, and a second call can never return the same entry twice regardless of timing.
func (*MemoryOidcStateStore) Save ¶
func (s *MemoryOidcStateStore) Save(entry OidcStateEntry) error
Save persists entry under its own State, expiring ttl from now.
func (*MemoryOidcStateStore) Size ¶
func (s *MemoryOidcStateStore) Size() int
Size reports the number of unexpired entries currently held. Intended for tests and metrics.
type MfaEnrollment ¶
type MfaEnrollment struct {
// SecretBase32 is the shared TOTP secret. Anyone holding it can generate
// valid codes indefinitely.
SecretBase32 Sensitive
// TotpURI is otpauth://totp/...?secret=<SecretBase32> — so it CONTAINS the
// secret beside it. Both are Sensitive for that reason, and this is the one
// that actually reaches a log, because it is the one a caller hands to a QR
// renderer (§25.3).
TotpURI Sensitive
}
MfaEnrollment is a TOTP enrolment offer.
THE FACTOR IS NOT ACTIVE YET. It becomes active when MfaConfirm accepts a code derived from this secret — which is why §25.2 rule 4 forbids a composed one-call helper here: the human step in the middle, scanning the URI and reading a code, is not something a helper can wait for, and one that returned after MfaEnroll would report MFA as enabled when it is not.
type MigrateCustodyResponse ¶
type MigrateCustodyResponse struct {
// CACertificateID The CA whose key moved.
CACertificateID uuid.UUID `json:"ca_certificate_id"`
// KeyCustody Where it is now.
KeyCustody string `json:"key_custody"`
// KeyLocator Where the new custodian filed it, when the custodian has a path.
KeyLocator *string `json:"key_locator,omitempty"`
// PreviousCustody Where the key was.
PreviousCustody string `json:"previous_custody"`
}
MigrateCustodyResponse What a custody migration did.
type MtlsEndpointAliases ¶
type MtlsEndpointAliases struct {
// TokenEndpoint is RFC 8705 §2 client authentication, and §3 the mint of
// a certificate-bound token.
TokenEndpoint string `json:"token_endpoint,omitempty"`
// UserinfoEndpoint is OIDC Core §5.3, reached with an access token that
// may carry `cnf`.
UserinfoEndpoint string `json:"userinfo_endpoint,omitempty"`
// RevocationEndpoint is RFC 7009 §2.1, which authenticates the client.
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
// IntrospectionEndpoint is RFC 7662 §2.1, which authenticates the caller.
IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"`
// DeviceAuthorizationEndpoint is RFC 8628 §3.1, which authenticates the
// client.
DeviceAuthorizationEndpoint string `json:"device_authorization_endpoint,omitempty"`
// PushedAuthorizationRequestEndpoint is RFC 9126 §2, which authenticates
// the client.
PushedAuthorizationRequestEndpoint string `json:"pushed_authorization_request_endpoint,omitempty"`
}
MtlsEndpointAliases is RFC 8705 §5 `mtls_endpoint_aliases` — the six endpoints re-based on the host that performs the mutual-TLS handshake (wire schema MtlsEndpointAliases, contract 1.40).
A TLS listener decides whether to request a client certificate during the handshake, before it has seen any HTTP, so "ask for a certificate on /oauth2/token but not on /oauth2/authorize" is not something one listener can do. A deployment wanting both runs two, and this object names the second.
Only these six are ever aliased. AuthorizationEndpoint and EndSessionEndpoint are front-channel and JwksURI is public key material, so CONTRACT.md §21.3 rule 2 forbids synthesising an alias for any of them — sending a browser to an mTLS host raises a native certificate-chooser dialog most users cannot answer. Issuer is not an endpoint and does not move either: §12.4 rule 3 still compares `iss` against it by exact string.
Every field carries `omitempty` and an empty value is meaningful, though the server's schema marks all six required. AXIAM builds them from one path through a shared macro and so always publishes the complete set, but RFC 8705 §5 permits an OP to alias fewer, and the shape of this member must never be why a client stops working — the same principle rule 2 point 1 states for the object as a whole, one level in. An empty entry falls back to the top-level endpoint of the same name, exactly as an absent object does.
type NetworkError ¶
type NetworkError struct {
Message string
// RetryAfter carries a server-supplied Retry-After hint (CONTRACT.md §16.1),
// zero when the response had none.
//
// It is a DURATION parsed from the header, never the raw header value, so
// the redaction invariant above is untouched: a duration cannot carry a
// token, a URL, or anything else a header might. §16 honors it as a floor
// on the backoff — the server is stating when it will be ready, so
// retrying sooner is not permitted.
RetryAfter time.Duration
// contains filtered or unexported fields
}
NetworkError represents a transport-level failure: connection refused, timeout, TLS error, DNS failure, or a server-side 5xx (CONTRACT.md §2).
cause is unexported and MUST only ever be populated via newNetworkError, which redacts sensitive headers from any wrapped *http.Response BEFORE constructing the error (D-04, Phase 17 CR-04 carry-forward) — never construct a NetworkError directly from an unredacted *http.Response.
func (*NetworkError) Error ¶
func (e *NetworkError) Error() string
func (*NetworkError) Is ¶
func (e *NetworkError) Is(target error) bool
Is reports whether target is the ErrNetwork sentinel, enabling errors.Is(err, ErrNetwork) to match any *NetworkError.
func (*NetworkError) Unwrap ¶
func (e *NetworkError) Unwrap() error
Unwrap exposes the underlying (already-redacted) cause for errors.Is/As and errors.Unwrap chains.
type NotFoundError ¶
type NotFoundError struct {
// Operation is the registry operation that found nothing, e.g. "users.get".
Operation string
// Message is the full, caller-facing description.
Message string
}
NotFoundError reports HTTP 404: the resource does not exist, OR it belongs to another tenant.
The server answers identically in both cases on purpose: a distinguishable "exists but not yours" lets a caller enumerate another tenant's ids. That is why this matches ErrAuthz rather than being a category of its own — in a multi-tenant IAM the two really are one outcome.
func (*NotFoundError) Error ¶
func (e *NotFoundError) Error() string
func (*NotFoundError) Is ¶
func (e *NotFoundError) Is(target error) bool
Is matches both ErrNotFound and the §2 ErrAuthz sentinel this refusal is a kind of.
type NotificationEventType ¶
type NotificationEventType string
NotificationEventType Events that can trigger an admin notification.
const ( NotificationEventTypeLoginFailure NotificationEventType = "login_failure" NotificationEventTypeAccountLocked NotificationEventType = "account_locked" NotificationEventTypeMFAEnrollmentChanged NotificationEventType = "mfa_enrollment_changed" NotificationEventTypePasswordChanged NotificationEventType = "password_changed" NotificationEventTypePasswordResetRequested NotificationEventType = "password_reset_requested" NotificationEventTypeRoleAssigned NotificationEventType = "role_assigned" NotificationEventTypeRoleUnassigned NotificationEventType = "role_unassigned" NotificationEventTypePermissionGranted NotificationEventType = "permission_granted" NotificationEventTypePermissionRevoked NotificationEventType = "permission_revoked" NotificationEventTypeCertificateIssued NotificationEventType = "certificate_issued" NotificationEventTypeCertificateRevoked NotificationEventType = "certificate_revoked" NotificationEventTypeCACertificateRevoked NotificationEventType = "ca_certificate_revoked" NotificationEventTypeUserCreated NotificationEventType = "user_created" NotificationEventTypeUserDeleted NotificationEventType = "user_deleted" NotificationEventTypeUserUpdated NotificationEventType = "user_updated" NotificationEventTypeServiceAccountCreated NotificationEventType = "service_account_created" NotificationEventTypeServiceAccountDeleted NotificationEventType = "service_account_deleted" )
The NotificationEventType values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type NotificationPolicy ¶
type NotificationPolicy struct {
// AdminNotificationsEnabled carries the server's admin_notifications_enabled field.
AdminNotificationsEnabled bool `json:"admin_notifications_enabled"`
}
NotificationPolicy Admin notification preferences.
type NotificationRuleResponse ¶
type NotificationRuleResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// Events carries the server's events field.
Events []NotificationEventType `json:"events"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// RecipientEmails carries the server's recipient_emails field.
RecipientEmails []string `json:"recipient_emails"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
NotificationRuleResponse Notification rule response.
type NotificationRulesAPI ¶
type NotificationRulesAPI struct {
// contains filtered or unexported fields
}
NotificationRulesAPI is the notification_rules namespace handle.
Which events raise a notification, and to whom.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*NotificationRulesAPI) Create ¶
func (a *NotificationRulesAPI) Create(ctx context.Context, body CreateNotificationRuleRequest) (NotificationRuleResponse, error)
Create issues POST /api/v1/notification-rules.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*NotificationRulesAPI) Delete ¶
Delete issues DELETE /api/v1/notification-rules/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*NotificationRulesAPI) Get ¶
func (a *NotificationRulesAPI) Get(ctx context.Context, id uuid.UUID) (NotificationRuleResponse, error)
Get issues GET /api/v1/notification-rules/{id}.
func (*NotificationRulesAPI) List ¶
func (a *NotificationRulesAPI) List(ctx context.Context, page PageRequest) (Page[NotificationRuleResponse], error)
List issues GET /api/v1/notification-rules.
func (*NotificationRulesAPI) ListAll ¶
func (a *NotificationRulesAPI) ListAll(ctx context.Context, start PageRequest) ([]NotificationRuleResponse, error)
ListAll walks notification_rules.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*NotificationRulesAPI) Update ¶
func (a *NotificationRulesAPI) Update(ctx context.Context, id uuid.UUID, body UpdateNotificationRuleRequest) (NotificationRuleResponse, error)
Update issues PUT /api/v1/notification-rules/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type OAuth2ClientCreatedResponse ¶
type OAuth2ClientCreatedResponse struct {
// ClientID carries the server's client_id field.
ClientID string `json:"client_id"`
// ClientSecret carries the server's client_secret field.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ClientSecret Sensitive `json:"client_secret"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// GrantTypes carries the server's grant_types field.
GrantTypes []string `json:"grant_types"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// RedirectUris carries the server's redirect_uris field.
RedirectUris []string `json:"redirect_uris"`
// Scopes carries the server's scopes field.
Scopes []string `json:"scopes"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
OAuth2ClientCreatedResponse Response for client creation -- includes the one-time plaintext secret.
type OAuth2ClientResponse ¶
type OAuth2ClientResponse struct {
// AuthnRequestParams X7.1 — echoed so an operator can audit which clients act on the OIDC
// authentication-request parameters, from this endpoint rather than from
// the database.
AuthnRequestParams AuthnRequestParamsMode `json:"authn_request_params"`
// BrowserSSO X7.3 — echoed for the same reason.
BrowserSSO bool `json:"browser_sso"`
// ClientID carries the server's client_id field.
ClientID string `json:"client_id"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// DpopBoundAccessTokens carries the server's dpop_bound_access_tokens field.
DpopBoundAccessTokens bool `json:"dpop_bound_access_tokens"`
// DpopRequireNonce carries the server's dpop_require_nonce field.
DpopRequireNonce bool `json:"dpop_require_nonce"`
// GrantTypes carries the server's grant_types field.
GrantTypes []string `json:"grant_types"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// JWKS X5.1 — echoed so an operator can confirm which key source is
// registered. The document itself is public key material, so returning it
// leaks nothing; a `jwks_uri` is likewise public by construction.
JWKS *string `json:"jwks,omitempty"`
// JWKSURI carries the server's jwks_uri field.
JWKSURI *string `json:"jwks_uri,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
// Profile X5.1 — the registered posture and mTLS credentials. Read-back
// matters: an operator auditing which clients are financial-grade should
// be able to answer it from this endpoint rather than from the database.
Profile ClientProfile `json:"profile"`
// RedirectUris carries the server's redirect_uris field.
RedirectUris []string `json:"redirect_uris"`
// RequirePar carries the server's require_par field.
RequirePar bool `json:"require_par"`
// Scopes carries the server's scopes field.
Scopes []string `json:"scopes"`
// SelfSignedTLSClientAuthThumbprints carries the server's self_signed_tls_client_auth_thumbprints field.
SelfSignedTLSClientAuthThumbprints []string `json:"self_signed_tls_client_auth_thumbprints"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// TLSClientAuthSanDns carries the server's tls_client_auth_san_dns field.
TLSClientAuthSanDns *string `json:"tls_client_auth_san_dns,omitempty"`
// TLSClientAuthSanURI carries the server's tls_client_auth_san_uri field.
TLSClientAuthSanURI *string `json:"tls_client_auth_san_uri,omitempty"`
// TLSClientAuthSubjectDn carries the server's tls_client_auth_subject_dn field.
TLSClientAuthSubjectDn *string `json:"tls_client_auth_subject_dn,omitempty"`
// TLSClientCertificateBoundAccessTokens carries the server's tls_client_certificate_bound_access_tokens field.
TLSClientCertificateBoundAccessTokens bool `json:"tls_client_certificate_bound_access_tokens"`
// TokenEndpointAuthMethod carries the server's token_endpoint_auth_method field.
TokenEndpointAuthMethod ClientAuthMethod `json:"token_endpoint_auth_method"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
OAuth2ClientResponse OAuth2 client response -- omits client_secret_hash.
type OAuth2ClientsAPI ¶
type OAuth2ClientsAPI struct {
// contains filtered or unexported fields
}
OAuth2ClientsAPI is the oauth2_clients namespace handle.
Registered OAuth2/OIDC clients -- the registration half of what §12, §21 and §26 then speak to.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*OAuth2ClientsAPI) Create ¶
func (a *OAuth2ClientsAPI) Create(ctx context.Context, body CreateOAuth2ClientRequest) (OAuth2ClientCreatedResponse, error)
Create issues POST /api/v1/oauth2-clients.
Returns secret material, once. client_secret is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*OAuth2ClientsAPI) Delete ¶
Delete issues DELETE /api/v1/oauth2-clients/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*OAuth2ClientsAPI) Get ¶
func (a *OAuth2ClientsAPI) Get(ctx context.Context, id uuid.UUID) (OAuth2ClientResponse, error)
Get issues GET /api/v1/oauth2-clients/{id}.
func (*OAuth2ClientsAPI) List ¶
func (a *OAuth2ClientsAPI) List(ctx context.Context, page PageRequest) (Page[OAuth2ClientResponse], error)
List issues GET /api/v1/oauth2-clients.
func (*OAuth2ClientsAPI) ListAll ¶
func (a *OAuth2ClientsAPI) ListAll(ctx context.Context, start PageRequest) ([]OAuth2ClientResponse, error)
ListAll walks oauth2_clients.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*OAuth2ClientsAPI) Update ¶
func (a *OAuth2ClientsAPI) Update(ctx context.Context, id uuid.UUID, body UpdateOAuth2ClientRequest) (OAuth2ClientResponse, error)
Update issues PUT /api/v1/oauth2-clients/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type OAuthProtocolError ¶
type OAuthProtocolError struct {
AuthError
// ErrorCode is the RFC 6749 "error" field (e.g. invalid_grant).
ErrorCode string
// ErrorDescription is the RFC 6749 "error_description" field.
ErrorDescription string
}
OAuthProtocolError represents an RFC 6749 protocol error returned by an `/oauth2/*` endpoint as an OAuth2ErrorResponse body — `invalid_grant`, `invalid_client`, `invalid_request`, `unsupported_grant_type`, etc. (CONTRACT.md §2, §12.3 rule 3).
It is a language-idiomatic SUB-TYPE of AuthError, not a fourth peer error type (§12 port addendum item 17): OAuthProtocolError embeds AuthError by value and implements Unwrap() returning *AuthError, so:
- errors.Is(err, ErrAuth) matches via the promoted *AuthError.Is method (Is() is checked on err itself before any unwrapping), and
- errors.As(err, &authErrPtr) (with authErrPtr *AuthError) matches by unwrapping once to the embedded AuthError.
Every pre-existing `switch err := err.(type) { case *AuthError: ... }` or `errors.As`/`errors.Is` call site that already handles AuthError keeps working unchanged against an *OAuthProtocolError value — this is precisely what makes contract 1.4 "non-breaking, additive" for Go.
func (*OAuthProtocolError) Unwrap ¶
func (e *OAuthProtocolError) Unwrap() error
Unwrap exposes the embedded AuthError so errors.As(err, &authErrPtr) and errors.Unwrap chains keep matching *AuthError for an *OAuthProtocolError value (see the type doc comment above).
type OIDCAuthorizeRequest ¶
type OIDCAuthorizeRequest struct {
// ConfigID ID of the federation config to use.
ConfigID uuid.UUID `json:"config_id"`
// Nonce Nonce for replay protection (generated by the caller).
Nonce string `json:"nonce"`
// RedirectURI Redirect URI the external IdP should return the user to.
RedirectURI string `json:"redirect_uri"`
// State CSRF state value (generated by the caller).
State string `json:"state"`
}
OIDCAuthorizeRequest is the OIDCAuthorizeRequest schema from the server's OpenAPI document.
type OIDCAuthorizeResponse ¶
type OIDCAuthorizeResponse struct {
// URL The full authorization URL to redirect the user to.
URL string `json:"url"`
}
OIDCAuthorizeResponse is the OIDCAuthorizeResponse schema from the server's OpenAPI document.
type OIDCCallbackRequest ¶
type OIDCCallbackRequest struct {
// Code Authorization code returned by the external IdP.
Code string `json:"code"`
// ConfigID ID of the federation config used in the authorization request.
ConfigID uuid.UUID `json:"config_id"`
// Nonce Client-supplied nonce (SECHRD-07/D-04: retained for backward
// compatibility with older callers, but IGNORED for verification —
// `expected_nonce` always comes from the server-side
// `FederationLoginState` row looked up via `state`, never from this
// field).
Nonce string `json:"nonce"`
// RedirectURI Redirect URI that was used in the authorization request.
RedirectURI string `json:"redirect_uri"`
// State CSRF state value from the authorization request. Used to look up the
// server-side `FederationLoginState` row that holds the real nonce
// (SECHRD-07/D-04) — required so the callback can find its login state.
State string `json:"state"`
}
OIDCCallbackRequest is the OIDCCallbackRequest schema from the server's OpenAPI document.
type OIDCCallbackResponse ¶
type OIDCCallbackResponse struct {
// FederationLinkID carries the server's federation_link_id field.
FederationLinkID uuid.UUID `json:"federation_link_id"`
// NewlyProvisioned carries the server's newly_provisioned field.
NewlyProvisioned bool `json:"newly_provisioned"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
OIDCCallbackResponse is the OIDCCallbackResponse schema from the server's OpenAPI document.
type OIDCPolicy ¶
type OIDCPolicy struct {
// DefaultLocale The BCP 47 tag the sign-in page falls back to when the relying party's
// `ui_locales` selects nothing (W5's chain, plan §4.6). `None` means "no
// tenant preference", which lands on the deployment default (`en`) —
// the behaviour every deployment had before this field existed. A tag
// this build does not ship also lands there: the parse is exact rather
// than a language lookup, so a stored `fr-CA` reads as "somebody wrote
// something this binary does not ship" rather than as a guess at French.
// Stored as a string rather than as the `Locale` enum because that enum
// lives in `axiam-oauth2`, four layers above this crate, and the crate
// layering points inward.
DefaultLocale *string `json:"default_locale,omitempty"`
// SensitiveScopesEnabled Whether `address` and `phone` may be registered on a client, requested
// at the authorization endpoint, and released at UserInfo (X7 G8). **Off
// unless an organization turns it on.** The two scopes release a postal
// address and a telephone number — categories of personal data AXIAM
// has no other use for — so the deployment that has never thought about
// them releases nothing, and the operator who has thought about them says
// so once, at the organization level, where the lawful basis for holding
// the data was decided. The switch is a *capability*, not a grant: with
// it on, a client still has to register the scope, the request still has
// to ask for it, and the user still has to have consented. It is the
// first of four gates, and it is the only one an operator can close for
// everybody at once.
SensitiveScopesEnabled bool `json:"sensitive_scopes_enabled"`
}
OIDCPolicy OpenID Connect surface controls (X7 G8, plan §4.6/§4.8). Two settings that are not password rules, and are here because this is the org-baseline-plus-tenant-override surface every other per-tenant control lives on. They are also the two settings in this model that are *not* of the same kind as each other, so it is worth saying which is which: * [`Self::sensitive_scopes_enabled`] **is** ordered. Releasing personal data is the less-restrictive direction, so it is validated disable-only — the mirror image of `mfa_enforced` — and a tenant can turn its organization's decision off but never on. * [`Self::default_locale`] is **not** ordered, and no ordering is invented for it. A language is a presentation preference; there is no sense in which Italian is stricter than French. [`validate_tenant_override`] therefore does not check it and [`clamp_overrides_to_org`] never clears it. The model's rule is "a tenant may only be more restrictive", which binds every field that *has* a restrictiveness; a field that has none cannot violate it.
type OidcBeginParams ¶
type OidcBeginParams struct {
// RedirectURI is the relying party's redirect URI, echoed back into
// OidcExchange unchanged.
RedirectURI string
// Scope is the requested scope, space-separated. "openid" is added
// automatically when absent (§12.1 rule 4); the zero value requests
// exactly "openid".
Scope string
// ExtraParams are additional caller-supplied authorization-request query
// parameters (e.g. prompt, login_hint, ui_locales). §12.1 rule 5 allows
// caller-supplied additions but forbids the SDK from adding any of its
// own beyond the mandated eight: attempting to override one of those
// eight is a PROGRAMMING ERROR, returned as a plain error — deliberately
// NOT the AuthError/AuthzError/NetworkError taxonomy (§12 port addendum
// item 9).
ExtraParams map[string]string
}
OidcBeginParams are the arguments to OidcBegin — a pure local computation, no network I/O. ClientID comes from the Client's own configuration (WithOidcClientID), not a per-call argument (§12 T1 judgment call 21).
type OidcConfiguration ¶
type OidcConfiguration struct {
// Issuer is the value an ID token's `iss` claim must equal exactly.
Issuer string `json:"issuer"`
// AuthorizationEndpoint is what OidcBegin builds its redirect URL from.
AuthorizationEndpoint string `json:"authorization_endpoint"`
// TokenEndpoint is used by OidcExchange, OidcRefresh and
// LoginClientCredentials.
TokenEndpoint string `json:"token_endpoint"`
// UserinfoEndpoint is advertised by the server but deliberately NEVER
// called by this SDK (§12.3 rule 5).
UserinfoEndpoint string `json:"userinfo_endpoint"`
// JwksURI is the JWKS document whose keys verify ID-token signatures
// (§12.4 rule 2).
JwksURI string `json:"jwks_uri"`
// RevocationEndpoint is the RFC 7009 endpoint used by Revoke.
RevocationEndpoint string `json:"revocation_endpoint"`
// IntrospectionEndpoint is the RFC 7662 endpoint used by Introspect.
IntrospectionEndpoint string `json:"introspection_endpoint"`
// ResponseTypesSupported lists OAuth2 response_type values the server
// supports.
ResponseTypesSupported []string `json:"response_types_supported"`
// SubjectTypesSupported lists subject identifier types the server
// supports.
SubjectTypesSupported []string `json:"subject_types_supported"`
// IDTokenSigningAlgValuesSupported is informational only: §12.4 rule 1
// pins verification to EdDSA regardless of what appears here.
IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported"`
// ScopesSupported lists scopes the server supports.
ScopesSupported []string `json:"scopes_supported"`
// TokenEndpointAuthMethodsSupported lists the client-authentication
// methods the token endpoint supports (client_secret_post, §12.1 note 3).
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"`
// ClaimsSupported lists claims the server may include in an ID token.
ClaimsSupported []string `json:"claims_supported"`
// GrantTypesSupported lists grant types the token endpoint supports.
GrantTypesSupported []string `json:"grant_types_supported"`
// CodeChallengeMethodsSupported lists the RFC 7636 PKCE code-challenge
// methods the authorization endpoint accepts (RFC 8414 §2; AXIAM
// advertises `["S256"]` as of contract 1.42, §21.5).
//
// Informational only: OidcBegin and OidcPar send S256 unconditionally and
// this SDK implements no other method, so nothing here can widen what the
// SDK does.
//
// Nil when absent, and absence is NOT "S256". §21.5 is explicit that
// RFC 8414 defines no default for this member — an OP that omits it has
// not told a conforming client that PKCE is available at all. Modelled
// optional even though openapi.json now marks it required, because this
// type must keep parsing a discovery document from a non-AXIAM OP; every
// conditionally-advertised member around it is modelled the same way.
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
// TokenEndpointAuthSigningAlgValuesSupported lists the JWS algorithms the
// token endpoint accepts on a `private_key_jwt` client assertion
// (RFC 8414 §2; AXIAM advertises `["PS256", "ES256", "EdDSA"]` as of
// contract 1.42, §21.5).
//
// Informational, and nil-when-absent for the same reason as the member
// above it.
TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported,omitempty"`
// DeviceAuthorizationEndpoint is the RFC 8628 endpoint used by
// DeviceAuthorize (§14.1).
//
// Empty when the server does not implement the device grant, or when the
// document came from a non-AXIAM OP. Its absence is an error at call time,
// never a cue to build the URL by concatenation.
DeviceAuthorizationEndpoint string `json:"device_authorization_endpoint,omitempty"`
// PushedAuthorizationRequestEndpoint is the RFC 9126 endpoint used by
// OidcPar (§26.1).
//
// Empty for the same reason as the two around it, and with the same rule:
// its absence is an error at call time, never a cue to build
// <issuer>/oauth2/par by concatenation.
PushedAuthorizationRequestEndpoint string `json:"pushed_authorization_request_endpoint,omitempty"`
// EndSessionEndpoint is the OIDC RP-Initiated Logout 1.0 endpoint used by
// LogoutURL (§12.7.2 rule 1).
//
// Empty for the same reason, and the rule is stricter here: §12.7.2 rule 1
// forbids synthesising this URL from the issuer. Code that concatenates
// works against AXIAM and breaks against every other OP the same
// application is pointed at.
EndSessionEndpoint string `json:"end_session_endpoint,omitempty"`
// BackchannelLogoutSupported reports whether the OP sends logout tokens.
BackchannelLogoutSupported bool `json:"backchannel_logout_supported,omitempty"`
// BackchannelLogoutSessionSupported reports whether those tokens carry
// `sid`. AXIAM always sends it.
BackchannelLogoutSessionSupported bool `json:"backchannel_logout_session_supported,omitempty"`
// MtlsEndpointAliases carries the RFC 8705 §5 endpoint aliases for a
// deployment that terminates mutual TLS on a host other than the issuer's
// own (contract 1.40, §21.3 rule 2).
//
// A pointer, and NIL MEANS "no separate host", not "mTLS unsupported": a
// deployment running client_auth = optional on one listener serves both
// populations at the conventional endpoints and correctly publishes
// nothing here. A client treating absence as an error would refuse the
// most common mTLS topology AXIAM ships. The server omits the key rather
// than serialising null, and omitempty keeps this type's own output the
// same shape.
MtlsEndpointAliases *MtlsEndpointAliases `json:"mtls_endpoint_aliases,omitempty"`
}
OidcConfiguration is the OIDC Discovery 1.0 metadata document served by `GET /.well-known/openid-configuration` (wire schema OidcDiscoveryDocument, CONTRACT.md §12.1). Every field is required by the server's schema.
Issuer is the AUTHORITATIVE issuer for ID-token validation (§12.4 rule 3). It may legitimately differ from the client's base URL when AXIAM runs behind a proxy, so this SDK never rejects a document on an issuer/base-URL mismatch (§12.3 rule 6). Likewise JwksURI is read from here rather than hardcoded.
type OidcExchangeParams ¶
type OidcExchangeParams struct {
// Code is the authorization code the IdP redirected back with.
Code string
// CodeVerifier is the verifier from the matching AuthorizationRequest.
CodeVerifier Sensitive
// RedirectURI is the same redirect_uri that was sent on the
// authorization request.
RedirectURI string
// Nonce is the nonce from the matching AuthorizationRequest. MANDATORY —
// §12.4 rule 6 is not optional for this grant.
Nonce string
// TenantID is the tenant UUID for the token endpoint's required
// tenant_id query parameter. When empty, falls back to the tenant UUID
// resolved from a prior successful Login/Refresh (§12.3 rule 4).
TenantID string
// Configuration is a pre-fetched discovery document, to avoid
// re-reading the (cached) one. Fetched via OidcDiscover when nil.
Configuration *OidcConfiguration
}
OidcExchangeParams are the arguments to OidcExchange (`grant_type=authorization_code`).
type OidcParParams ¶
type OidcParParams struct {
// Request is what OidcBegin returned. Its URL is replaced by the
// PushedAuthorizationRequest's AuthorizationURL.
Request AuthorizationRequest
// RedirectURI is the relying party's redirect URI — the same value that
// will be sent at OidcExchange (§26.2 rule 6).
RedirectURI string
// Scope is the requested scope. openid is added when absent, exactly as
// OidcBegin does.
Scope string
// TenantID overrides the mandatory ?tenant_id= query parameter (§12.1 note 2).
TenantID string
// DPoPJKT is the RFC 7638 JWK SHA-256 thumbprint of the key the client
// will prove possession of at the token endpoint — RFC 9449 §10.1's
// `dpop_jkt` authorization-request parameter, accepted on PAR as of
// contract 1.42.
//
// Optional, and sent ONLY when non-empty: RFC 9449 §10.1 makes it a
// client choice, and an empty `dpop_jkt=` on the wire is a value, not an
// omission.
//
// CALLER-SUPPLIED, deliberately. This SDK implements the DPoP
// RESOURCE-SERVER half only (VerifyDPoPProof, §21.7.2) and holds no
// client key it could thumbprint, so there is nothing for it to compute
// here. An application that does hold such a key — one binding its own
// JOSE stack for the client role — computes the thumbprint over that
// key's public JWK and passes it in. Accepting the value costs nothing
// and closes RFC 9449 §10's authorization-code-injection gap for those
// callers; synthesising a proof generator to fill it in would be new
// surface, not a re-sync.
//
// Binding it at the PUSH is the point: the thumbprint travels over the
// authenticated back channel with everything else, so it cannot be
// stripped or swapped in the browser the way an inline `dpop_jkt` on
// /oauth2/authorize can.
DPoPJKT string
// Configuration is the discovery document; fetched via OidcDiscover when zero.
Configuration *OidcConfiguration
}
OidcParParams are the arguments to OidcPar.
type OidcRefreshParams ¶
type OidcRefreshParams struct {
// RefreshToken is the refresh token to redeem.
RefreshToken Sensitive
// Scope is an optional narrowed scope to request. Omitted from the form
// body when empty.
Scope string
// TenantID is the tenant UUID for the tenant_id query parameter (§12.3
// rule 4).
TenantID string
// Configuration is a pre-fetched discovery document. Fetched via
// OidcDiscover when nil.
Configuration *OidcConfiguration
}
OidcRefreshParams are the arguments to OidcRefresh (`grant_type=refresh_token`).
type OidcStateEntry ¶
type OidcStateEntry struct {
// State is the `state` value this entry is keyed by. Not a secret
// (§12.3 rule 2).
State string
// Nonce is checked against the ID token's `nonce` claim. Not a secret
// (§12.3 rule 2).
Nonce string
// CodeVerifier is the PKCE verifier for the matching authorization
// request (§12.5 secret).
CodeVerifier Sensitive
// RedirectURI is the redirect_uri that was sent on the authorization
// request and must be replayed on exchange.
RedirectURI string
// ReturnTo is optional application-owned data, e.g. the page the user
// was heading to before login.
ReturnTo string
}
OidcStateEntry is the tuple an OidcStateStore holds for one in-flight login.
CodeVerifier stays Sensitive while stored (§12.5: the verifier is secret for its whole lifetime, "including ... in any OidcStateStore entry").
type OidcStateStore ¶
type OidcStateStore interface {
// Save persists entry, keyed by its State, starting its TTL now.
Save(entry OidcStateEntry) error
// Consume atomically fetches AND REMOVES the entry for state. ok is
// false when the state is unknown, already consumed, or expired — three
// cases a caller MUST treat identically (as a failed login), because
// distinguishing them leaks whether a state ever existed.
Consume(state string) (entry OidcStateEntry, ok bool)
}
OidcStateStore is an OPTIONAL server-side store for in-flight OidcBegin state (CONTRACT.md §12.3 rule 1).
Implement this to back the login/callback handlers with your own storage (Redis, a database, an encrypted cookie). Two invariants are normative:
- Single-use: Consume MUST return the entry AND delete it atomically, so a replayed callback cannot reuse a state.
- Expiry: an entry older than the store's TTL (10 minutes, at most — OidcStateTTL) MUST NOT be returned.
type OidcTokenSet ¶
type OidcTokenSet struct {
// AccessToken is the OAuth2 access token (§12.5 secret).
AccessToken Sensitive
// TokenType is the token type the server issued ("Bearer").
TokenType string
// ExpiresIn is the access-token lifetime in seconds from the time of the
// response.
ExpiresIn int64
// Scope is the granted scope, when the server narrowed or echoed it.
Scope string
// RefreshToken is the refresh token, when the grant issued one (§12.5
// secret). Empty when absent.
RefreshToken Sensitive
// IDToken is the raw ID token, when the grant issued one (§12.5 secret).
// Empty when absent.
IDToken Sensitive
// IDClaims is the validated ID-token claims — non-nil exactly when
// IDToken is non-empty (§12.1, §12.4).
IDClaims *IDTokenClaims
}
OidcTokenSet is a token set returned by the OAuth2 token endpoint (wire schema TokenResponse), returned by OidcExchange, OidcRefresh and LoginClientCredentials.
AccessToken, RefreshToken and IDToken are Sensitive (§12.5): String()/ fmt/JSON all redact them to "[SENSITIVE]", and the raw value is reachable only through the package-internal expose() accessor. RefreshToken and IDToken are the empty string when the grant did not issue one — no legitimate token is ever the empty string, matching the convention LoginResult.MFAToken already uses.
IDClaims is non-nil exactly when IDToken is non-empty, and holds the ALREADY-VALIDATED claim set (§12.4) — validation happens before this value is ever constructed, so an OidcTokenSet in your hands is never partially trusted (§12.4 rule 7).
type OpaqueEnrollment ¶
type OpaqueEnrollment struct {
OpaqueSession string `json:"opaque_session"`
RegistrationRecord string `json:"registration_record"`
}
OpaqueEnrollment is a completed registration record, to send with any request that sets a password.
Two fields, where the SRP verifier it replaces had seven. The server chose the credential identifier, the ciphersuite and the costs and sealed them into OpaqueSession — which is why a client cannot name any of them, and why it cannot enrol a record against somebody else's account.
type OpaqueEnrollmentPayload ¶
type OpaqueEnrollmentPayload struct {
// OpaqueSession The `opaque_session` from the register/start response, echoed verbatim.
OpaqueSession string `json:"opaque_session"`
// RegistrationRecord Lowercase-hex serialized RFC 9807 `RegistrationRecord`.
RegistrationRecord string `json:"registration_record"`
}
OpaqueEnrollmentPayload The client-supplied half of an OPAQUE enrolment, as it appears inside registration / change-password / reset-completion / bootstrap request bodies. There is no standalone `register/finish` endpoint, deliberately. A record can only be created at a moment when the plaintext password legitimately exists on the client, and every one of those moments is already an endpoint that takes a password. A free-standing finish would be an endpoint whose only job is to attach a credential to an account, which is a thing worth not having. Kept separate from [`CreateOpaqueCredential`] because the tenant, the user and the credential identifier are all decided by the server — a client that could name them could enrol a record against somebody else's account.
type OpaqueKsfParams ¶
type OpaqueKsfParams struct {
Ksf string `json:"ksf"`
MemoryKiB *uint32 `json:"memory_kib,omitempty"`
Iterations *uint32 `json:"iterations,omitempty"`
Parallelism *uint32 `json:"parallelism,omitempty"`
LogN *uint8 `json:"log_n,omitempty"`
R *uint32 `json:"r,omitempty"`
P *uint32 `json:"p,omitempty"`
}
OpaqueKsfParams are the key-stretching parameters a server named.
Flat and optional, matching the wire format: the fields that do not apply to the named function are absent, NOT zero. Reading an absent field as 0 would stretch with the wrong cost and fail against a record that is perfectly good (§23.4 rule 5).
type OpaquePolicy ¶
type OpaquePolicy struct {
// OpaqueKsf Key-stretching function new records are enrolled under. Both variants
// are memory-hard; see [`opaque_ksf_is_at_least`] for the tighten-only
// ordering.
OpaqueKsf string `json:"opaque_ksf"`
// OpaqueMode Whether OPAQUE is offered, and whether password login is still
// accepted.
OpaqueMode string `json:"opaque_mode"`
// OpaqueSuite RFC 9807 ciphersuite new records are enrolled under.
OpaqueSuite string `json:"opaque_suite"`
}
OpaquePolicy Secure Remote Password policy. `suite` and `ksf` are the parameters a *new* registration record is enrolled with. They deliberately do not apply retroactively: an existing record is only valid under the suite and KSF it was created with, so tightening these takes effect as users next set a password rather than invalidating everybody at once.
type Option ¶
type Option func(*clientConfig)
Option configures a Client at construction time (D-03).
func WithClientCertificate ¶
WithClientCertificate configures a client-certificate identity for mutual TLS (CONTRACT.md §6.1). certPEM is a PEM-encoded X.509 certificate chain and keyPEM is the matching PEM-encoded private key (PKCS#8 or PKCS#1). The SDK presents this identity on BOTH the REST transport (here) and any gRPC channel built for the same logical client (grpc.NewTLSCredentials).
Presenting a client certificate NEVER relaxes server verification: this is additive to WithCustomCA/§6 and keeps the SDK's TLS-1.3 floor and strict RootCAs behavior unchanged. A non-PEM cert/key pair is a construction-time error returned from NewClient, consistent with WithCustomCA.
The private key is secret material (§7): it is held behind the SDK's Sensitive type and never appears in any log, error, or display output.
func WithCustomCA ¶
WithCustomCA adds a PEM-encoded CA certificate to the TLS verification chain (§6). This is the ONLY TLS-related escape hatch — there is no option anywhere in this SDK that disables or weakens certificate verification. Returns a construction-time error via NewClient if pem is not valid PEM.
func WithDecisionMemoTTL ¶
WithDecisionMemoTTL enables the CONTRACT.md §17 client-side decision memo.
DISABLED BY DEFAULT — §11.2 rule 6's ban on caching authorization decisions is still the default behaviour, and this is the single opt-in exception.
What you are accepting: the staleness bound is ttl IN BOTH DIRECTIONS. A grant revoked on the server can still read as allowed for up to the TTL, and a grant just added can still read as denied for up to the TTL.
READS-YOUR-OWN-WRITES IS NOT GUARANTEED. An admin UI that grants a role and immediately re-checks is the case that breaks, and it breaks silently. If that is your workload, do not set this.
ttl is clamped to MaxMemoTTL rather than rejected, so asking for a minute gets you five seconds. Allows and denies are memoized identically (asymmetric caching leaks the outcome through latency), failures are never memoized, and the memo is cleared on any credential change.
func WithHTTPClient ¶
WithHTTPClient supplies a base *http.Client whose Transport/Timeout the SDK adopts. D-09: the SDK ALWAYS re-applies its own cookiejar and TLS config over the supplied client afterward — an override can never silently drop the jar (breaking every post-login request) or bypass TLS verification.
func WithLogger ¶
func WithOidcClientID ¶
WithOidcClientID sets the relying party's OAuth2 client_id (CONTRACT.md §12.1), used on every §12 grant and matched against the ID token's aud/azp (§12.4 rule 4). Required before calling any §12 operation other than OidcDiscover.
func WithOidcClientSecret ¶
WithOidcClientSecret configures a confidential client's client_secret (CONTRACT.md §12.1), held behind Sensitive (§12.5). Omit for a public client: LoginClientCredentials, Introspect and Revoke then return an *AuthError client-side, without a wire call (§12.1 note 4 — a public client cannot call them).
func WithOidcClockSkew ¶
WithOidcClockSkew overrides the permitted ID-token clock skew, in seconds. Clamped to [1, MaxIDTokenClockSkewSec] (60s) per CONTRACT.md §12.4 rule 5 — the contract forbids configuring it above that bound.
func WithOidcDiscoveryTTL ¶
WithOidcDiscoveryTTL overrides the OIDC discovery-document cache TTL. Floored at MinOidcDiscoveryTTL (5 minutes) per CONTRACT.md §12.3 rule 6 — a smaller configured value is silently raised to the floor.
func WithOrgID ¶
WithOrgID sets the organization UUID the real login/refresh endpoints require (RESEARCH.md Pitfall 3). Mutually exclusive with WithOrgSlug — last call wins.
func WithOrgSlug ¶
WithOrgSlug sets the organization slug the real login/refresh endpoints require (RESEARCH.md Pitfall 3). Mutually exclusive with WithOrgID — last call wins.
func WithRetryDisabled ¶
func WithRetryDisabled() Option
WithLogger supplies an injectable, redaction-aware logger (CF-02). OFF by default (nil logger — the SDK never logs unless a logger is supplied). The SDK never emits raw token values regardless of the logger's configured level (Sensitive redacts itself in any log call). WithRetryDisabled turns off the CONTRACT.md §16 bounded read-only retry policy, making every operation exactly one attempt.
That is the right choice for a caller who owns their own retry layer — they know their deadline and this SDK does not — but it is not a way to make failures quieter: a transient *NetworkError simply surfaces immediately.
§16.1 permits this switch but forbids raising the attempt cap, base delay or delay cap above the contract's values, so there is no option for those: eleven SDKs agreeing on one table is the point.
func WithTelemetryHook ¶
func WithTelemetryHook(hook TelemetryHook) Option
WithTelemetryHook installs a CONTRACT.md §19 telemetry sink.
It receives request start/end, §16 retry and §9 refresh events, so metrics can be wired without this module depending on any metrics library. See examples/telemetry_hook.
A hook that panics cannot fail the operation that fired it (§19.2 rule 2), and no event payload can carry a token — TelemetryEvent is a closed interface with fixed field sets (§19.2 rule 3). It is invoked on the calling goroutine, so it must not block; buffer on your side if you need async delivery.
func WithTimeout ¶
WithTimeout overrides the default request timeout applied to the SDK's http.Client (CF-03; default 30s).
type Organization ¶
type Organization struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Metadata Arbitrary key-value metadata.
Metadata any `json:"metadata"`
// Name Human-readable name.
Name string `json:"name"`
// Slug URL-safe unique identifier (e.g., `acme-corp`).
Slug string `json:"slug"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Organization An organization groups multiple tenants under a single administrative entity. Organizations represent companies, departments, or business units. CA certificates are registered at the organization level, enabling a hierarchical trust model across all tenants.
type OrganizationsAPI ¶
type OrganizationsAPI struct {
// contains filtered or unexported fields
}
OrganizationsAPI is the organizations namespace handle.
Organizations an SDK client may read and configure. Creation and deletion are outside the SDK boundary (§27.0).
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*OrganizationsAPI) Get ¶
func (a *OrganizationsAPI) Get(ctx context.Context) (Organization, error)
Get issues GET /api/v1/organizations/{org_id}.
func (*OrganizationsAPI) InOrg ¶
func (a *OrganizationsAPI) InOrg(orgID uuid.UUID) *OrganizationsAPI
InOrg addresses a different organization than the client's own.
§27.4 rule 3: the client's organization is the default, and a platform-admin token legitimately overrides it. Returns a new handle; the original is unchanged.
func (*OrganizationsAPI) List ¶
func (a *OrganizationsAPI) List(ctx context.Context, page PageRequest) (Page[Organization], error)
List issues GET /api/v1/organizations.
func (*OrganizationsAPI) ListAll ¶
func (a *OrganizationsAPI) ListAll(ctx context.Context, start PageRequest) ([]Organization, error)
ListAll walks organizations.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*OrganizationsAPI) Update ¶
func (a *OrganizationsAPI) Update(ctx context.Context, body UpdateOrganizationRequest) (Organization, error)
Update issues PUT /api/v1/organizations/{org_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type PGPKey ¶
type PGPKey struct {
// Algorithm carries the server's algorithm field.
Algorithm PGPKeyAlgorithm `json:"algorithm"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Fingerprint OpenPGP key fingerprint (hex).
Fingerprint string `json:"fingerprint"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// PublicKeyArmored carries the server's public_key_armored field.
PublicKeyArmored string `json:"public_key_armored"`
// Purpose carries the server's purpose field.
Purpose PGPKeyPurpose `json:"purpose"`
// Status carries the server's status field.
Status PGPKeyStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
}
PGPKey An OpenPGP key stored by AXIAM.
type PGPKeyAlgorithm ¶
type PGPKeyAlgorithm string
PGPKeyAlgorithm Key algorithm for OpenPGP keys.
const ( PGPKeyAlgorithmRsa4096 PGPKeyAlgorithm = "Rsa4096" PGPKeyAlgorithmEd25519 PGPKeyAlgorithm = "Ed25519" )
The PGPKeyAlgorithm values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type PGPKeyPurpose ¶
type PGPKeyPurpose string
PGPKeyPurpose The purpose of an OpenPGP key.
const ( PGPKeyPurposeAuditSigning PGPKeyPurpose = "AuditSigning" PGPKeyPurposeExport PGPKeyPurpose = "Export" )
The PGPKeyPurpose values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type PGPKeyStatus ¶
type PGPKeyStatus string
PGPKeyStatus Status of an OpenPGP key.
const ( PGPKeyStatusActive PGPKeyStatus = "Active" PGPKeyStatusRevoked PGPKeyStatus = "Revoked" )
The PGPKeyStatus values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type PGPKeysAPI ¶
type PGPKeysAPI struct {
// contains filtered or unexported fields
}
PGPKeysAPI is the pgp_keys namespace handle.
OpenPGP keys used for audit signing and encrypted data export.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*PGPKeysAPI) Encrypt ¶
func (a *PGPKeysAPI) Encrypt(ctx context.Context, id uuid.UUID, body EncryptRequest) (EncryptedExport, error)
Encrypt issues POST /api/v1/pgp-keys/{id}/encrypt.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PGPKeysAPI) Generate ¶
func (a *PGPKeysAPI) Generate(ctx context.Context, body CreatePGPKeyRequest) (GeneratedPGPKey, error)
Generate issues POST /api/v1/pgp-keys.
Returns secret material, once. private_key_armored is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PGPKeysAPI) List ¶
func (a *PGPKeysAPI) List(ctx context.Context, page PageRequest) (Page[PGPKey], error)
List issues GET /api/v1/pgp-keys.
func (*PGPKeysAPI) ListAll ¶
func (a *PGPKeysAPI) ListAll(ctx context.Context, start PageRequest) ([]PGPKey, error)
ListAll walks pgp_keys.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*PGPKeysAPI) Revoke ¶
Revoke issues POST /api/v1/pgp-keys/{id}/revoke.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PGPKeysAPI) SignAuditBatch ¶
func (a *PGPKeysAPI) SignAuditBatch(ctx context.Context, body SignAuditBatchRequest) (SignedAuditBatch, error)
SignAuditBatch issues POST /api/v1/pgp-keys/sign-audit-batch.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type Page ¶
type Page[T any] struct { // Items are the items on this page. Items []T `json:"items"` // Total is how many items exist in the whole set, across every page. Total int `json:"total"` // Offset is the offset this page starts at. Offset int `json:"offset"` // Limit is the page size the server applied. Limit int `json:"limit"` }
Page is one page of a paginated management read.
type PageRequest ¶
type PageRequest struct {
// Offset is how many items to skip.
Offset int
// Limit is how many items to take. Nil lets the server decide.
Limit *int
// Search is a free-text filter applied by the SERVER, before Offset/Limit.
//
// Matched case-insensitively against the identifying fields of whatever is
// being listed — a name or username, plus the record id, so a UUID out of a
// log line can be pasted in as-is. Page.Total then counts MATCHES, not rows,
// which is what lets a pager built on it show a page count belonging to the
// result set it is paging.
//
// It lives here rather than as a third argument on each of the twenty
// generated List methods (§27.4 rule 4), and that is what makes ListAll
// carry it across the whole walk — a walk that filtered its first request
// and not the rest would return the matches followed by the unfiltered tail.
//
// The zero value sends no search parameter. A term that is all whitespace is
// treated the same way: a search box that fires on every keystroke sends one
// the moment it is cleared, and "rows containing the empty string" is a
// different question from "all rows".
//
// The server caps the term's length. This SDK deliberately does not
// re-implement that cap — a client-side truncation the server would not have
// made is a silently different query.
Search string
}
PageRequest says where a paginated read starts and how much of it to take.
Limit is deliberately a pointer with no SDK-side default: §27.4 rule 4 forbids silently truncating, and a client-side default does exactly that while leaving the caller no way to tell a short page from a complete one. A nil Limit lets the server decide.
func Limited ¶
func Limited(n int) PageRequest
Limited returns a PageRequest asking the server for n items per page.
func Matching ¶
func Matching(n int, term string) PageRequest
Matching returns a PageRequest of n items per page, filtered by term.
The §27.4 rule 4 shape: the term rides on the page request, so ListAll carries it across every request of the walk rather than only the first.
type PasswordPolicy ¶
type PasswordPolicy struct {
// HibpCheckEnabled carries the server's hibp_check_enabled field.
HibpCheckEnabled bool `json:"hibp_check_enabled"`
// MinLength carries the server's min_length field.
MinLength int `json:"min_length"`
// PasswordHistoryCount carries the server's password_history_count field.
PasswordHistoryCount int `json:"password_history_count"`
// RequireDigits carries the server's require_digits field.
RequireDigits bool `json:"require_digits"`
// RequireLowercase carries the server's require_lowercase field.
RequireLowercase bool `json:"require_lowercase"`
// RequireSymbols carries the server's require_symbols field.
RequireSymbols bool `json:"require_symbols"`
// RequireUppercase carries the server's require_uppercase field.
RequireUppercase bool `json:"require_uppercase"`
}
PasswordPolicy Password complexity and history requirements.
type PasswordResetConfirmation ¶
type PasswordResetConfirmation struct {
// Token is the single-use token from the reset mail.
Token Sensitive
// NewPassword is the replacement password.
NewPassword Sensitive
// TenantID is the tenant the account belongs to. A UUID, and a BODY field —
// this is not an /oauth2/* endpoint.
TenantID string
// Opaque is the §23 registration record, for a tenant whose
// PasswordResetContext says it requires one. Sending a plaintext
// NewPassword to a tenant in opaque_mode: required is refused, and refused
// late (§25.4 rule 1).
Opaque map[string]any
}
PasswordResetConfirmation carries everything ConfirmPasswordReset needs.
type PasswordResetContext ¶
type PasswordResetContext struct {
// Opaque carries the tenant's OPAQUE parameters when it has OPAQUE
// enabled, and is nil when plaintext is accepted.
Opaque map[string]any `json:"opaque,omitempty"`
}
PasswordResetContext is the effective OPAQUE policy for the account a reset token belongs to.
It discloses no identity. Contract 1.26 removed the username from this response when OPAQUE replaced SRP — OPAQUE has no identity in its key derivation, so nothing needed it, and an unauthenticated endpoint that confirms which account a token belongs to is an oracle worth not having (§25.4 rule 2).
type PasswordResetRequest ¶
PasswordResetRequest names the account a reset mail should go to.
Slugs are accepted here, as on Login — this is not an /oauth2/* endpoint and §12.1 rule 2's UUID requirement does not reach it. Empty fields fall back to the client's own configuration.
type Permission ¶
type Permission struct {
// Action The action this permission represents (e.g., `read`, `write`,
// `delete`).
Action string `json:"action"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Permission is the Permission schema from the server's OpenAPI document.
type PermissionEffect ¶
type PermissionEffect string
PermissionEffect Whether a grant permits an action or refuses it (B1, deny-override). # Precedence Default deny -> an [`PermissionEffect::Allow`] grant permits -> a [`PermissionEffect::Deny`] grant refuses, **and beats every allow**, wherever either sits in the resource hierarchy. Deny wins; there is no most-specific-wins tie-break. That choice is deliberate and is argued in full in `claude_dev/deny-override-design.md` §2.1. The short version: deny-override buys one checkable property — **adding a deny rule can never widen access, and can never be undone by adding allows** — and most-specific-wins buys expressiveness at the cost of making "is X denied?" unanswerable without enumerating every other rule that might out-specify it. [`PermissionEffect::Allow`] is the default, so data written before this existed, and clients that send no `effect`, both mean "allow". No migration.
const ( PermissionEffectAllow PermissionEffect = "allow" PermissionEffectDeny PermissionEffect = "deny" )
The PermissionEffect values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type PermissionSpec ¶
type PermissionSpec struct {
// Key is the manifest-local identifier a role's grants refer to.
Key string
// Action is the action — the permission's natural key within the tenant.
Action string
// Description is human-readable. The server requires one.
Description string
}
PermissionSpec is a permission — an action, tenant-wide.
type PermissionsAPI ¶
type PermissionsAPI struct {
// contains filtered or unexported fields
}
PermissionsAPI is the permissions namespace handle.
Permissions -- an action on a resource, optionally narrowed by a scope.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*PermissionsAPI) Create ¶
func (a *PermissionsAPI) Create(ctx context.Context, body CreatePermissionRequest) (Permission, error)
Create issues POST /api/v1/permissions.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PermissionsAPI) Delete ¶
Delete issues DELETE /api/v1/permissions/{permission_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PermissionsAPI) Get ¶
func (a *PermissionsAPI) Get(ctx context.Context, permissionID uuid.UUID) (Permission, error)
Get issues GET /api/v1/permissions/{permission_id}.
func (*PermissionsAPI) List ¶
func (a *PermissionsAPI) List(ctx context.Context, page PageRequest) (Page[Permission], error)
List issues GET /api/v1/permissions.
func (*PermissionsAPI) ListAll ¶
func (a *PermissionsAPI) ListAll(ctx context.Context, start PageRequest) ([]Permission, error)
ListAll walks permissions.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*PermissionsAPI) Update ¶
func (a *PermissionsAPI) Update(ctx context.Context, permissionID uuid.UUID, body UpdatePermissionRequest) (Permission, error)
Update issues PUT /api/v1/permissions/{permission_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type PlannedAction ¶
type PlannedAction struct {
// Change is whether this step creates, updates, or does nothing.
Change Change
// Target is what kind of thing it acts on.
Target Target
// Key is the manifest key it came from, for a human reading the plan.
Key string
// Summary is a one-line description, stable across runs so plans diff.
Summary string
}
PlannedAction is one step of a plan.
type PlatformAPI ¶
type PlatformAPI struct {
// contains filtered or unexported fields
}
PlatformAPI is the platform namespace handle.
Deployment-level probes and FIDO metadata state. Unauthenticated where the server leaves them so.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*PlatformAPI) Health ¶
func (a *PlatformAPI) Health(ctx context.Context) (HealthResponse, error)
Health issues GET /health.
func (*PlatformAPI) MDSRefresh ¶
func (a *PlatformAPI) MDSRefresh(ctx context.Context) (MDSRefreshOutcome, error)
MDSRefresh issues POST /api/v1/mds/refresh.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PlatformAPI) MDSStatus ¶
func (a *PlatformAPI) MDSStatus(ctx context.Context) (MDSStatusResponse, error)
MDSStatus issues GET /api/v1/mds/status.
func (*PlatformAPI) Ready ¶
func (a *PlatformAPI) Ready(ctx context.Context) (ReadyResponse, error)
Ready issues GET /ready.
type PolicyResponse ¶
type PolicyResponse struct {
// AllowedAaguids `None` = every AAGUID is allowed except `blocked_aaguids`.
// `Some(vec![])` is a deliberate "nothing may register" policy and is
// accepted as such: `evaluate` denies every AAGUID against an empty
// allow-list. Nothing rejects it, precisely because the failure direction
// is safe — a client that sends `[]` when it meant `null` gets a
// locked-down tenant, which is visible immediately, rather than an open
// one, which is not.
AllowedAaguids []uuid.UUID `json:"allowed_aaguids,omitempty"`
// BlockRevokedStatus Deny registration if the MDS entry has ever reported `REVOKED` or any
// `*_COMPROMISE` status (sticky — D8 step 7).
BlockRevokedStatus bool `json:"block_revoked_status"`
// BlockedAaguids carries the server's blocked_aaguids field.
BlockedAaguids []uuid.UUID `json:"blocked_aaguids,omitempty"`
// EffectiveUnknownAAGUID The action actually applied to an AAGUID with no MDS metadata, with
// `unknown_aaguid: null` resolved against `mode`. Read-only — `PUT`
// ignores it.
EffectiveUnknownAAGUID UnknownAAGUIDAction `json:"effective_unknown_aaguid"`
// MinCertification carries the server's min_certification field.
MinCertification *CertificationLevel `json:"min_certification,omitempty"`
// Mode carries the server's mode field.
Mode AttestationMode `json:"mode"`
// RequireFidoCertified Require *some* `FIDO_CERTIFIED*` status, any level. Independent of (and
// checked before) `min_certification`.
RequireFidoCertified bool `json:"require_fido_certified"`
// UnknownAAGUID carries the server's unknown_aaguid field.
UnknownAAGUID *UnknownAAGUIDAction `json:"unknown_aaguid,omitempty"`
}
PolicyResponse `GET` response: the stored policy plus the unknown-AAGUID action it currently *resolves to*. `unknown_aaguid` is nullable, where `null` means "use this mode's default" (deny under `direct_required`, allow otherwise). A client that only saw the stored `null` would have to re-derive that rule itself to display what the policy actually does — and a security rule implemented twice is a security rule that will eventually disagree with itself. So the server resolves it once, here, and reports both: the admin's stored intent and its effect.
type PresentedProofs ¶
type PresentedProofs = jwks.PresentedProofs
PresentedProofs carries what the caller proved about this connection and this request. See VerifyTokenBinding.
type PrivacyAPI ¶
type PrivacyAPI struct {
// contains filtered or unexported fields
}
PrivacyAPI is the privacy namespace handle.
GDPR self-service: the authenticated account's own export and erasure. Scoped to the caller, never to another user.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*PrivacyAPI) CancelDelete ¶
func (a *PrivacyAPI) CancelDelete(ctx context.Context, token string) error
CancelDelete issues GET /api/v1/auth/account/delete/cancel.
func (*PrivacyAPI) DownloadExport ¶
func (a *PrivacyAPI) DownloadExport(ctx context.Context, token string) error
DownloadExport issues GET /api/v1/account/export/{token}.
func (*PrivacyAPI) GrantScopeConsent ¶
func (a *PrivacyAPI) GrantScopeConsent(ctx context.Context, body GrantScopeConsent) error
GrantScopeConsent issues POST /api/v1/account/consents/oidc-scopes.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PrivacyAPI) ListConsents ¶
func (a *PrivacyAPI) ListConsents(ctx context.Context) ([]ConsentView, error)
ListConsents issues GET /api/v1/account/consents.
func (*PrivacyAPI) RequestDelete ¶
func (a *PrivacyAPI) RequestDelete(ctx context.Context, body any) error
RequestDelete issues POST /api/v1/account/delete.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PrivacyAPI) RequestExport ¶
func (a *PrivacyAPI) RequestExport(ctx context.Context, body any) error
RequestExport issues POST /api/v1/account/export.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*PrivacyAPI) WithdrawScopeConsent ¶
func (a *PrivacyAPI) WithdrawScopeConsent(ctx context.Context, clientID string) error
WithdrawScopeConsent issues DELETE /api/v1/account/consents/oidc-scopes/{client_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type PrivacyPolicy ¶
type PrivacyPolicy struct {
// DeletionGracePeriodDays How long a requested account erasure stays cancellable before the purge
// runs, in days. The window exists so an erasure triggered by mistake, or
// under coercion, can be undone — `POST
// /api/v1/auth/account/delete/cancel` works for exactly this long. It was
// fixed at 30 days in the handler, which meant the "cancel a pending
// deletion" control in the admin UI referred to a duration no operator
// could see or change. Shorter is the more restrictive direction, so a
// tenant may lower it and not raise it: it is time spent holding data the
// subject has already asked to have erased, and GDPR Art. 17(1) asks for
// that to be "without undue delay". The upper bound of 90 days is where
// Art. 12(3)'s one-month response deadline plus its two-month extension
// for complex cases runs out; anything past 30 wants a reason recorded.
DeletionGracePeriodDays int `json:"deletion_grace_period_days"`
}
PrivacyPolicy Data-retention rules that apply after a subject asks to be erased.
type ProviderConfig ¶
type ProviderConfig struct {
// Kind is the discriminator: it says which of the fields below are set.
Kind string `json:"kind"`
// APIURL Override base URL (useful for testing / self-hosted instances).
APIURL *string `json:"api_url,omitempty"`
// Host carries the server's host field.
Host *string `json:"host,omitempty"`
// Port carries the server's port field.
Port *int `json:"port,omitempty"`
// Starttls Use STARTTLS (true) or implicit TLS (false).
Starttls *bool `json:"starttls,omitempty"`
// Username carries the server's username field.
Username *string `json:"username,omitempty"`
}
ProviderConfig Provider-specific connection details.
Go has no sum type, so every arm's fields live on this one struct as pointers and kind says which are set: kind="smtp" carries host, port, starttls, username. kind="send_grid" carries api_url. kind="postmark" carries api_url. kind="resend" carries api_url. kind="brevo" carries api_url. A field belonging to another arm is nil.
type PushedAuthorizationRequest ¶
type PushedAuthorizationRequest struct {
// AuthorizationURL is where to redirect the browser.
//
// It carries EXACTLY client_id and request_uri. Not response_type, not
// redirect_uri, not scope, not state — the server refuses a request that
// mixes a request_uri with inline authorization parameters rather than
// merging them, because merging is where parameter confusion lives
// (§26.2 rule 2).
AuthorizationURL string
// RequestURI is the opaque, single-use handle.
//
// Sensitive per §26.5: short-lived and single-use are both reasons it gets
// treated as harmless, but between the push and the redirect it is a
// bearer handle to a fully-formed authorization request, and a log line is
// the wrong place for it to sit for the length of that window.
RequestURI Sensitive
// ExpiresIn is the handle's lifetime in seconds. Not advisory (§26.2 rule 3).
ExpiresIn int
// State is the value to compare against what the IdP returns.
State string
// Nonce is the value that must equal the ID token's nonce claim.
Nonce string
// CodeVerifier is the PKCE verifier to pass into OidcExchange — the same
// one OidcBegin produced.
CodeVerifier Sensitive
}
PushedAuthorizationRequest is the result of OidcPar (CONTRACT.md §26.1).
The server answered 201 — RFC 9126 §2.2 specifies Created, and a success predicate written == 200 would treat every successful push as a failure.
State, Nonce and CodeVerifier are carried straight through from the AuthorizationRequest that was pushed: §26.2 rule 1 forbids a second generator, and rule 6 wants exactly one CodeVerifier so there is no second place for the two to disagree.
type ReactorEventDescriptor ¶
type ReactorEventDescriptor struct {
// DefaultFailurePolicy carries the server's default_failure_policy field.
DefaultFailurePolicy FailurePolicy `json:"default_failure_policy"`
// Description carries the server's description field.
Description string `json:"description"`
// Interceptable carries the server's interceptable field.
Interceptable bool `json:"interceptable"`
// Mutable carries the server's mutable field.
Mutable bool `json:"mutable"`
// MutableFields Exact field names, or a namespace prefix ending in `.` — `ext.`
// admits `ext.department` and nothing outside the namespace.
MutableFields []string `json:"mutable_fields"`
// Name carries the server's name field.
Name string `json:"name"`
}
ReactorEventDescriptor One hookable event, as the registry describes it.
type ReactorMode ¶
type ReactorMode string
ReactorMode How a reactor participates in an event.
const ( ReactorModeIntercept ReactorMode = "intercept" ReactorModeListen ReactorMode = "listen" )
The ReactorMode values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type ReactorResponse ¶
type ReactorResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// Events carries the server's events field.
Events []string `json:"events"`
// FailurePolicy carries the server's failure_policy field.
FailurePolicy FailurePolicy `json:"failure_policy"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// LastSeenAt When this reactor last consumed from its queue. `null` means it has
// never connected — which the admin UI shows differently from
// "connected once, silent since".
LastSeenAt *string `json:"last_seen_at,omitempty"`
// Mode carries the server's mode field.
Mode ReactorMode `json:"mode"`
// Name carries the server's name field.
Name string `json:"name"`
// Priority carries the server's priority field.
Priority int `json:"priority"`
// RecentTimeoutCount R2.3: dispatch failures against this registration in the last 24h whose
// cause was a timeout (as opposed to a rejected reply, a transport
// failure, or overload), capped at 100 — a health signal read from the
// audit trail R2.2 started writing, not a replacement for the audit log
// itself (`GET /api/v1/audit-log` is that).
RecentTimeoutCount int `json:"recent_timeout_count"`
// RecentVetoCount R2.3: operations this reactor's own reply *denied* in the last 24h,
// capped at 100. Distinct from `recent_timeout_count`: a veto is the
// reactor working as designed; a timeout is the reactor not answering.
RecentVetoCount int `json:"recent_veto_count"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// TimeoutMs carries the server's timeout_ms field.
TimeoutMs int `json:"timeout_ms"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
ReactorResponse is the ReactorResponse schema from the server's OpenAPI document.
type ReactorsAPI ¶
type ReactorsAPI struct {
// contains filtered or unexported fields
}
ReactorsAPI is the reactors namespace handle.
Registration of §22 AMQP extension actors -- the admin surface §22.9 describes, which no SDK could previously reach.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*ReactorsAPI) Create ¶
func (a *ReactorsAPI) Create(ctx context.Context, body CreateReactorRequest) (ReactorResponse, error)
Create issues POST /api/v1/reactors.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ReactorsAPI) Delete ¶
Delete issues DELETE /api/v1/reactors/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ReactorsAPI) Get ¶
func (a *ReactorsAPI) Get(ctx context.Context, id uuid.UUID) (ReactorResponse, error)
Get issues GET /api/v1/reactors/{id}.
func (*ReactorsAPI) List ¶
func (a *ReactorsAPI) List(ctx context.Context, page PageRequest) (Page[ReactorResponse], error)
List issues GET /api/v1/reactors.
func (*ReactorsAPI) ListAll ¶
func (a *ReactorsAPI) ListAll(ctx context.Context, start PageRequest) ([]ReactorResponse, error)
ListAll walks reactors.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*ReactorsAPI) ListEvents ¶
func (a *ReactorsAPI) ListEvents(ctx context.Context) ([]ReactorEventDescriptor, error)
ListEvents issues GET /api/v1/reactors/events.
func (*ReactorsAPI) Update ¶
func (a *ReactorsAPI) Update(ctx context.Context, id uuid.UUID, body UpdateReactorRequest) (ReactorResponse, error)
Update issues PUT /api/v1/reactors/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type ReadyResponse ¶
type ReadyResponse struct {
// Database carries the server's database field.
Database string `json:"database"`
// Status carries the server's status field.
Status string `json:"status"`
}
ReadyResponse is the ReadyResponse schema from the server's OpenAPI document.
type RefreshEvent ¶
type RefreshEvent struct {
Role RefreshRole
Duration time.Duration
}
RefreshEvent is emitted around a §9 single-flight refresh.
type RefreshRole ¶
type RefreshRole string
RefreshRole reports whether this caller performed a §9 refresh or waited on another goroutine's.
const ( // RefreshLeader means this caller performed the refresh. RefreshLeader RefreshRole = "leader" // RefreshFollower means this caller waited on another's refresh. RefreshFollower RefreshRole = "follower" )
type RequestEndEvent ¶
type RequestEndEvent struct {
Operation string
Method string
PathTemplate string
Attempt int
// Status is the HTTP status, or 0 when the call never got a response.
Status int
// Duration is the wall-clock time this attempt took.
Duration time.Duration
Outcome Outcome
}
RequestEndEvent is emitted after a call completes, success or failure.
type RequestStartEvent ¶
type RequestStartEvent struct {
// Operation is the canonical name, e.g. "CheckAccess".
Operation string
// Method is the HTTP method.
Method string
// PathTemplate is the route constant — "/api/v1/authz/check", never a URL
// with ids substituted in. A metric label carrying a UUID is a cardinality
// bomb.
PathTemplate string
// Attempt is 1 for the first try, incrementing per §16 retry.
Attempt int
}
RequestStartEvent is emitted before an outbound call leaves the SDK.
type RequestedPermission ¶
type RequestedPermission struct {
// ResourceID is the AXIAM resource id — the same UUID the Protection API
// returned as `_id`.
ResourceID string
// ResourceScopes are scope names, each of which the resource must already
// declare. Matched exactly: no prefix or wildcard semantics in either
// direction.
ResourceScopes []string
}
RequestedPermission is one (resource, scopes) pair a resource server requires (§20.1).
type RequestingPartyToken ¶
type RequestingPartyToken struct {
// AccessToken is the RPT itself (§20.6 secret).
AccessToken Sensitive
// TokenType is the token type (Bearer).
TokenType string
// ExpiresIn is min(claim token remaining, server ceiling, 300s).
ExpiresIn int
}
RequestingPartyToken is the result of the UMA ticket grant (§20.1).
There is NO RefreshToken field, and that is deliberate (§20.2 rule 5). The grant issues none, so an RPT cannot outlive the ticket that authorised it; an application that wants a fresh one re-runs the grant. This result never enters the §9 single-flight refresh guard — there is nothing to refresh.
type ResolvedPermissionGrant ¶
type ResolvedPermissionGrant struct {
// Effect Whether the grant permits or refuses.
Effect PermissionEffect `json:"effect"`
// Permission The permission this grant is about.
Permission Permission `json:"permission"`
// ScopeIDs The scope ids the grant is constrained to. Empty is the wildcard.
ScopeIDs []uuid.UUID `json:"scope_ids"`
// Scopes The scopes `scope_ids` names, in the same order where resolvable. A
// scope that cannot be resolved is **omitted** rather than represented by
// a placeholder, so this can be shorter than `scope_ids`. That happens
// when a scope was deleted while a grant still referenced it, and showing
// a name for something that no longer exists would be worse than showing
// one fewer chip beside a count that still says how many ids the grant
// carries.
Scopes []GrantedScope `json:"scopes"`
}
ResolvedPermissionGrant A permission grant with its scopes resolved. A superset of [`PermissionGrant`]: `scope_ids` is still present and still authoritative, so a client written before `scopes` existed is unaffected.
type Resource ¶
type Resource struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Metadata carries the server's metadata field.
Metadata any `json:"metadata"`
// Name carries the server's name field.
Name string `json:"name"`
// ParentID Parent resource ID for hierarchical organization. `None` for root
// resources.
ParentID *uuid.UUID `json:"parent_id,omitempty"`
// ResourceType The type of resource (e.g., `project`, `service`, `endpoint`).
ResourceType string `json:"resource_type"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UmaRegisteredBy The `client_id` that registered this resource through the UMA
// Protection API (X2), or `None` for a resource created any other way.
// Read-only from every ordinary path: [`UpdateResource`] cannot set it
// and [`CreateResource`] cannot either, so the only writer is the
// resource-registration handler. That is deliberate — the field backs a
// provenance badge in the admin UI, and a provenance marker anyone can
// write is decoration that reads like evidence.
UmaRegisteredBy *string `json:"uma_registered_by,omitempty"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Resource is the Resource schema from the server's OpenAPI document.
type ResourceSet ¶
type ResourceSet struct {
// ID is assigned by the server on registration; empty on the way in.
ID string
// Name is the human-readable name, shown in the admin UI.
Name string
// Type is a free-form resource type. Omitted from the payload when empty,
// so the server applies its own `uma_resource` default rather than storing
// an empty string that sorts oddly next to hand-made resources.
Type string
// ResourceScopes are the scope names a resource server may ask for on this
// resource.
//
// REPLACED WHOLESALE BY AN UPDATE, NEVER MERGED (§20.2 rule 8) — this SDK
// does not read the current scopes and fold them into an update payload as
// a convenience, because that would make removing a scope impossible
// through it.
ResourceScopes []string
}
ResourceSet is a UMA resource set — an AXIAM resource seen through the Protection API (CONTRACT.md §20.1).
ID is THE AXIAM RESOURCE ID, not a parallel identifier: the same UUID is directly usable as RequestedPermission.ResourceID, and as the resource id anywhere else in this SDK.
type ResourceSpec ¶
type ResourceSpec struct {
// Key is the manifest-local identifier Parent and grants refer to.
Key string
// Name is the resource's name — its natural key within the tenant.
Name string
// ResourceType is the server's resource_type discriminator.
ResourceType string
// Parent is the Key of this resource's parent, empty if it has none.
Parent string
// Scopes are the scopes declared under this resource.
Scopes []ScopeSpec
}
ResourceSpec is a resource in the hierarchy, and the scopes beneath it.
type ResourcesAPI ¶
type ResourcesAPI struct {
// contains filtered or unexported fields
}
ResourcesAPI is the resources namespace handle.
The resource hierarchy role assignments cascade down.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*ResourcesAPI) Create ¶
func (a *ResourcesAPI) Create(ctx context.Context, body CreateResourceRequest) (Resource, error)
Create issues POST /api/v1/resources.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ResourcesAPI) Delete ¶
Delete issues DELETE /api/v1/resources/{resource_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ResourcesAPI) List ¶
func (a *ResourcesAPI) List(ctx context.Context, page PageRequest) (Page[Resource], error)
List issues GET /api/v1/resources.
func (*ResourcesAPI) ListAll ¶
func (a *ResourcesAPI) ListAll(ctx context.Context, start PageRequest) ([]Resource, error)
ListAll walks resources.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*ResourcesAPI) ListAncestors ¶
ListAncestors issues GET /api/v1/resources/{resource_id}/ancestors.
func (*ResourcesAPI) ListChildren ¶
ListChildren issues GET /api/v1/resources/{resource_id}/children.
func (*ResourcesAPI) Update ¶
func (a *ResourcesAPI) Update(ctx context.Context, resourceID uuid.UUID, body UpdateResourceRequest) (Resource, error)
Update issues PUT /api/v1/resources/{resource_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type RetryEvent ¶
type RetryEvent struct {
Operation string
// Attempt is the attempt that just failed.
Attempt int
// Delay is the wait about to be taken, after jitter and any Retry-After.
Delay time.Duration
// Reason is a redacted failure description. Never carries a token, because
// NetworkError.Error() is redacted at construction (D-04/CR-04).
Reason string
}
RetryEvent is emitted before each §16 retry wait.
§16.5 requires this: a retried-then-succeeded operation is otherwise invisible — the caller sees a slow success and no signal that the server is failing. That silence is the standing objection to automatic retry.
type RetryPolicy ¶
type RetryPolicy struct {
// BackoffMultiplier Multiplier for exponential backoff.
BackoffMultiplier float64 `json:"backoff_multiplier"`
// InitialDelaySecs Initial delay between retries in seconds.
InitialDelaySecs int64 `json:"initial_delay_secs"`
// MaxRetries Maximum number of retry attempts.
MaxRetries int `json:"max_retries"`
}
RetryPolicy Retry policy for failed webhook deliveries.
type RevocationFeed ¶
type RevocationFeed = revocation.Feed
RevocationFeed is a poller for one deployment's session-revocation feed (CONTRACT.md §10.4 — AXIAM threats T-39 and T-143).
§10.2 records the gap it narrows: local verification proves a token was issued and has not expired, never that the session behind it still exists. A logout or a role removal therefore does not reach a token already in a caller's hands until it expires, up to fifteen minutes. A deployment that publishes GET /oauth2/revocations lets a guard close that to ONE POLL INTERVAL, for one cacheable fetch per interval rather than the round trip per request gRPC introspection costs.
It is NOT a control. It is off unless you attach one, it is never fetched on the request path once warm, and it NEVER FAILS CLOSED: an unreachable feed, a non-200, an unparseable body or an unknown alg all behave exactly as no feed at all — and specifically not as an empty list, which would assert that nothing has been revoked and is a guard silently honouring no revocations while appearing to honour them. Every §10.1 rule runs first and still decides; the feed can only ever turn an accept into a reject.
Safe for concurrent use, and meant to be shared: several guards built from one RevocationFeed poll once between them rather than once each.
func NewRevocationFeed ¶
func NewRevocationFeed(hc *http.Client, baseURL string) (*RevocationFeed, error)
NewRevocationFeed polls {baseURL}/oauth2/revocations on RevocationFeedDefaultPollInterval, through hc (nil means a default client). Attach it with JWKSVerifier.WithRevocationFeed.
A deployment that does not publish the feed is not an error here — that is discovered on the first poll, and behaves as no feed at all from then on.
type RevokeParams ¶
type RevokeParams struct {
// Token is the token to revoke.
Token Sensitive
// TokenTypeHint is an optional RFC 7009 token_type_hint.
TokenTypeHint string
// TenantID is the tenant UUID for the tenant_id query parameter (§12.3
// rule 4).
TenantID string
// Configuration is a pre-fetched discovery document. Fetched via
// OidcDiscover when nil.
Configuration *OidcConfiguration
}
RevokeParams are the arguments to Revoke (RFC 7009). Requires confidential-client credentials (§12.1 note 4).
type Role ¶
type Role struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IsGlobal Global roles grant permissions across all resources.
IsGlobal bool `json:"is_global"`
// Name carries the server's name field.
Name string `json:"name"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Role is the Role schema from the server's OpenAPI document.
type RoleAssignment ¶
type RoleAssignment struct {
// ResourceID `None` means the role was assigned globally (no resource scope).
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// Role carries the server's role field.
Role Role `json:"role"`
// TenantScope The tenants this assignment reaches. See [`TenantScope`].
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
}
RoleAssignment A role together with its assignment context (the resource it is scoped to).
type RoleGroupAssignment ¶
type RoleGroupAssignment struct {
// Group The assigned group.
Group Group `json:"group"`
// ResourceID `None` means the role was assigned globally (no resource scope).
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// TenantScope The tenants this assignment reaches, or omitted for "wherever the role
// does". Shown next to the assignment so an operator can tell a
// deliberately narrowed grant from an organization-wide one.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
}
RoleGroupAssignment A group together with the resource scope of its assignment of this role.
type RoleServiceAccountAssignment ¶
type RoleServiceAccountAssignment struct {
// ResourceID `None` means the role was assigned globally (no resource scope).
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// ServiceAccount The assigned service account. Carries no secret — the client secret
// is returned once, at creation, and never again.
ServiceAccount ServiceAccountResponse `json:"service_account"`
// TenantScope The tenants this assignment reaches, or omitted for "wherever the role
// does". Shown next to the assignment so an operator can tell a
// deliberately narrowed grant from an organization-wide one.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
}
RoleServiceAccountAssignment A service account together with the resource scope of its assignment.
type RoleSpec ¶
type RoleSpec struct {
// Key is the manifest-local identifier users and groups refer to.
Key string
// Name is the role's name — its natural key within the tenant.
Name string
// Description is human-readable. The server requires one.
Description string
// IsGlobal says whether the role applies tenant-wide rather than to a
// resource subtree.
IsGlobal bool
// Grants are the permissions this role grants.
Grants []GrantSpec
}
RoleSpec is a role and the permissions granted to it.
type RoleUserAssignment ¶
type RoleUserAssignment struct {
// ResourceID `None` means the role was assigned globally (no resource scope).
ResourceID *uuid.UUID `json:"resource_id,omitempty"`
// TenantScope The tenants this assignment reaches, or omitted for "wherever the role
// does". Shown next to the assignment so an operator can tell a
// deliberately narrowed grant from an organization-wide one.
TenantScope []uuid.UUID `json:"tenant_scope,omitempty"`
// User The assigned user.
User UserResponse `json:"user"`
}
RoleUserAssignment A user together with the resource scope of their assignment of this role.
type RolesAPI ¶
type RolesAPI struct {
// contains filtered or unexported fields
}
RolesAPI is the roles namespace handle.
Roles, their permission sets, and their assignment to users and groups.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*RolesAPI) AssignToGroup ¶
func (a *RolesAPI) AssignToGroup(ctx context.Context, roleID uuid.UUID, body AssignRoleToGroupRequest) error
AssignToGroup issues POST /api/v1/roles/{role_id}/groups.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) AssignToServiceAccount ¶
func (a *RolesAPI) AssignToServiceAccount(ctx context.Context, roleID uuid.UUID, body AssignRoleToServiceAccountRequest) error
AssignToServiceAccount issues POST /api/v1/roles/{role_id}/service-accounts.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) AssignToUser ¶
func (a *RolesAPI) AssignToUser(ctx context.Context, roleID uuid.UUID, body AssignRoleToUserRequest) error
AssignToUser issues POST /api/v1/roles/{role_id}/users.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) Create ¶
Create issues POST /api/v1/roles.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) Delete ¶
Delete issues DELETE /api/v1/roles/{role_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) GrantPermission ¶
func (a *RolesAPI) GrantPermission(ctx context.Context, roleID uuid.UUID, body GrantPermissionRequest) error
GrantPermission issues POST /api/v1/roles/{role_id}/permissions.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) ListAll ¶
ListAll walks roles.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*RolesAPI) ListGroups ¶
ListGroups issues GET /api/v1/roles/{role_id}/groups.
func (*RolesAPI) ListPermissions ¶
func (a *RolesAPI) ListPermissions(ctx context.Context, roleID uuid.UUID) ([]ResolvedPermissionGrant, error)
ListPermissions issues GET /api/v1/roles/{role_id}/permissions.
func (*RolesAPI) ListServiceAccounts ¶
func (a *RolesAPI) ListServiceAccounts(ctx context.Context, roleID uuid.UUID) ([]RoleServiceAccountAssignment, error)
ListServiceAccounts issues GET /api/v1/roles/{role_id}/service-accounts.
func (*RolesAPI) RevokePermission ¶
func (a *RolesAPI) RevokePermission(ctx context.Context, roleID uuid.UUID, permissionID uuid.UUID) error
RevokePermission issues DELETE /api/v1/roles/{role_id}/permissions/{permission_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) UnassignFromGroup ¶
func (a *RolesAPI) UnassignFromGroup(ctx context.Context, roleID uuid.UUID, groupID uuid.UUID, resourceID string) error
UnassignFromGroup issues DELETE /api/v1/roles/{role_id}/groups/{group_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) UnassignFromServiceAccount ¶
func (a *RolesAPI) UnassignFromServiceAccount(ctx context.Context, roleID uuid.UUID, serviceAccountID uuid.UUID, resourceID string) error
UnassignFromServiceAccount issues DELETE /api/v1/roles/{role_id}/service-accounts/{service_account_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*RolesAPI) UnassignFromUser ¶
func (a *RolesAPI) UnassignFromUser(ctx context.Context, roleID uuid.UUID, userID uuid.UUID, resourceID string) error
UnassignFromUser issues DELETE /api/v1/roles/{role_id}/users/{user_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type RotateSecretResponse ¶
type RotateSecretResponse struct {
// ClientSecret carries the server's client_secret field.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ClientSecret Sensitive `json:"client_secret"`
}
RotateSecretResponse Response for secret rotation.
type RptPermission ¶
type RptPermission struct {
// ResourceID is the resource the engine allowed.
ResourceID string
// ResourceScopes are the scopes it allowed on that resource.
ResourceScopes []string
// Exp is the absolute expiry, seconds since the epoch.
Exp int64
}
RptPermission is one entry of an RPT's `permissions` claim (§20.1).
A RECORD OF A DECISION ALREADY MADE, NOT A LIVE AUTHORIZATION ANSWER (§20.2 rule 7). These are the pairs the engine allowed when the RPT was minted; a grant revoked afterwards does not empty a live RPT. Do not cache them beyond the token's own expiry — which is why that expiry is short.
type SCIMTokenResponse ¶
type SCIMTokenResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// CreatedBy carries the server's created_by field.
CreatedBy uuid.UUID `json:"created_by"`
// ExpiresAt carries the server's expires_at field.
ExpiresAt string `json:"expires_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// LastUsedAt carries the server's last_used_at field.
LastUsedAt *string `json:"last_used_at,omitempty"`
// Name carries the server's name field.
Name string `json:"name"`
// RevokedAt carries the server's revoked_at field.
RevokedAt *string `json:"revoked_at,omitempty"`
// Status carries the server's status field.
Status SCIMTokenStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UserID carries the server's user_id field.
UserID uuid.UUID `json:"user_id"`
}
SCIMTokenResponse Metadata only. The handle is never in a list response — it exists in plaintext exactly once, in [`CreateScimTokenResponse`].
type SCIMTokenStatus ¶
type SCIMTokenStatus string
SCIMTokenStatus Why a token is or is not currently usable — for display only. The authentication path never surfaces this distinction on the wire.
const ( SCIMTokenStatusActive SCIMTokenStatus = "active" SCIMTokenStatusExpired SCIMTokenStatus = "expired" SCIMTokenStatusRevoked SCIMTokenStatus = "revoked" )
The SCIMTokenStatus values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type SCIMTokensAPI ¶
type SCIMTokensAPI struct {
// contains filtered or unexported fields
}
SCIMTokensAPI is the scim_tokens namespace handle.
Bearer tokens for the SCIM 2.0 provisioning endpoint.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*SCIMTokensAPI) Create ¶
func (a *SCIMTokensAPI) Create(ctx context.Context, body CreateSCIMTokenRequest) (CreateSCIMTokenResponse, error)
Create issues POST /api/v1/scim-tokens.
Returns secret material, once. provisioning_token is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*SCIMTokensAPI) List ¶
func (a *SCIMTokensAPI) List(ctx context.Context) ([]SCIMTokenResponse, error)
List issues GET /api/v1/scim-tokens.
type SMTPConfig ¶
type SMTPConfig struct {
// Host carries the server's host field.
Host string `json:"host"`
// Port carries the server's port field.
Port int `json:"port"`
// Starttls Use STARTTLS (true) or implicit TLS (false).
Starttls bool `json:"starttls"`
// Username carries the server's username field.
Username string `json:"username"`
}
SMTPConfig SMTP-specific configuration. `password` is write-only (D-01): `#[serde(skip_serializing)]` means it is never emitted in a GET/serialized response. On the write path (D-02), `#[serde(default)]` lets a caller omit the field entirely (deserializing to `""`); an empty string is the sentinel for "no new secret supplied — preserve whatever is already stored" (see `SurrealEmailConfigRepository:: set_org_config`). A non-empty value is a real secret to encrypt+replace.
type Scope ¶
type Scope struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description string `json:"description"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// ResourceID The resource this scope belongs to.
ResourceID uuid.UUID `json:"resource_id"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Scope is the Scope schema from the server's OpenAPI document.
type ScopeSpec ¶
type ScopeSpec struct {
// Key is the manifest-local identifier a role's grants refer to.
Key string
// Name is the scope's name — its natural key within its resource.
Name string
// Description is human-readable. The server requires one.
Description string
}
ScopeSpec is a scope, always beneath the resource that declares it.
type ScopesAPI ¶
type ScopesAPI struct {
// contains filtered or unexported fields
}
ScopesAPI is the scopes namespace handle.
Sub-resource granularity, always addressed under their resource.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*ScopesAPI) Create ¶
func (a *ScopesAPI) Create(ctx context.Context, resourceID uuid.UUID, body CreateScopeRequest) (Scope, error)
Create issues POST /api/v1/resources/{resource_id}/scopes.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ScopesAPI) Delete ¶
Delete issues DELETE /api/v1/resources/{resource_id}/scopes/{scope_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ScopesAPI) Get ¶
func (a *ScopesAPI) Get(ctx context.Context, resourceID uuid.UUID, scopeID uuid.UUID) (Scope, error)
Get issues GET /api/v1/resources/{resource_id}/scopes/{scope_id}.
func (*ScopesAPI) Update ¶
func (a *ScopesAPI) Update(ctx context.Context, resourceID uuid.UUID, scopeID uuid.UUID, body UpdateScopeRequest) (Scope, error)
Update issues PUT /api/v1/resources/{resource_id}/scopes/{scope_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type SecuritySettings ¶
type SecuritySettings struct {
// Certificate carries the server's certificate field.
Certificate CertificatePolicy `json:"certificate"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Email carries the server's email field.
Email EmailVerificationPolicy `json:"email"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Lockout carries the server's lockout field.
Lockout LockoutPolicy `json:"lockout"`
// MFA carries the server's mfa field.
MFA MFAPolicy `json:"mfa"`
// Notification carries the server's notification field.
Notification NotificationPolicy `json:"notification"`
// OIDC carries the server's oidc field.
OIDC OIDCPolicy `json:"oidc"`
// Opaque carries the server's opaque field.
Opaque OpaquePolicy `json:"opaque"`
// Password carries the server's password field.
Password PasswordPolicy `json:"password"`
// Privacy carries the server's privacy field.
Privacy PrivacyPolicy `json:"privacy"`
// Scope carries the server's scope field.
Scope SettingsScope `json:"scope"`
// ScopeID carries the server's scope_id field.
ScopeID uuid.UUID `json:"scope_id"`
// Token carries the server's token field.
Token TokenPolicy `json:"token"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
// Webauthn carries the server's webauthn field.
Webauthn WebauthnPolicy `json:"webauthn"`
}
SecuritySettings Fully resolved security settings (all fields present).
type Sensitive ¶
type Sensitive string
Sensitive wraps a token-carrying string so it can never accidentally leak via fmt verbs, Go-syntax representation, or JSON encoding (CONTRACT.md §7, D-08). All token-carrying fields (access token, refresh token, MFA challenge token, AMQP signing key) MUST use this type.
The raw value is reachable two ways: Expose, which is the greppable one to use and to audit, and a plain string(...) conversion, which Go permits on any defined string type and which this type cannot prevent. The protection here is against ACCIDENTAL disclosure — a %v in a log line, a struct marshalled into a request, a panic dump — not against a caller who means to read the value.
Callers do sometimes mean to. CONTRACT.md §25.3 hands back a TOTP URI that has to reach a QR renderer, and §27.5 rule 3 hands back one-time secrets — a certificate's private key, a SCIM provisioning token, a service account's client secret — that are returned by exactly one call and never again, so the caller must store them or lose them.
func (Sensitive) Expose ¶
Expose returns the raw wrapped value.
Use it at exactly the point the secret is needed — written to a file, handed to a QR renderer, put on a socket — and never in between. Its whole value is that "this is where a secret becomes a plain string" is one greppable call rather than an ordinary-looking conversion, so an audit can find every such point by searching for this name.
Never pass the result to a log, fmt, or JSON sink: doing so throws away the redaction this type exists to provide.
func (Sensitive) Format ¶
Format implements fmt.Formatter, closing the fmt-verb leak path (%v/%+v/%s/%q/width/precision) that a bare String() method does not fully cover — this is the CR-04 leak class this type exists to prevent.
func (Sensitive) GoString ¶
GoString implements fmt.GoStringer, covering %#v (Go-syntax representation), which bypasses String()/Format() entirely if not implemented.
func (Sensitive) MarshalJSON ¶
MarshalJSON implements json.Marshaler so any struct embedding a Sensitive field serializes the redacted placeholder rather than the raw value.
type ServiceAccountCreatedResponse ¶
type ServiceAccountCreatedResponse struct {
// ClientID carries the server's client_id field.
ClientID string `json:"client_id"`
// ClientSecret carries the server's client_secret field.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ClientSecret Sensitive `json:"client_secret"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// Status carries the server's status field.
Status UserStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
ServiceAccountCreatedResponse Response for service account creation — includes the one-time plaintext secret.
type ServiceAccountResponse ¶
type ServiceAccountResponse struct {
// ClientID carries the server's client_id field.
ClientID string `json:"client_id"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Name carries the server's name field.
Name string `json:"name"`
// Status carries the server's status field.
Status UserStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
ServiceAccountResponse Public-safe service account representation.
type ServiceAccountsAPI ¶
type ServiceAccountsAPI struct {
// contains filtered or unexported fields
}
ServiceAccountsAPI is the service_accounts namespace handle.
Machine identities, their secrets, and the certificate a device-bound one authenticates with.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*ServiceAccountsAPI) BindCertificate ¶
func (a *ServiceAccountsAPI) BindCertificate(ctx context.Context, saID uuid.UUID, body BindCertificate) error
BindCertificate issues POST /api/v1/service-accounts/{sa_id}/bind-certificate.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ServiceAccountsAPI) Create ¶
func (a *ServiceAccountsAPI) Create(ctx context.Context, body CreateServiceAccountRequest) (ServiceAccountCreatedResponse, error)
Create issues POST /api/v1/service-accounts.
Returns secret material, once. client_secret is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ServiceAccountsAPI) Delete ¶
Delete issues DELETE /api/v1/service-accounts/{sa_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ServiceAccountsAPI) Get ¶
func (a *ServiceAccountsAPI) Get(ctx context.Context, saID uuid.UUID) (ServiceAccountResponse, error)
Get issues GET /api/v1/service-accounts/{sa_id}.
func (*ServiceAccountsAPI) List ¶
func (a *ServiceAccountsAPI) List(ctx context.Context, page PageRequest) (Page[ServiceAccountResponse], error)
List issues GET /api/v1/service-accounts.
func (*ServiceAccountsAPI) ListAll ¶
func (a *ServiceAccountsAPI) ListAll(ctx context.Context, start PageRequest) ([]ServiceAccountResponse, error)
ListAll walks service_accounts.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*ServiceAccountsAPI) ListGroups ¶
func (a *ServiceAccountsAPI) ListGroups(ctx context.Context, serviceAccountID uuid.UUID) ([]Group, error)
ListGroups issues GET /api/v1/service-accounts/{service_account_id}/groups.
func (*ServiceAccountsAPI) ListRoles ¶
func (a *ServiceAccountsAPI) ListRoles(ctx context.Context, serviceAccountID uuid.UUID) ([]RoleAssignment, error)
ListRoles issues GET /api/v1/service-accounts/{service_account_id}/roles.
func (*ServiceAccountsAPI) RotateSecret ¶
func (a *ServiceAccountsAPI) RotateSecret(ctx context.Context, saID uuid.UUID) (RotateSecretResponse, error)
RotateSecret issues POST /api/v1/service-accounts/{sa_id}/rotate-secret.
Returns secret material, once. client_secret is returned by this call and by no other; no later Get will return it again, and the Get projection has no field where it was. Discarding the result destroys the credential (§27.5 rule 3).
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*ServiceAccountsAPI) Update ¶
func (a *ServiceAccountsAPI) Update(ctx context.Context, saID uuid.UUID, body UpdateServiceAccount) (ServiceAccountResponse, error)
Update issues PUT /api/v1/service-accounts/{sa_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type SessionResponse ¶
type SessionResponse struct {
// Amr RFC 8176 method references for that authentication.
Amr []string `json:"amr"`
// AuthenticatedAt X7.2 — when the end user actually authenticated, which is not
// `created_at` on a session produced by refresh rotation.
AuthenticatedAt string `json:"authenticated_at"`
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// ExpiresAt carries the server's expires_at field.
ExpiresAt string `json:"expires_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IPAddress carries the server's ip_address field.
IPAddress *string `json:"ip_address,omitempty"`
// RefreshReplayAt T-254 — when a refresh token of this session was last presented after
// it had already been rotated. `None` if that has never happened.
RefreshReplayAt *string `json:"refresh_replay_at,omitempty"`
// RefreshReplayGraceAccepted T-254 — replays accepted under the FAPI 2.0 §5.3.2.1-9 grace window.
// Only ever non-zero for a client registered `profile: fapi2`.
RefreshReplayGraceAccepted int `json:"refresh_replay_grace_accepted"`
// RefreshReplayRefused T-254 — replays refused because there was no window to accept them
// in. Nothing a conformant client does.
RefreshReplayRefused int `json:"refresh_replay_refused"`
// RefreshReplayVerdict T-254 — the badge: `none`, `fapi_grace_retry` or `refused`. Derived
// from the two counters below rather than stored, so it cannot disagree
// with them. A refusal outranks an accepted grace retry however the
// counts compare.
RefreshReplayVerdict string `json:"refresh_replay_verdict"`
// UserAgent carries the server's user_agent field.
UserAgent *string `json:"user_agent,omitempty"`
}
SessionResponse One of a user's sessions, as an administrator sees it.
type SetMTLSTrustAnchor ¶
type SetMTLSTrustAnchor struct {
// Enabled Whether this CA should be trusted for client-certificate
// authentication.
Enabled bool `json:"enabled"`
}
SetMTLSTrustAnchor Body for `PUT .../ca-certificates/{id}/mtls-trust-anchor`.
func NewSetMTLSTrustAnchor ¶
func NewSetMTLSTrustAnchor(enabled bool) SetMTLSTrustAnchor
NewSetMTLSTrustAnchor builds a SetMTLSTrustAnchor with every field the server requires.
This body REPLACES rather than patches (§27.4 rule 5), so what you do not carry over from a prior read is not preserved — it is overwritten. Taking every required field as an argument is what makes forgetting one a compile error rather than a silent zero value on the wire.
type SetOrgEmailConfig ¶
type SetOrgEmailConfig struct {
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// FromEmail carries the server's from_email field.
FromEmail string `json:"from_email"`
// FromName carries the server's from_name field.
FromName string `json:"from_name"`
// Provider carries the server's provider field.
Provider ProviderConfig `json:"provider"`
// ReplyTo carries the server's reply_to field.
ReplyTo *string `json:"reply_to,omitempty"`
}
SetOrgEmailConfig Input for setting organization-level email config.
func NewSetOrgEmailConfig ¶
func NewSetOrgEmailConfig(enabled bool, fromEmail string, fromName string, provider ProviderConfig) SetOrgEmailConfig
NewSetOrgEmailConfig builds a SetOrgEmailConfig with every field the server requires.
This body REPLACES rather than patches (§27.4 rule 5), so what you do not carry over from a prior read is not preserved — it is overwritten. Taking every required field as an argument is what makes forgetting one a compile error rather than a silent zero value on the wire.
The optional fields (ReplyTo) stay settable on the returned value, and are equally overwritten when omitted — read the current state first and carry them across.
type SetOrgSettings ¶
type SetOrgSettings struct {
// AccessTokenLifetimeSecs carries the server's access_token_lifetime_secs field.
AccessTokenLifetimeSecs int64 `json:"access_token_lifetime_secs"`
// AdminNotificationsEnabled carries the server's admin_notifications_enabled field.
AdminNotificationsEnabled bool `json:"admin_notifications_enabled"`
// DefaultCertValidityDays carries the server's default_cert_validity_days field.
DefaultCertValidityDays int `json:"default_cert_validity_days"`
// DefaultLocale carries the server's default_locale field.
DefaultLocale *string `json:"default_locale,omitempty"`
// DeletionGracePeriodDays carries the server's deletion_grace_period_days field.
DeletionGracePeriodDays *int `json:"deletion_grace_period_days,omitempty"`
// EmailVerificationGracePeriodHours carries the server's email_verification_grace_period_hours field.
EmailVerificationGracePeriodHours int `json:"email_verification_grace_period_hours"`
// EmailVerificationRequired carries the server's email_verification_required field.
EmailVerificationRequired bool `json:"email_verification_required"`
// HibpCheckEnabled carries the server's hibp_check_enabled field.
HibpCheckEnabled bool `json:"hibp_check_enabled"`
// LockoutBackoffMultiplier carries the server's lockout_backoff_multiplier field.
LockoutBackoffMultiplier float64 `json:"lockout_backoff_multiplier"`
// LockoutDurationSecs carries the server's lockout_duration_secs field.
LockoutDurationSecs int64 `json:"lockout_duration_secs"`
// MaxCertValidityDays carries the server's max_cert_validity_days field.
MaxCertValidityDays int `json:"max_cert_validity_days"`
// MaxFailedLoginAttempts carries the server's max_failed_login_attempts field.
MaxFailedLoginAttempts int `json:"max_failed_login_attempts"`
// MaxLockoutDurationSecs carries the server's max_lockout_duration_secs field.
MaxLockoutDurationSecs int64 `json:"max_lockout_duration_secs"`
// MFAChallengeLifetimeSecs carries the server's mfa_challenge_lifetime_secs field.
MFAChallengeLifetimeSecs int64 `json:"mfa_challenge_lifetime_secs"`
// MFAEnforced carries the server's mfa_enforced field.
MFAEnforced bool `json:"mfa_enforced"`
// MinLength carries the server's min_length field.
MinLength int `json:"min_length"`
// OpaqueKsf carries the server's opaque_ksf field.
OpaqueKsf *string `json:"opaque_ksf,omitempty"`
// OpaqueMode carries the server's opaque_mode field.
OpaqueMode *string `json:"opaque_mode,omitempty"`
// OpaqueSuite carries the server's opaque_suite field.
OpaqueSuite *string `json:"opaque_suite,omitempty"`
// PasswordHistoryCount carries the server's password_history_count field.
PasswordHistoryCount int `json:"password_history_count"`
// RefreshTokenLifetimeSecs carries the server's refresh_token_lifetime_secs field.
RefreshTokenLifetimeSecs int64 `json:"refresh_token_lifetime_secs"`
// RequireDigits carries the server's require_digits field.
RequireDigits bool `json:"require_digits"`
// RequireLowercase carries the server's require_lowercase field.
RequireLowercase bool `json:"require_lowercase"`
// RequireSymbols carries the server's require_symbols field.
RequireSymbols bool `json:"require_symbols"`
// RequireUppercase carries the server's require_uppercase field.
RequireUppercase bool `json:"require_uppercase"`
// SensitiveScopesEnabled carries the server's sensitive_scopes_enabled field.
SensitiveScopesEnabled *bool `json:"sensitive_scopes_enabled,omitempty"`
// WebauthnUserVerification carries the server's webauthn_user_verification field.
WebauthnUserVerification *string `json:"webauthn_user_verification,omitempty"`
}
SetOrgSettings Input for setting organization-level security settings.
func NewSetOrgSettings ¶
func NewSetOrgSettings(accessTokenLifetimeSecs int64, adminNotificationsEnabled bool, defaultCertValidityDays int, emailVerificationGracePeriodHours int, emailVerificationRequired bool, hibpCheckEnabled bool, lockoutBackoffMultiplier float64, lockoutDurationSecs int64, maxCertValidityDays int, maxFailedLoginAttempts int, maxLockoutDurationSecs int64, mfaChallengeLifetimeSecs int64, mfaEnforced bool, minLength int, passwordHistoryCount int, refreshTokenLifetimeSecs int64, requireDigits bool, requireLowercase bool, requireSymbols bool, requireUppercase bool) SetOrgSettings
NewSetOrgSettings builds a SetOrgSettings with every field the server requires.
This body REPLACES rather than patches (§27.4 rule 5), so what you do not carry over from a prior read is not preserved — it is overwritten. Taking every required field as an argument is what makes forgetting one a compile error rather than a silent zero value on the wire.
The optional fields (DefaultLocale, DeletionGracePeriodDays, OpaqueKsf, OpaqueMode, OpaqueSuite, SensitiveScopesEnabled, WebauthnUserVerification) stay settable on the returned value, and are equally overwritten when omitted — read the current state first and carry them across.
type SettingsAPI ¶
type SettingsAPI struct {
// contains filtered or unexported fields
}
SettingsAPI is the settings namespace handle.
Effective settings, and the organization/tenant layers they resolve from.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*SettingsAPI) DeleteTenantOverride ¶
func (a *SettingsAPI) DeleteTenantOverride(ctx context.Context) error
DeleteTenantOverride issues DELETE /api/v1/tenants/{tenant_id}/settings.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*SettingsAPI) ForTenant ¶
func (a *SettingsAPI) ForTenant(tenantID uuid.UUID) *SettingsAPI
ForTenant addresses a different tenant than the client's own (§27.4 rule 3).
Returns a new handle; the original is unchanged.
func (*SettingsAPI) GetEffective ¶
func (a *SettingsAPI) GetEffective(ctx context.Context) (SecuritySettings, error)
GetEffective issues GET /api/v1/settings.
func (*SettingsAPI) GetOrg ¶
func (a *SettingsAPI) GetOrg(ctx context.Context) (SecuritySettings, error)
GetOrg issues GET /api/v1/organizations/{org_id}/settings.
func (*SettingsAPI) GetTenantOverride ¶
func (a *SettingsAPI) GetTenantOverride(ctx context.Context) (TenantSettingsOverride, error)
GetTenantOverride issues GET /api/v1/tenants/{tenant_id}/settings.
func (*SettingsAPI) InOrg ¶
func (a *SettingsAPI) InOrg(orgID uuid.UUID) *SettingsAPI
InOrg addresses a different organization than the client's own.
§27.4 rule 3: the client's organization is the default, and a platform-admin token legitimately overrides it. Returns a new handle; the original is unchanged.
func (*SettingsAPI) SetEffective ¶
func (a *SettingsAPI) SetEffective(ctx context.Context, body TenantSettingsOverride) (SecuritySettings, error)
SetEffective issues PUT /api/v1/settings.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*SettingsAPI) SetOrg ¶
func (a *SettingsAPI) SetOrg(ctx context.Context, body SetOrgSettings) (SecuritySettings, error)
SetOrg issues PUT /api/v1/organizations/{org_id}/settings.
This is a REPLACEMENT, not a patch (§27.4 rule 5). Every field of the body is required, and what you do not carry over from a prior read is not preserved — it is overwritten. Read first, change the field you mean, send the whole thing back.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*SettingsAPI) SetTenantOverride ¶
func (a *SettingsAPI) SetTenantOverride(ctx context.Context, body TenantSettingsOverride) (TenantSettingsOverride, error)
SetTenantOverride issues PUT /api/v1/tenants/{tenant_id}/settings.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type SettingsScope ¶
type SettingsScope string
SettingsScope Whether a settings row belongs to an organization or a tenant.
const ( SettingsScopeOrg SettingsScope = "Org" SettingsScopeTenant SettingsScope = "Tenant" )
The SettingsScope values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type SignAuditBatchRequest ¶
type SignAuditBatchRequest struct {
// EntryIDs carries the server's entry_ids field.
EntryIDs []uuid.UUID `json:"entry_ids"`
}
SignAuditBatchRequest Request body for signing an audit batch.
type SignIntermediateCSRRequest ¶
type SignIntermediateCSRRequest struct {
// CSRPEM PEM-encoded PKCS#10 certificate signing request.
CSRPEM string `json:"csr_pem"`
// ParentCAID The organization CA that signs it.
ParentCAID uuid.UUID `json:"parent_ca_id"`
// ValidityDays Validity duration in days, capped to the parent's own expiry.
ValidityDays int `json:"validity_days"`
}
SignIntermediateCSRRequest Body of `POST .../tenants/{tenant_id}/signing-cas/sign-csr`. Deliberately carries no key algorithm: it is the CSR's, read out of the request, because a caller who could state it separately could state one the key does not have.
type SignedAuditBatch ¶
type SignedAuditBatch struct {
// BatchID carries the server's batch_id field.
BatchID uuid.UUID `json:"batch_id"`
// EntryIDs carries the server's entry_ids field.
EntryIDs []uuid.UUID `json:"entry_ids"`
// SignatureArmored ASCII-armored PGP signed message containing the audit batch payload.
SignatureArmored string `json:"signature_armored"`
// SignedAt carries the server's signed_at field.
SignedAt string `json:"signed_at"`
// SigningKeyID carries the server's signing_key_id field.
SigningKeyID uuid.UUID `json:"signing_key_id"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
}
SignedAuditBatch A signed batch of audit log entries.
type SsoCompleteHandoffParams ¶
type SsoCompleteHandoffParams struct {
// Code is the single-use code read from the HandoffQueryParam query
// parameter on the SPA's callback URL. Valid for HandoffCodeTTL and
// redeemable ONCE.
Code string
}
SsoCompleteHandoffParams are the arguments to SsoCompleteHandoff (`POST /api/v1/auth/federation/handoff`).
type SsoCompleteOauth2Params ¶
type SsoCompleteOauth2Params struct {
// State is the `state` the provider redirected back with — the one
// SsoStartOauth2 returned, unmodified.
State string
// Code is the authorization code the provider redirected back with.
Code string
}
SsoCompleteOauth2Params are the arguments to SsoCompleteOauth2 (`POST /api/v1/auth/federation/oauth2/callback`).
type SsoCompleteParams ¶
type SsoCompleteParams struct {
// State is the `state` value the IdP redirected back with — must be the
// one SsoStart returned.
State string
// Code is the authorization code the IdP redirected back with.
Code string
}
SsoCompleteParams are the arguments to SsoComplete (`POST /api/v1/auth/federation/oidc/callback`).
type SsoCompleteResult ¶
type SsoCompleteResult struct {
// UserID is the provisioned/linked user's UUID.
UserID string
// SessionID is the established session's UUID.
SessionID string
// ExpiresIn is the session/access-token lifetime in seconds.
ExpiresIn int64
// RedirectURI is the post-login destination that was stored during
// SsoStart.
RedirectURI string
}
SsoCompleteResult is the result of SsoComplete (wire schema SsoLoginSuccessResponse).
It carries NO token material — the session arrives as Set-Cookie, so the §4 cookie jar (already owned by every *Client) is what actually captures it (§12.1 note 6).
type SsoProvidersParams ¶
type SsoProvidersParams struct {
// OrgID is the organization UUID. Alternative to OrgSlug.
OrgID string
// OrgSlug is the organization slug, as typed on a login page.
OrgSlug string
// TenantID is the tenant UUID. Alternative to TenantSlug.
TenantID string
// TenantSlug is the tenant slug. Omitted or blank means the
// organization's own scope.
TenantSlug string
}
SsoProvidersParams are the arguments to SsoProviders (`GET /api/v1/auth/federation/providers`).
Every field is optional and all four travel as QUERY parameters — this is a GET and sends no body (§12.1). Unset forms fall back to the Client's own configuration (§5.1); when neither these fields nor the Client supply a workspace the request is still sent, and still answers 200 with an empty list.
type SsoStartOauth2Params ¶
type SsoStartOauth2Params struct {
// FederationConfigID is the UUID of the federation configuration, from
// FederationProvider.ID.
FederationConfigID string
// RedirectURI is the SPA callback route. Sent to the provider verbatim,
// so it must match what is registered there byte for byte.
RedirectURI string
// TenantID is the tenant UUID; defaults to the Client's configuration.
TenantID string
// TenantSlug is the tenant slug. Alternative to TenantID.
TenantSlug string
// OrgID is the organization UUID; defaults to the Client's configuration.
OrgID string
// OrgSlug is the organization slug. Alternative to OrgID.
OrgSlug string
}
SsoStartOauth2Params are the arguments to SsoStartOauth2 (`POST /api/v1/auth/federation/oauth2/start`).
Deliberately identical in shape to SsoStartParams, because the wire schemas are: OAuth2StartRequest and OidcStartRequest differ in name only. There is NO PKCE field, and there must not be — the verifier is generated and held server-side (§12.1 note 11).
type SsoStartParams ¶
type SsoStartParams struct {
// FederationConfigID is the UUID of the server-side federation
// configuration identifying the upstream IdP.
FederationConfigID string
// RedirectURI is the post-login destination, stored server-side and
// echoed back by SsoComplete.
RedirectURI string
// TenantID is the tenant UUID. Defaults to the Client's own tenant when
// empty (this SDK always constructs a Client with a tenant slug, so the
// default tenant form is TenantSlug — see TenantSlug below).
TenantID string
// TenantSlug is the tenant slug — the tenant form used by default,
// since NewClient always requires one.
TenantSlug string
// OrgID is the organization UUID. Defaults to the Client's configured
// organization (WithOrgID) when empty.
OrgID string
// OrgSlug is the organization slug. Defaults to the Client's configured
// organization (WithOrgSlug) when empty.
OrgSlug string
}
SsoStartParams are the arguments to SsoStart (`POST /api/v1/auth/federation/oidc/start`).
One tenant form (TenantID or TenantSlug) and one org form (OrgID or OrgSlug) must be resolvable, from these fields or from the Client's own construction options (CONTRACT.md §5.1).
type SsoStartResult ¶
type SsoStartResult struct {
// AuthorizeURL is the upstream IdP authorization URL to redirect the
// browser to.
AuthorizeURL string
// State is the single-use CSRF state to round-trip back into SsoComplete
// unmodified.
State string
// ExpiresInSecs is the remaining TTL of the server-side state row, in
// seconds (600 = 10 min).
ExpiresInSecs int64
}
SsoStartResult is the result of SsoStart (wire schema OidcStartResponse).
There is deliberately no nonce: on the federation path the nonce never leaves the server (§12.1 note 7). Round-trip State into SsoComplete unmodified — the server stores it single-use with a 10-minute TTL and recovers the whole login context from it.
type Status ¶
type Status string
Status says what actually became of one planned step.
const ( // StatusCreated: the step ran and the thing now exists. StatusCreated Status = "created" // StatusUpdated: the step ran and the thing was updated. StatusUpdated Status = "updated" // StatusUnchanged: a no-op step; nothing was sent. StatusUnchanged Status = "unchanged" // StatusFailed: the step failed. Everything before it has already happened. StatusFailed Status = "failed" // StatusNotAttempted: never attempted, because an earlier step failed. StatusNotAttempted Status = "not-attempted" )
The Status values.
type StepOutcome ¶
type StepOutcome struct {
// Status is created, updated, unchanged, failed or not-attempted.
Status Status
// Message is the error the server or transport gave, on a failed step only.
Message string
}
StepOutcome is what actually happened to one planned step.
type Target ¶
type Target string
Target says which part of the manifest an action came from.
const ( TargetResource Target = "resource" TargetScope Target = "scope" TargetPermission Target = "permission" TargetRole Target = "role" TargetRoleGrant Target = "role-grant" TargetGroup Target = "group" TargetGroupRole Target = "group-role" TargetUser Target = "user" TargetUserRole Target = "user-role" TargetGroupMember Target = "group-member" )
The Target values, one per kind of thing the reconciler acts on.
type TelemetryEvent ¶
type TelemetryEvent interface {
// contains filtered or unexported methods
}
TelemetryEvent is a §19 event.
The interface is closed — isTelemetryEvent is unexported, so no package outside this one can add a variant. That is what makes the "no field can carry a secret" guarantee checkable rather than aspirational.
type TelemetryHook ¶
type TelemetryHook func(TelemetryEvent)
TelemetryHook is a caller-supplied sink.
It is invoked on the calling goroutine, so it must not block: §19.2 rule 4 makes buffering the caller's job so they can pick the policy. Every mature metrics library already buffers.
type Tenant ¶
type Tenant struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// Kind Whether this is an ordinary tenant or the organization's own scope.
// `#[serde(default)]` so every row written before organization scope
// existed reads back as [`TenantKind::Standard`], which is what it is.
Kind *TenantKind `json:"kind,omitempty"`
// Metadata Arbitrary key-value metadata.
Metadata any `json:"metadata"`
// Name Human-readable name.
Name string `json:"name"`
// OrganizationID The organization this tenant belongs to.
OrganizationID uuid.UUID `json:"organization_id"`
// Slug URL-safe unique identifier within the organization (e.g.,
// `production`).
Slug string `json:"slug"`
// Status Lifecycle status. New tenants default to [`TenantStatus::Active`].
Status TenantStatus `json:"status"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
}
Tenant A tenant is an isolated context within an organization. Each tenant has its own set of users, roles, permissions, resources, certificates, and configuration. Tenants can represent environments (dev/staging/prod) or separate business contexts.
type TenantKind ¶
type TenantKind string
TenantKind What a tenant *is*, as distinct from what state it is in. Reserved rather than inferred: an organization has exactly one tenant of kind [`Self::Organization`], enforced by a unique index rather than by convention. Deriving it from a magic slug or from "the oldest tenant" would make the organization scope something an operator could rename or delete by accident, and it is the scope the super-admin lives in.
const ( TenantKindStandard TenantKind = "standard" TenantKindOrganization TenantKind = "organization" )
The TenantKind values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type TenantSettingsOverride ¶
type TenantSettingsOverride struct {
// AccessTokenLifetimeSecs carries the server's access_token_lifetime_secs field.
AccessTokenLifetimeSecs *int64 `json:"access_token_lifetime_secs,omitempty"`
// AdminNotificationsEnabled carries the server's admin_notifications_enabled field.
AdminNotificationsEnabled *bool `json:"admin_notifications_enabled,omitempty"`
// DefaultCertValidityDays carries the server's default_cert_validity_days field.
DefaultCertValidityDays *int `json:"default_cert_validity_days,omitempty"`
// DefaultLocale The tenant's fallback UI language. Not ordered, therefore not validated
// against the baseline and never clamped — see [`OidcPolicy`].
DefaultLocale *string `json:"default_locale,omitempty"`
// DeletionGracePeriodDays carries the server's deletion_grace_period_days field.
DeletionGracePeriodDays *int `json:"deletion_grace_period_days,omitempty"`
// EmailVerificationGracePeriodHours carries the server's email_verification_grace_period_hours field.
EmailVerificationGracePeriodHours *int `json:"email_verification_grace_period_hours,omitempty"`
// EmailVerificationRequired carries the server's email_verification_required field.
EmailVerificationRequired *bool `json:"email_verification_required,omitempty"`
// HibpCheckEnabled carries the server's hibp_check_enabled field.
HibpCheckEnabled *bool `json:"hibp_check_enabled,omitempty"`
// LockoutBackoffMultiplier carries the server's lockout_backoff_multiplier field.
LockoutBackoffMultiplier *float64 `json:"lockout_backoff_multiplier,omitempty"`
// LockoutDurationSecs carries the server's lockout_duration_secs field.
LockoutDurationSecs *int64 `json:"lockout_duration_secs,omitempty"`
// MaxCertValidityDays carries the server's max_cert_validity_days field.
MaxCertValidityDays *int `json:"max_cert_validity_days,omitempty"`
// MaxFailedLoginAttempts carries the server's max_failed_login_attempts field.
MaxFailedLoginAttempts *int `json:"max_failed_login_attempts,omitempty"`
// MaxLockoutDurationSecs carries the server's max_lockout_duration_secs field.
MaxLockoutDurationSecs *int64 `json:"max_lockout_duration_secs,omitempty"`
// MFAChallengeLifetimeSecs carries the server's mfa_challenge_lifetime_secs field.
MFAChallengeLifetimeSecs *int64 `json:"mfa_challenge_lifetime_secs,omitempty"`
// MFAEnforced carries the server's mfa_enforced field.
MFAEnforced *bool `json:"mfa_enforced,omitempty"`
// MinLength carries the server's min_length field.
MinLength *int `json:"min_length,omitempty"`
// OpaqueKsf carries the server's opaque_ksf field.
OpaqueKsf *string `json:"opaque_ksf,omitempty"`
// OpaqueMode carries the server's opaque_mode field.
OpaqueMode *string `json:"opaque_mode,omitempty"`
// OpaqueSuite carries the server's opaque_suite field.
OpaqueSuite *string `json:"opaque_suite,omitempty"`
// PasswordHistoryCount carries the server's password_history_count field.
PasswordHistoryCount *int `json:"password_history_count,omitempty"`
// RefreshTokenLifetimeSecs carries the server's refresh_token_lifetime_secs field.
RefreshTokenLifetimeSecs *int64 `json:"refresh_token_lifetime_secs,omitempty"`
// RequireDigits carries the server's require_digits field.
RequireDigits *bool `json:"require_digits,omitempty"`
// RequireLowercase carries the server's require_lowercase field.
RequireLowercase *bool `json:"require_lowercase,omitempty"`
// RequireSymbols carries the server's require_symbols field.
RequireSymbols *bool `json:"require_symbols,omitempty"`
// RequireUppercase carries the server's require_uppercase field.
RequireUppercase *bool `json:"require_uppercase,omitempty"`
// SensitiveScopesEnabled carries the server's sensitive_scopes_enabled field.
SensitiveScopesEnabled *bool `json:"sensitive_scopes_enabled,omitempty"`
// WebauthnUserVerification carries the server's webauthn_user_verification field.
WebauthnUserVerification *string `json:"webauthn_user_verification,omitempty"`
}
TenantSettingsOverride Partial tenant overrides. `None` = inherit from org baseline.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type TenantStatus ¶
type TenantStatus string
TenantStatus Lifecycle status of a tenant. A `Suspended` tenant remains stored and its data isolated, but is treated as administratively disabled. New tenants are `Active` by default.
const ( TenantStatusActive TenantStatus = "Active" TenantStatusSuspended TenantStatus = "Suspended" )
The TenantStatus values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type TenantsAPI ¶
type TenantsAPI struct {
// contains filtered or unexported fields
}
TenantsAPI is the tenants namespace handle.
Tenants within an organization -- the isolation boundary every other namespace is scoped to.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*TenantsAPI) Create ¶
func (a *TenantsAPI) Create(ctx context.Context, body CreateTenantRequest) (Tenant, error)
Create issues POST /api/v1/organizations/{org_id}/tenants.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*TenantsAPI) Delete ¶
Delete issues DELETE /api/v1/organizations/{org_id}/tenants/{tenant_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*TenantsAPI) ExportAudit ¶
ExportAudit issues POST /api/v1/organizations/{org_id}/tenants/{tenant_id}/audit-export.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*TenantsAPI) InOrg ¶
func (a *TenantsAPI) InOrg(orgID uuid.UUID) *TenantsAPI
InOrg addresses a different organization than the client's own.
§27.4 rule 3: the client's organization is the default, and a platform-admin token legitimately overrides it. Returns a new handle; the original is unchanged.
func (*TenantsAPI) List ¶
func (a *TenantsAPI) List(ctx context.Context, page PageRequest) (Page[Tenant], error)
List issues GET /api/v1/organizations/{org_id}/tenants.
func (*TenantsAPI) ListAll ¶
func (a *TenantsAPI) ListAll(ctx context.Context, start PageRequest) ([]Tenant, error)
ListAll walks tenants.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*TenantsAPI) Update ¶
func (a *TenantsAPI) Update(ctx context.Context, tenantID uuid.UUID, body UpdateTenant) (Tenant, error)
Update issues PUT /api/v1/organizations/{org_id}/tenants/{tenant_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type TokenExchangeParams ¶
type TokenExchangeParams struct {
// SubjectToken is the token being exchanged (§15.5 secret). Required.
SubjectToken Sensitive
// SubjectTokenType names what kind of token SubjectToken is — one of the
// SubjectTokenType* constants. REQUIRED (§15.1).
//
// There is no default. Go cannot make a struct field mandatory at compile
// time, so leaving it empty fails CLIENT-SIDE with no wire call, the same
// way a missing client secret does — rather than sending a type you did
// not choose.
//
// Pass SubjectTokenTypeAccessToken for the same-domain exchange of §15.1,
// or SubjectTokenTypeJWT for a trusted external issuer's JWT (§15.7).
//
// The SDK never reads SubjectToken to decide this value (§15.7). Which
// kind of token you hold is something only you know; AXIAM refuses refresh
// and ID token types by name, and the SDK will not retry a refusal as a
// different type.
SubjectTokenType string
// ActorToken is the acting party, when this is a DELEGATION (§15.2
// rule 1).
//
// Its absence selects IMPERSONATION — a different operation with different
// risk. The SDK never fills this in for you.
ActorToken Sensitive
// Scopes are the scopes to request. Omitted from the body when empty.
Scopes []string
// Audience is the service the issued token is for.
Audience string
// Resource is the RFC 8707 synonym of Audience; the server refuses the
// pair when they disagree.
Resource string
// TenantID supplies the `tenant_id` query parameter.
TenantID string
// Configuration is a pre-fetched discovery document.
Configuration *OidcConfiguration
}
TokenExchangeParams are the arguments to Client.TokenExchange (§15.1).
A struct rather than positional arguments because four optional strings in positional order is a bug waiting to be written (§15.1).
type TokenExchangeTrustRequest ¶
type TokenExchangeTrustRequest struct {
// AcceptedAudiences Audiences an incoming subject token may name. Required (non-empty) when
// `enabled`; there is deliberately no accept-all value.
AcceptedAudiences []string `json:"accepted_audiences,omitempty"`
// Enabled Off unless explicitly enabled. Configuring a provider for *login* is
// not agreement to accept its tokens as API credentials.
Enabled *bool `json:"enabled,omitempty"`
// MaxLifetimeSecs Per-provider ceiling on the issued AXIAM token's lifetime.
MaxLifetimeSecs *int64 `json:"max_lifetime_secs,omitempty"`
// MaxTokenAgeSecs Bound on `now - iat`, independent of the token's own `exp`.
MaxTokenAgeSecs *int64 `json:"max_token_age_secs,omitempty"`
// ScopeMap External asserted value -> AXIAM scopes. Deny-by-default: an external
// value with no entry contributes nothing.
ScopeMap map[string]any `json:"scope_map,omitempty"`
// SubjectMapping `linked_only` (default) or `jit_provision`.
SubjectMapping *string `json:"subject_mapping,omitempty"`
}
TokenExchangeTrustRequest X4 trust for exchanging this provider's tokens (RFC 8693, external issuer). Mirrors [`TokenExchangeTrust`] on the wire rather than reusing it directly so the API surface can carry its own defaults: an admin PUTting a partial block gets the documented default for anything they omitted, instead of a deserialization error listing fields they have never heard of.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type TokenExchangeTrustResponse ¶
type TokenExchangeTrustResponse struct {
// AcceptedAudiences carries the server's accepted_audiences field.
AcceptedAudiences []string `json:"accepted_audiences"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// MaxLifetimeSecs carries the server's max_lifetime_secs field.
MaxLifetimeSecs *int64 `json:"max_lifetime_secs,omitempty"`
// MaxTokenAgeSecs carries the server's max_token_age_secs field.
MaxTokenAgeSecs int64 `json:"max_token_age_secs"`
// ScopeMap carries the server's scope_map field.
ScopeMap map[string]any `json:"scope_map"`
// SubjectMapping carries the server's subject_mapping field.
SubjectMapping string `json:"subject_mapping"`
}
TokenExchangeTrustResponse X4 trust as returned. Same shape as the request; nothing here is secret — an operator reading a provider needs to see exactly what it trusts.
type TokenPolicy ¶
type TokenPolicy struct {
// AccessTokenLifetimeSecs carries the server's access_token_lifetime_secs field.
AccessTokenLifetimeSecs int64 `json:"access_token_lifetime_secs"`
// RefreshTokenLifetimeSecs carries the server's refresh_token_lifetime_secs field.
RefreshTokenLifetimeSecs int64 `json:"refresh_token_lifetime_secs"`
}
TokenPolicy Token lifetime configuration.
type TokenValidationOptions ¶
type TokenValidationOptions = jwks.ValidationOptions
TokenValidationOptions carries the relying party's §10.1 expectations for JWKSVerifier.VerifyAccessToken.
Tenant is required — an empty Tenant fails closed rather than accepting an arbitrary tenant's token (§10.1 rule 4). ExpectedIssuer and ExpectedAudience are optional and default to unset: an empty value means "no expectation configured, so no check" (§10.1 rules 5/6), never "expect the empty string". This SDK hardcodes no issuer or audience anywhere.
type UmaChallenge ¶
type UmaChallenge struct {
// Realm is the protection realm the resource server named.
Realm string
// AsURI is the authorization server the resource server nominates.
// NOT AUTOMATICALLY TRUSTED — see UmaParseChallenge.
AsURI string
// Ticket is the ticket to exchange — a bearer credential for its
// 60-second life (§20.6).
Ticket Sensitive
}
UmaChallenge is a parsed `WWW-Authenticate: UMA` challenge (UMA 2.0 §3.2, §20.3).
func UmaParseChallenge ¶
func UmaParseChallenge(header string) (UmaChallenge, bool)
UmaParseChallenge parses a `WWW-Authenticate: UMA …` header value (§20.3) into its three fields, returning ok=false when the header names a different scheme.
PURE LOCAL COMPUTATION — it performs NO exchange of the ticket it finds, and that is the point. Parsing a challenge and acting on it are separate decisions: the as_uri names an authorization server the client has not necessarily chosen to trust, and auto-exchanging would send the requesting party's claim_token to whatever host answered the 401. Return the parsed challenge and let the caller decide.
type UmaExchangeTicketParams ¶
type UmaExchangeTicketParams struct {
// Ticket is the permission ticket to redeem (§20.6 secret). Required.
//
// SINGLE-USE AND NOT RETRYABLE: it is spent whether or not the exchange
// succeeds. A failure means "request a NEW ticket", never "send this one
// again" (§20.2 rule 6).
Ticket Sensitive
// ClaimToken is the requesting party's access token (§20.6 secret).
// Required, and never defaulted (§20.2 rule 2) — it is the only channel
// that names the requesting party.
ClaimToken Sensitive
// TenantID supplies the `tenant_id` query parameter.
TenantID string
// Configuration is a pre-fetched discovery document.
Configuration *OidcConfiguration
}
UmaExchangeTicketParams are the arguments to Client.UmaExchangeTicket (§20.1).
type UnknownAAGUIDAction ¶
type UnknownAAGUIDAction string
UnknownAAGUIDAction What to do with an AAGUID that has no MDS entry (i.e. FIDO Alliance has no metadata for it — not necessarily malicious, MDS coverage is incomplete for some legitimate authenticators).
const ( UnknownAAGUIDActionAllow UnknownAAGUIDAction = "allow" UnknownAAGUIDActionDeny UnknownAAGUIDAction = "deny" )
The UnknownAAGUIDAction values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type UpdateFederationConfigRequest ¶
type UpdateFederationConfigRequest struct {
// AllowTenantInheritance Whether tenants may inherit this organization-level provider.
AllowTenantInheritance *bool `json:"allow_tenant_inheritance,omitempty"`
// AllowedAlgorithms Accepted signature algorithms (CQ-B40/REQ-14 AC-5).
AllowedAlgorithms []string `json:"allowed_algorithms,omitempty"`
// AllowedIssuerTenants Accepted external IdP tenants for a templated issuer. Replaced
// wholesale.
AllowedIssuerTenants []string `json:"allowed_issuer_tenants,omitempty"`
// AppleKeyID Apple Key ID. `Some(None)` clears it.
AppleKeyID *string `json:"apple_key_id,omitempty"`
// AppleTeamID Apple Team ID. `Some(None)` clears it.
AppleTeamID *string `json:"apple_team_id,omitempty"`
// AttributeMap carries the server's attribute_map field.
AttributeMap *any `json:"attribute_map,omitempty"`
// AuthorizationEndpoint OAuth2-variant authorization endpoint. `Some(None)` clears it.
AuthorizationEndpoint *string `json:"authorization_endpoint,omitempty"`
// ButtonIcon Sign-in-button icon for a generic provider. `Some(None)` clears it.
ButtonIcon *string `json:"button_icon,omitempty"`
// ClientID carries the server's client_id field.
ClientID *string `json:"client_id,omitempty"`
// ClientSecret carries the server's client_secret field.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
ClientSecret *Sensitive `json:"client_secret,omitempty"`
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// IdpSigningCertPEM PEM-encoded X.509 certificate for verifying SAML assertions
// (CQ-B40/REQ-14 AC-5). `Some(None)` clears the stored cert.
IdpSigningCertPEM *string `json:"idp_signing_cert_pem,omitempty"`
// MetadataURL carries the server's metadata_url field.
MetadataURL *string `json:"metadata_url,omitempty"`
// Provider carries the server's provider field.
Provider *string `json:"provider,omitempty"`
// ProviderSlug Operator-chosen identifier for a `generic_*` kind. `Some(None)` clears
// it.
ProviderSlug *string `json:"provider_slug,omitempty"`
// RequirePkce Send PKCE on the authorization request.
RequirePkce *bool `json:"require_pkce,omitempty"`
// Scopes Scopes to request. Replaced wholesale; empty restores the per-kind
// default.
Scopes []string `json:"scopes,omitempty"`
// TokenEndpoint OAuth2-variant token endpoint. `Some(None)` clears it.
TokenEndpoint *string `json:"token_endpoint,omitempty"`
// TokenExchange carries the server's token_exchange field.
TokenExchange *TokenExchangeTrustRequest `json:"token_exchange,omitempty"`
// UserinfoEndpoint OAuth2-variant userinfo endpoint. `Some(None)` clears it.
UserinfoEndpoint *string `json:"userinfo_endpoint,omitempty"`
}
UpdateFederationConfigRequest is the UpdateFederationConfigRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateGroup ¶
type UpdateGroup struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
}
UpdateGroup is the UpdateGroup schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateNotificationRuleRequest ¶
type UpdateNotificationRuleRequest struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// Events carries the server's events field.
Events []NotificationEventType `json:"events,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// RecipientEmails carries the server's recipient_emails field.
RecipientEmails []string `json:"recipient_emails,omitempty"`
}
UpdateNotificationRuleRequest is the UpdateNotificationRuleRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateOAuth2ClientRequest ¶
type UpdateOAuth2ClientRequest struct {
// AuthnRequestParams carries the server's authn_request_params field.
AuthnRequestParams *AuthnRequestParamsMode `json:"authn_request_params,omitempty"`
// BackchannelLogoutURI Pass an empty string to clear a previously registered URI — the one
// edit an operator makes when an RP is decommissioned.
BackchannelLogoutURI *string `json:"backchannel_logout_uri,omitempty"`
// BrowserSSO X7.3 — see [`CreateOAuth2ClientRequest::browser_sso`].
BrowserSSO *bool `json:"browser_sso,omitempty"`
// DpopBoundAccessTokens carries the server's dpop_bound_access_tokens field.
DpopBoundAccessTokens *bool `json:"dpop_bound_access_tokens,omitempty"`
// DpopRequireNonce carries the server's dpop_require_nonce field.
DpopRequireNonce *bool `json:"dpop_require_nonce,omitempty"`
// GrantTypes carries the server's grant_types field.
GrantTypes []string `json:"grant_types,omitempty"`
// JWKS X5.1 — see the create DTO. `Some("")` clears, so a client can be
// migrated from an inline key set to a published one.
JWKS *string `json:"jwks,omitempty"`
// JWKSURI X5.1 — see the create DTO. `Some("")` clears.
JWKSURI *string `json:"jwks_uri,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// PostLogoutRedirectUris carries the server's post_logout_redirect_uris field.
PostLogoutRedirectUris []string `json:"post_logout_redirect_uris,omitempty"`
// Profile carries the server's profile field.
Profile *ClientProfile `json:"profile,omitempty"`
// RedirectUris carries the server's redirect_uris field.
RedirectUris []string `json:"redirect_uris,omitempty"`
// RequirePar carries the server's require_par field.
RequirePar *bool `json:"require_par,omitempty"`
// Scopes carries the server's scopes field.
Scopes []string `json:"scopes,omitempty"`
// SelfSignedTLSClientAuthThumbprints carries the server's self_signed_tls_client_auth_thumbprints field.
SelfSignedTLSClientAuthThumbprints []string `json:"self_signed_tls_client_auth_thumbprints,omitempty"`
// TLSClientAuthSanDns carries the server's tls_client_auth_san_dns field.
TLSClientAuthSanDns *string `json:"tls_client_auth_san_dns,omitempty"`
// TLSClientAuthSanURI carries the server's tls_client_auth_san_uri field.
TLSClientAuthSanURI *string `json:"tls_client_auth_san_uri,omitempty"`
// TLSClientAuthSubjectDn Pass an empty string to clear, as with `backchannel_logout_uri`.
TLSClientAuthSubjectDn *string `json:"tls_client_auth_subject_dn,omitempty"`
// TLSClientCertificateBoundAccessTokens carries the server's tls_client_certificate_bound_access_tokens field.
TLSClientCertificateBoundAccessTokens *bool `json:"tls_client_certificate_bound_access_tokens,omitempty"`
// TokenEndpointAuthMethod carries the server's token_endpoint_auth_method field.
TokenEndpointAuthMethod *ClientAuthMethod `json:"token_endpoint_auth_method,omitempty"`
}
UpdateOAuth2ClientRequest is the UpdateOAuth2ClientRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateOrganizationRequest ¶
type UpdateOrganizationRequest struct {
// Metadata Free-form metadata (the admin UI stores `description` here).
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// Slug carries the server's slug field.
Slug *string `json:"slug,omitempty"`
}
UpdateOrganizationRequest is the UpdateOrganizationRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdatePermissionRequest ¶
type UpdatePermissionRequest struct {
// Action carries the server's action field.
Action *string `json:"action,omitempty"`
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
}
UpdatePermissionRequest is the UpdatePermissionRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateReactorRequest ¶
type UpdateReactorRequest struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// Events carries the server's events field.
Events []string `json:"events,omitempty"`
// FailurePolicy carries the server's failure_policy field.
FailurePolicy *FailurePolicy `json:"failure_policy,omitempty"`
// Mode carries the server's mode field.
Mode *ReactorMode `json:"mode,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// Priority carries the server's priority field.
Priority *int `json:"priority,omitempty"`
// TimeoutMs carries the server's timeout_ms field.
TimeoutMs *int `json:"timeout_ms,omitempty"`
}
UpdateReactorRequest is the UpdateReactorRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateResourceRequest ¶
type UpdateResourceRequest struct {
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// ParentID carries the server's parent_id field.
ParentID *uuid.UUID `json:"parent_id,omitempty"`
// ResourceType carries the server's resource_type field.
ResourceType *string `json:"resource_type,omitempty"`
}
UpdateResourceRequest is the UpdateResourceRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateRole ¶
type UpdateRole struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// IsGlobal carries the server's is_global field.
IsGlobal *bool `json:"is_global,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
}
UpdateRole is the UpdateRole schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateScopeRequest ¶
type UpdateScopeRequest struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
}
UpdateScopeRequest is the UpdateScopeRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateServiceAccount ¶
type UpdateServiceAccount struct {
// Description carries the server's description field.
Description *string `json:"description,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// Status carries the server's status field.
Status *UserStatus `json:"status,omitempty"`
}
UpdateServiceAccount is the UpdateServiceAccount schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateTenant ¶
type UpdateTenant struct {
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Name carries the server's name field.
Name *string `json:"name,omitempty"`
// Slug carries the server's slug field.
Slug *string `json:"slug,omitempty"`
// Status carries the server's status field.
Status *TenantStatus `json:"status,omitempty"`
}
UpdateTenant Fields that can be updated on an existing tenant.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateUserRequest ¶
type UpdateUserRequest struct {
// Email carries the server's email field.
Email *string `json:"email,omitempty"`
// Metadata carries the server's metadata field.
Metadata *any `json:"metadata,omitempty"`
// Status carries the server's status field.
Status *UserStatus `json:"status,omitempty"`
// Username carries the server's username field.
Username *string `json:"username,omitempty"`
}
UpdateUserRequest is the UpdateUserRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UpdateWebhookRequest ¶
type UpdateWebhookRequest struct {
// Enabled carries the server's enabled field.
Enabled *bool `json:"enabled,omitempty"`
// Events carries the server's events field.
Events []string `json:"events,omitempty"`
// RetryPolicy carries the server's retry_policy field.
RetryPolicy *RetryPolicy `json:"retry_policy,omitempty"`
// Secret New HMAC-SHA256 shared secret (D-02 secret rotation). Encrypted
// server-side with AES-256-GCM before storage; omit to leave the existing
// secret untouched.
//
// Secret. Redacted from every fmt verb, log line and JSON rendering; the
// raw value never leaves this package except on the wire.
Secret *Sensitive `json:"secret,omitempty"`
// URL carries the server's url field.
URL *string `json:"url,omitempty"`
}
UpdateWebhookRequest is the UpdateWebhookRequest schema from the server's OpenAPI document.
Every field is optional, so this is a SPARSE body: what you leave nil is left unchanged, and is omitted from the wire request entirely rather than sent as null (§27.4 rule 5).
type UserResponse ¶
type UserResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Email carries the server's email field.
Email string `json:"email"`
// EmailVerified True when the user's email address has been verified
// (`email_verified_at` is set). Exposed for the admin UI / profile.
EmailVerified bool `json:"email_verified"`
// FailedLoginAttempts Number of consecutive failed login attempts.
FailedLoginAttempts int `json:"failed_login_attempts"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// IsLocked Whether the account is currently locked (locked_until is in the
// future).
IsLocked bool `json:"is_locked"`
// LockedUntil Timestamp until which the account is locked, if any.
LockedUntil *string `json:"locked_until,omitempty"`
// Metadata carries the server's metadata field.
Metadata any `json:"metadata"`
// MFAEnabled carries the server's mfa_enabled field.
MFAEnabled bool `json:"mfa_enabled"`
// Status carries the server's status field.
Status UserStatus `json:"status"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
// Username carries the server's username field.
Username string `json:"username"`
}
UserResponse Public-safe user representation (no password_hash, no mfa_secret).
type UserSpec ¶
type UserSpec struct {
// Key is the manifest-local identifier.
Key string
// Username is the user's natural key within the tenant.
Username string
// Email is the user's email address.
Email string
// InitialPassword is the password to set IF this user has to be created.
//
// Never used for a user that already exists: a manifest is a description of
// shape, and silently resetting a live account's password because a config
// file mentions one is not a shape change. Plan fails before any request
// when a user must be created and this is empty, rather than discovering it
// halfway through an Apply (§27.6 rule 1).
InitialPassword Sensitive
// Roles are the Keys of roles assigned directly to this user.
Roles []string
// Groups are the Keys of groups this user belongs to.
Groups []string
}
UserSpec is a user, their roles and their group memberships.
type UserStatus ¶
type UserStatus string
UserStatus is a UserStatus value from the server's schema.
const ( UserStatusActive UserStatus = "Active" UserStatusInactive UserStatus = "Inactive" UserStatusLocked UserStatus = "Locked" UserStatusPendingVerification UserStatus = "PendingVerification" UserStatusAnonymized UserStatus = "Anonymized" UserStatusDeleted UserStatus = "Deleted" )
The UserStatus values the server defines. The type is a plain string, so a value this SDK's copy of the spec does not list still decodes rather than failing the response it arrived in (CONTRACT §27.11 rule 1) — a switch over these constants needs a default arm.
type UsersAPI ¶
type UsersAPI struct {
// contains filtered or unexported fields
}
UsersAPI is the users namespace handle.
Users within the client's tenant, and the administrative side of their second factor and lockout state.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*UsersAPI) Create ¶
func (a *UsersAPI) Create(ctx context.Context, body CreateUserRequest) (UserResponse, error)
Create issues POST /api/v1/users.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*UsersAPI) Delete ¶
Delete issues DELETE /api/v1/users/{user_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*UsersAPI) DeleteMFAMethod ¶
DeleteMFAMethod issues DELETE /api/v1/users/{user_id}/mfa-methods/{method_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*UsersAPI) List ¶
func (a *UsersAPI) List(ctx context.Context, page PageRequest) (Page[UserResponse], error)
List issues GET /api/v1/users.
func (*UsersAPI) ListAll ¶
func (a *UsersAPI) ListAll(ctx context.Context, start PageRequest) ([]UserResponse, error)
ListAll walks users.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*UsersAPI) ListMFAMethods ¶
func (a *UsersAPI) ListMFAMethods(ctx context.Context, userID uuid.UUID) ([]MFAMethodResponse, error)
ListMFAMethods issues GET /api/v1/users/{user_id}/mfa-methods.
func (*UsersAPI) ListSessions ¶
ListSessions issues GET /api/v1/users/{user_id}/sessions.
func (*UsersAPI) ResetMFA ¶
ResetMFA issues POST /api/v1/users/{user_id}/reset-mfa.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*UsersAPI) Unlock ¶
Unlock issues POST /api/v1/users/{user_id}/unlock.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*UsersAPI) Update ¶
func (a *UsersAPI) Update(ctx context.Context, userID uuid.UUID, body UpdateUserRequest) (UserResponse, error)
Update issues PUT /api/v1/users/{user_id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type ValidationError ¶
type ValidationError struct {
// Operation is the registry operation that was rejected.
Operation string
// Status is the HTTP status the server answered with — 400 or 422.
Status int
// Message is the full, caller-facing description.
Message string
// Fields carries per-field detail, where the server sent any. Empty is
// normal.
Fields []FieldError
}
ValidationError reports HTTP 400 or 422: the request was rejected.
§2 maps 400 to ErrNetwork, described as an "SDK programming error". That description was written when nothing but the SDK itself could produce a 400. On this surface a 400 is usually a *user's* invalid input — an email that is not an email, a slug already taken — and an application needs to tell that from a broken socket without matching on message text. The sentinel it also matches is inherited from §2 rather than chosen here.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
func (*ValidationError) Is ¶
func (e *ValidationError) Is(target error) bool
Is matches both ErrValidation and the §2 ErrNetwork sentinel.
type VerifiedLogoutToken ¶
type VerifiedLogoutToken struct {
// SID is the session that ended. When non-empty, end only this session —
// falling back to "every session for Sub" is over-reach the AXIAM server
// itself refuses to make.
SID string
// Sub is the subject whose session ended.
Sub string
// JTI is the replay identifier.
//
// The RP dedups on this, not the SDK. Back-channel delivery is
// at-least-once with retry, so a valid token legitimately arrives twice;
// the SDK has no durable store and an in-memory guard would silently drop
// a real second logout after a restart. Surfaced, never consumed.
JTI string
}
VerifiedLogoutToken is what a verified logout token names (§12.7.3).
Deliberately NOT a bare bool: the RP has to know WHICH session to end, and a verifier that only says "valid" would force the caller to re-parse the token themselves, with none of the checks this type is proof of.
type WebauthnAttestationPolicy ¶
type WebauthnAttestationPolicy struct {
// AllowedAaguids `None` = every AAGUID is allowed except `blocked_aaguids`.
// `Some(vec![])` is a deliberate "nothing may register" policy and is
// accepted as such: `evaluate` denies every AAGUID against an empty
// allow-list. Nothing rejects it, precisely because the failure direction
// is safe — a client that sends `[]` when it meant `null` gets a
// locked-down tenant, which is visible immediately, rather than an open
// one, which is not.
AllowedAaguids []uuid.UUID `json:"allowed_aaguids,omitempty"`
// BlockRevokedStatus Deny registration if the MDS entry has ever reported `REVOKED` or any
// `*_COMPROMISE` status (sticky — D8 step 7).
BlockRevokedStatus bool `json:"block_revoked_status"`
// BlockedAaguids carries the server's blocked_aaguids field.
BlockedAaguids []uuid.UUID `json:"blocked_aaguids,omitempty"`
// MinCertification carries the server's min_certification field.
MinCertification *CertificationLevel `json:"min_certification,omitempty"`
// Mode carries the server's mode field.
Mode AttestationMode `json:"mode"`
// RequireFidoCertified Require *some* `FIDO_CERTIFIED*` status, any level. Independent of (and
// checked before) `min_certification`.
RequireFidoCertified bool `json:"require_fido_certified"`
// UnknownAAGUID carries the server's unknown_aaguid field.
UnknownAAGUID *UnknownAAGUIDAction `json:"unknown_aaguid,omitempty"`
}
WebauthnAttestationPolicy Per-tenant WebAuthn attestation policy (D5). One row per tenant; an absent row means [`WebauthnAttestationPolicy::default`], which is today's behavior unchanged.
func NewWebauthnAttestationPolicy ¶
func NewWebauthnAttestationPolicy(blockRevokedStatus bool, mode AttestationMode, requireFidoCertified bool) WebauthnAttestationPolicy
NewWebauthnAttestationPolicy builds a WebauthnAttestationPolicy with every field the server requires.
This body REPLACES rather than patches (§27.4 rule 5), so what you do not carry over from a prior read is not preserved — it is overwritten. Taking every required field as an argument is what makes forgetting one a compile error rather than a silent zero value on the wire.
The optional fields (AllowedAaguids, BlockedAaguids, MinCertification, UnknownAAGUID) stay settable on the returned value, and are equally overwritten when omitted — read the current state first and carry them across.
type WebauthnChallenge ¶
type WebauthnChallenge struct {
// Challenge is the server's options, untouched.
Challenge json.RawMessage
// StateToken binds the authenticator's answer to this challenge.
//
// A bearer credential for the length of the ceremony — one that leaks
// inside that window is a ceremony an attacker can try to complete — so it
// is Sensitive (§24.5). It is OPAQUE: this SDK never decodes it, and
// neither should a caller.
StateToken Sensitive
}
WebauthnChallenge is a started ceremony: the server's options plus the token binding a response to them.
Challenge is the raw wire value, unparsed — a {"publicKey": {...}} object carrying base64url buffers exactly as the server sent them. Hand it to the authenticator unchanged (§24.0), or call RequestJSON for the string a platform API takes.
func (WebauthnChallenge) RequestJSON ¶
func (w WebauthnChallenge) RequestJSON() (string, error)
RequestJSON returns the challenge in the JSON form every platform authenticator API takes (§24.6a rule 1).
This is the string an Android app passes to CreatePublicKeyCredentialRequest or GetPublicKeyCredentialOption, and the value a browser passes to PublicKeyCredential.parseCreationOptionsFromJSON(). It is the inner options object: the "publicKey" wrapper belongs to the DOM's CredentialCreationOptions, and the platform JSON APIs do not want it.
Pure local computation, no I/O. Nothing is defaulted, dropped or reordered on the way through (§24.0).
type WebauthnCredential ¶
type WebauthnCredential struct {
// ID is the AXIAM record id (UUID).
ID string `json:"id"`
// CredentialID is the base64url credential id, as the authenticator reported it.
CredentialID string `json:"credential_id"`
// Name is the caller-supplied label.
Name string `json:"name"`
// CredentialType is "passkey" or "security_key", as the server classified it.
CredentialType string `json:"credential_type"`
// CreatedAt is an RFC 3339 timestamp.
CreatedAt string `json:"created_at"`
// LastUsedAt is an RFC 3339 timestamp, empty when the credential has never
// produced an assertion.
LastUsedAt string `json:"last_used_at,omitempty"`
}
WebauthnCredential is a credential the user just enrolled — the 201 body of register/finish.
type WebauthnFailure ¶
type WebauthnFailure string
WebauthnFailure is a ceremony failure a caller can say something useful about (§24.6b rule 5). Five outcomes, and the first two are the ones that matter.
const ( // WebauthnCancelled covers BOTH an explicit refusal and a silent timeout. // The WebAuthn spec deliberately refuses to distinguish them, because // telling a website which one happened leaks whether an authenticator was // present. It must not be recovered by timing the call. WebauthnCancelled WebauthnFailure = "cancelled" // WebauthnAlreadyRegistered means the authenticator already holds a // credential for this account and refused to silently mint a second — the // exclusion list working, not a failure. The only classification whose // remedy is "use a different device". WebauthnAlreadyRegistered WebauthnFailure = "already_registered" // WebauthnTimeout is an explicitly aborted ceremony. WebauthnTimeout WebauthnFailure = "timeout" // WebauthnUnsupported means this device or browser cannot run the ceremony. WebauthnUnsupported WebauthnFailure = "unsupported" // WebauthnUnknown is everything else. WebauthnUnknown WebauthnFailure = "unknown" )
func ClassifyWebauthnError ¶
func ClassifyWebauthnError(name string) WebauthnFailure
ClassifyWebauthnError maps a platform ceremony error name to its canonical classification (§24.6b rule 5).
Every platform reports a ceremony failure as one opaque type whose only machine-readable part is a name, so a handset can relay just that name and a Go service can turn it into the same five outcomes a browser would see. Anything unrecognized is WebauthnUnknown rather than an error — a classifier that can fail is one more thing for an error handler to handle.
type WebauthnLoginResult ¶
type WebauthnLoginResult struct {
// AccessToken is the new access token, already adopted by this client.
AccessToken Sensitive
// RefreshToken is a SESSION refresh token, refreshed through Refresh() and
// not OidcRefresh (§24.3 rule 5).
RefreshToken Sensitive
// SessionID identifies the session just created.
SessionID string
// ExpiresIn is the access-token lifetime in seconds.
ExpiresIn uint64
}
WebauthnLoginResult is the outcome of a completed passkey sign-in.
The client is ALREADY authenticated when this is returned (§24.3 rule 1) — the tokens come back as well because a caller may want to hand them onward, not because adoption was optional.
type WebauthnPolicy ¶
type WebauthnPolicy struct {
// WebauthnUserVerification How hard the authenticator must prove *who* is present. Applies to
// enrolment and to second-factor authentication. Usernameless sign-in is
// held to `required` whatever this says — see
// [`WebauthnUserVerification`].
WebauthnUserVerification string `json:"webauthn_user_verification"`
}
WebauthnPolicy WebAuthn ceremony policy. One field today. It is a struct rather than a bare field on [`SecuritySettings`] so that the next WebAuthn control has an obvious home, and so the admin UI can group them. The *attestation* policy is deliberately not here: it lives in [`crate::models::webauthn_policy::WebauthnAttestationPolicy`], is tenant-only, and cannot join this model because AAGUID allow/block lists have no "more restrictive than" ordering to validate an override against. User verification does, so it can.
type WebauthnPolicyAPI ¶
type WebauthnPolicyAPI struct {
// contains filtered or unexported fields
}
WebauthnPolicyAPI is the webauthn_policy namespace handle.
Per-tenant attestation policy governing the §24 ceremonies, and the compliance report over it.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*WebauthnPolicyAPI) ComplianceReport ¶
func (a *WebauthnPolicyAPI) ComplianceReport(ctx context.Context) ([]ComplianceReportEntry, error)
ComplianceReport issues GET /api/v1/tenants/{tenant_id}/webauthn/compliance-report.
func (*WebauthnPolicyAPI) ForTenant ¶
func (a *WebauthnPolicyAPI) ForTenant(tenantID uuid.UUID) *WebauthnPolicyAPI
ForTenant addresses a different tenant than the client's own (§27.4 rule 3).
Returns a new handle; the original is unchanged.
func (*WebauthnPolicyAPI) Get ¶
func (a *WebauthnPolicyAPI) Get(ctx context.Context) (PolicyResponse, error)
Get issues GET /api/v1/tenants/{tenant_id}/webauthn/attestation-policy.
func (*WebauthnPolicyAPI) Set ¶
func (a *WebauthnPolicyAPI) Set(ctx context.Context, body WebauthnAttestationPolicy) (WebauthnAttestationPolicy, error)
Set issues PUT /api/v1/tenants/{tenant_id}/webauthn/attestation-policy.
This is a REPLACEMENT, not a patch (§27.4 rule 5). Every field of the body is required, and what you do not carry over from a prior read is not preserved — it is overwritten. Read first, change the field you mean, send the whole thing back.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
type WebauthnWorkspace ¶
WebauthnWorkspace names the workspace a usernameless ceremony runs inside.
Unlike the five tenant-scoped /oauth2/* operations of §12.1 rule 2, this endpoint ACCEPTS SLUGS, so a slug-only client can run a discoverable sign-in. The SDK fills these from its own configured identity when the caller passes nothing.
type WebhookResponse ¶
type WebhookResponse struct {
// CreatedAt carries the server's created_at field.
CreatedAt string `json:"created_at"`
// Enabled carries the server's enabled field.
Enabled bool `json:"enabled"`
// Events carries the server's events field.
Events []string `json:"events"`
// ID carries the server's id field.
ID uuid.UUID `json:"id"`
// RetryPolicy carries the server's retry_policy field.
RetryPolicy RetryPolicy `json:"retry_policy"`
// TenantID carries the server's tenant_id field.
TenantID uuid.UUID `json:"tenant_id"`
// UpdatedAt carries the server's updated_at field.
UpdatedAt string `json:"updated_at"`
// URL carries the server's url field.
URL string `json:"url"`
}
WebhookResponse Webhook response — omits the shared secret.
type WebhooksAPI ¶
type WebhooksAPI struct {
// contains filtered or unexported fields
}
WebhooksAPI is the webhooks namespace handle.
Outbound event notifications. Delivery signatures are verified with the §13 helper, which this namespace configures.
Acquiring one performs no I/O and allocates nothing meaningful (§27.2 rule 1); it holds the client and cannot be constructed without one.
func (*WebhooksAPI) Create ¶
func (a *WebhooksAPI) Create(ctx context.Context, body CreateWebhookRequest) (WebhookResponse, error)
Create issues POST /api/v1/webhooks.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*WebhooksAPI) Delete ¶
Delete issues DELETE /api/v1/webhooks/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
func (*WebhooksAPI) Get ¶
func (a *WebhooksAPI) Get(ctx context.Context, id uuid.UUID) (WebhookResponse, error)
Get issues GET /api/v1/webhooks/{id}.
func (*WebhooksAPI) List ¶
func (a *WebhooksAPI) List(ctx context.Context, page PageRequest) (Page[WebhookResponse], error)
List issues GET /api/v1/webhooks.
func (*WebhooksAPI) ListAll ¶
func (a *WebhooksAPI) ListAll(ctx context.Context, start PageRequest) ([]WebhookResponse, error)
ListAll walks webhooks.list to exhaustion, concatenating every page.
The auto-paging form §27.4 rule 4 requires. It stops on an empty page even if Total disagrees, so a misreporting server costs one wasted request rather than an unbounded loop.
func (*WebhooksAPI) Update ¶
func (a *WebhooksAPI) Update(ctx context.Context, id uuid.UUID, body UpdateWebhookRequest) (WebhookResponse, error)
Update issues PUT /api/v1/webhooks/{id}.
Not retried on failure (§27.4 rule 8): every write on this surface is issued exactly once, including the ones that look idempotent.
Source Files
¶
- account.go
- authz.go
- client.go
- decision_memo.go
- errors.go
- jwks.go
- login.go
- management_api.go
- management_audit.go
- management_ca_certificates.go
- management_certificates.go
- management_email_config.go
- management_errors.go
- management_federation.go
- management_groups.go
- management_manifest.go
- management_models.go
- management_notification_rules.go
- management_oauth2_clients.go
- management_organizations.go
- management_page.go
- management_permissions.go
- management_pgp_keys.go
- management_plan.go
- management_platform.go
- management_privacy.go
- management_reactors.go
- management_reconcile.go
- management_reconcile_apply.go
- management_reconcile_plan.go
- management_request.go
- management_resources.go
- management_roles.go
- management_scim_tokens.go
- management_scope.go
- management_scopes.go
- management_service_accounts.go
- management_settings.go
- management_tenants.go
- management_users.go
- management_webauthn_policy.go
- management_webhooks.go
- management_wire.go
- oidc.go
- oidc_device.go
- oidc_exchange.go
- oidc_idtoken.go
- oidc_logout.go
- oidc_par.go
- oidc_pkce.go
- oidc_state.go
- oidc_types.go
- oidc_uma.go
- oidc_wire.go
- opaque.go
- opaque_login.go
- retry.go
- sensitive.go
- telemetry.go
- version.go
- webauthn.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package amqp implements the AXIAM AMQP event consumer: a closure-handler Consume loop that HMAC-SHA256-verifies every delivery BEFORE the caller's handler ever runs (CONTRACT.md §8, D-07, SC#4).
|
Package amqp implements the AXIAM AMQP event consumer: a closure-handler Consume loop that HMAC-SHA256-verifies every delivery BEFORE the caller's handler ever runs (CONTRACT.md §8, D-07, SC#4). |
|
examples
|
|
|
account-lifecycle
command
Command account-lifecycle shows CONTRACT.md §25 — the operations that get an account into the state §1's Login/VerifyMfa/Refresh/Logout already assume: email verification, both MFA enrolment paths, and password reset.
|
Command account-lifecycle shows CONTRACT.md §25 — the operations that get an account into the state §1's Login/VerifyMfa/Refresh/Logout already assume: email verification, both MFA enrolment paths, and password reset. |
|
amqp-consumer
command
Command amqp-consumer demonstrates amqp.Consume with a closure handler that shows the full ack/nack matrix (CONTRACT.md §8, D-07).
|
Command amqp-consumer demonstrates amqp.Consume with a closure handler that shows the full ack/nack matrix (CONTRACT.md §8, D-07). |
|
authz-check
command
Command authz-check demonstrates the REST authorization surface: CheckAccess, Can (the browser/UI alias), and BatchCheck (CONTRACT.md §1).
|
Command authz-check demonstrates the REST authorization surface: CheckAccess, Can (the browser/UI alias), and BatchCheck (CONTRACT.md §1). |
|
device-login
command
Device Authorization Grant (CONTRACT.md §14) — signing in a device that cannot show a browser.
|
Device Authorization Grant (CONTRACT.md §14) — signing in a device that cannot show a browser. |
|
device-mtls-provisioning
command
Command device-mtls-provisioning provisions an IoT device with an mTLS identity, then authenticates as that device.
|
Command device-mtls-provisioning provisions an IoT device with an mTLS identity, then authenticates as that device. |
|
external-token-exchange
command
External-IdP token exchange (CONTRACT.md §15.7) — accepting a partner's token at an API gateway.
|
External-IdP token exchange (CONTRACT.md §15.7) — accepting a partner's token at an API gateway. |
|
grpc-checkaccess
command
Command grpc-checkaccess demonstrates the gRPC authorization transport: CheckAccess and BatchCheck over a lazily-connected *grpc.ClientConn (CONTRACT.md §1, §5, §9).
|
Command grpc-checkaccess demonstrates the gRPC authorization transport: CheckAccess and BatchCheck over a lazily-connected *grpc.ClientConn (CONTRACT.md §1, §5, §9). |
|
login-mfa
command
Command login-mfa demonstrates the two-phase Login/VerifyMfa flow (CONTRACT.md §1, §5).
|
Command login-mfa demonstrates the two-phase Login/VerifyMfa flow (CONTRACT.md §1, §5). |
|
logout
command
RP-initiated and back-channel logout (CONTRACT.md §12.7).
|
RP-initiated and back-channel logout (CONTRACT.md §12.7). |
|
management-basics
command
Command management-basics walks the CONTRACT §27 management surface.
|
Command management-basics walks the CONTRACT §27 management surface. |
|
management-manifest
command
Command management-manifest describes a tenant's shape and reconciles it (CONTRACT.md §27.6).
|
Command management-manifest describes a tenant's shape and reconciles it (CONTRACT.md §27.6). |
|
middleware-guard
command
Command middleware-guard demonstrates wrapping a sample net/http route with middleware.Middleware (CONTRACT.md §10, SC#1), plus a second route additionally protected with middleware.RequireAccess (CONTRACT.md §11 declarative authorization helpers).
|
Command middleware-guard demonstrates wrapping a sample net/http route with middleware.Middleware (CONTRACT.md §10, SC#1), plus a second route additionally protected with middleware.RequireAccess (CONTRACT.md §11 declarative authorization helpers). |
|
oidc-login
command
Command oidc-login demonstrates "Login with AXIAM" — the OIDC/SSO relying-party helpers (CONTRACT.md §12) — wired into a plain net/http server via middleware.OidcLoginHandler and middleware.OidcCallbackHandler.
|
Command oidc-login demonstrates "Login with AXIAM" — the OIDC/SSO relying-party helpers (CONTRACT.md §12) — wired into a plain net/http server via middleware.OidcLoginHandler and middleware.OidcCallbackHandler. |
|
opaque-login
command
Command opaque-login demonstrates the OPAQUE (RFC 9807) login path (CONTRACT.md §23).
|
Command opaque-login demonstrates the OPAQUE (RFC 9807) login path (CONTRACT.md §23). |
|
par-login
command
Command par-login shows Pushed Authorization Requests — CONTRACT.md §26 (RFC 9126).
|
Command par-login shows Pushed Authorization Requests — CONTRACT.md §26 (RFC 9126). |
|
reactor
command
Command reactor demonstrates amqp.ReactorServe — an AXIAM Reactor, the AMQP extension actor of CONTRACT.md §22.
|
Command reactor demonstrates amqp.ReactorServe — an AXIAM Reactor, the AMQP extension actor of CONTRACT.md §22. |
|
sender-constrained-guard
command
Enforcing CONTRACT.md §10.1 rule 9 in a resource server — the full rule, covering certificate-bound (RFC 8705) and DPoP-bound (RFC 9449) tokens.
|
Enforcing CONTRACT.md §10.1 rule 9 in a resource server — the full rule, covering certificate-bound (RFC 8705) and DPoP-bound (RFC 9449) tokens. |
|
telemetry-hook
command
Telemetry hooks — CONTRACT.md §19.
|
Telemetry hooks — CONTRACT.md §19. |
|
token-exchange
command
Token Exchange (CONTRACT.md §15) — narrowing a user's token before calling the next service.
|
Token Exchange (CONTRACT.md §15) — narrowing a user's token before calling the next service. |
|
uma-client
command
Command uma-client is the client half of the UMA 2.0 (CONTRACT.md §20) example pair.
|
Command uma-client is the client half of the UMA 2.0 (CONTRACT.md §20) example pair. |
|
uma-resource-server
command
Command uma-resource-server is the resource-server half of the UMA 2.0 (CONTRACT.md §20) example pair.
|
Command uma-resource-server is the resource-server half of the UMA 2.0 (CONTRACT.md §20) example pair. |
|
version-compatibility
command
Command version-compatibility reports the running Go toolchain against the range of Go versions this SDK supports.
|
Command version-compatibility reports the running Go toolchain against the range of Go versions this SDK supports. |
|
webauthn-relying-party
command
Command webauthn-relying-party shows WebAuthn / passkeys from Go — CONTRACT.md §24.
|
Command webauthn-relying-party shows WebAuthn / passkeys from Go — CONTRACT.md §24. |
|
Package grpc implements the gRPC transport for AuthorizationService (CheckAccess/BatchCheckAccess) with strict TLS and a sync-safe auth/tenant interceptor (CONTRACT.md §5/§6, SC#3).
|
Package grpc implements the gRPC transport for AuthorizationService (CheckAccess/BatchCheckAccess) with strict TLS and a sync-safe auth/tenant interceptor (CONTRACT.md §5/§6, SC#3). |
|
internal
|
|
|
cmd/genmanagement
command
Command genmanagement generates the CONTRACT §27 management surface.
|
Command genmanagement generates the CONTRACT §27 management surface. |
|
dpop
Package dpop implements DPoP proof verification — CONTRACT.md §21.7.2 (RFC 9449), contract 1.16.
|
Package dpop implements DPoP proof verification — CONTRACT.md §21.7.2 (RFC 9449), contract 1.16. |
|
jwks
Package jwks implements local JWKS fetch/cache/verification via lestrrat-go/jwx/v3 (D-06/§10), the shared local-verify primitive consumed by the net/http middleware (Plan 05) and any proactive-refresh check.
|
Package jwks implements local JWKS fetch/cache/verification via lestrrat-go/jwx/v3 (D-06/§10), the shared local-verify primitive consumed by the net/http middleware (Plan 05) and any proactive-refresh check. |
|
refreshguard
Package refreshguard implements the sync.Mutex single-flight refresh guard required by CONTRACT.md §9: exactly one in-flight POST /api/v1/auth/refresh call across any number of concurrent callers observing the same expired access token, with a double-check-after-lock pattern and no retry loop on failure (§9.3).
|
Package refreshguard implements the sync.Mutex single-flight refresh guard required by CONTRACT.md §9: exactly one in-flight POST /api/v1/auth/refresh call across any number of concurrent callers observing the same expired access token, with a double-check-after-lock pattern and no retry loop on failure (§9.3). |
|
revocation
Package revocation implements the optional session-revocation feed poller (CONTRACT.md §10.4, contract 1.44 — AXIAM threats T-39 and T-143).
|
Package revocation implements the optional session-revocation feed poller (CONTRACT.md §10.4, contract 1.44 — AXIAM threats T-39 and T-143). |
|
Package middleware implements the net/http middleware / route-guard interface (CONTRACT.md §10, D-06).
|
Package middleware implements the net/http middleware / route-guard interface (CONTRACT.md §10, D-06). |
|
Package webhook implements the T-145 / CONTRACT.md §13 webhook-signature verifier: HMAC-SHA256 verification of an inbound AXIAM webhook delivery, with Stripe-style signed-timestamp freshness checking.
|
Package webhook implements the T-145 / CONTRACT.md §13 webhook-signature verifier: HMAC-SHA256 verification of an inbound AXIAM webhook delivery, with Stripe-style signed-timestamp freshness checking. |