Documentation
¶
Overview ¶
Package organization owns storage-neutral organization and membership policy. Its selected profiles use an explicitly selected organization and genuine bearer sessions. Invitation preparation selects only existing verified email recipients and member grants. Durable adapters own locking and atomic effects; active-session selection, dynamic team permissions and caches remain unselected.
Index ¶
- Variables
- func CanonicalDomain(input string) (string, error)
- func ValidateRoleStatements(c DynamicRoleConfig, statements []RoleStatement) error
- type Authentication
- type Command
- type CommandInput
- type Config
- type CreateRequest
- type CreateTeamRequest
- type DeleteTeamRequest
- type DomainClaim
- type DomainClaimReadRequest
- type DomainClaimRequest
- type DomainClaimState
- type DomainConfig
- type DomainEvidenceCommand
- type DomainEvidenceObserver
- type DomainEvidenceRequest
- type DomainEvidenceResult
- type DomainEvidenceTransition
- type DomainMethod
- type DomainObservation
- type DomainProof
- type DomainProofKey
- type DomainProofReader
- type DynamicRole
- type DynamicRoleConfig
- type DynamicRoleReadRequest
- type DynamicRoleRequest
- type ID
- type Invitation
- type InvitationAcceptRequest
- type InvitationCancelRequest
- type InvitationConfig
- type InvitationCursor
- type InvitationDelivery
- type InvitationExpireRequest
- type InvitationInput
- type InvitationListMineQuery
- type InvitationListMineReader
- type InvitationListMineRequest
- type InvitationListMineResult
- type InvitationListMineSnapshot
- type InvitationPage
- type InvitationQuery
- type InvitationReadRequest
- type InvitationRecipientIdentifier
- type InvitationRejectRequest
- type InvitationRepository
- type InvitationResendRequest
- type InvitationSendRequest
- type InvitationService
- func (s *InvitationService) Get(ctx context.Context, r InvitationReadRequest) (out InvitationDelivery, err error)
- func (s *InvitationService) List(ctx context.Context, r InvitationReadRequest) (out InvitationPage, err error)
- func (s *InvitationService) ListMine(ctx context.Context, r InvitationListMineRequest) (out InvitationListMineResult, err error)
- func (s *InvitationService) PrepareAccept(ctx context.Context, r InvitationAcceptRequest) (out Command, err error)
- func (s *InvitationService) PrepareCancel(ctx context.Context, r InvitationCancelRequest) (out Command, err error)
- func (s *InvitationService) PrepareExpire(ctx context.Context, r InvitationExpireRequest) (out Command, err error)
- func (s *InvitationService) PrepareReject(ctx context.Context, r InvitationRejectRequest) (out Command, err error)
- func (s *InvitationService) PrepareResend(ctx context.Context, r InvitationResendRequest) (out Command, err error)
- func (s *InvitationService) PrepareSend(ctx context.Context, r InvitationSendRequest) (out Command, err error)
- type InvitationSnapshot
- type InvitationStatus
- type InvitationVerifier
- type LeaveRequest
- type LifecycleConfig
- type LifecycleRequest
- type LifecycleState
- type ListOrganizationsRequest
- type ListOrganizationsResult
- type Member
- type MemberRequest
- type Operation
- type Organization
- type OrganizationCursor
- type OrganizationListEntry
- type OrganizationListQuery
- type OrganizationListReader
- type OwnerTransferRequest
- type Permission
- type PermissionCheckRequest
- type Query
- type ReadRequest
- type Repository
- type Role
- type RoleBinding
- type RoleBindingRequest
- type RoleStatement
- type Service
- func (s *Service) CheckPermission(ctx context.Context, r PermissionCheckRequest) (out authorization.Decision, err error)
- func (s *Service) Execute(ctx context.Context, c Command, work UnitOfWork) (out StoreResult, err error)
- func (s *Service) Get(ctx context.Context, r ReadRequest) (View, error)
- func (s *Service) GetDomainClaim(ctx context.Context, r DomainClaimReadRequest) (out View, err error)
- func (s *Service) GetDynamicRole(ctx context.Context, r DynamicRoleReadRequest) (View, error)
- func (s *Service) GetLifecycle(ctx context.Context, r ReadRequest) (out View, err error)
- func (s *Service) GetTeam(ctx context.Context, r TeamReadRequest) (View, error)
- func (s *Service) ListDynamicRoles(ctx context.Context, r DynamicRoleReadRequest) (View, error)
- func (s *Service) ListMembers(ctx context.Context, r ReadRequest) (View, error)
- func (s *Service) ListMyTeams(ctx context.Context, r TeamReadRequest) (View, error)
- func (s *Service) ListOrganizations(ctx context.Context, r ListOrganizationsRequest) (out ListOrganizationsResult, err error)
- func (s *Service) ListTeamMembers(ctx context.Context, r TeamReadRequest) (View, error)
- func (s *Service) ListTeams(ctx context.Context, r TeamReadRequest) (View, error)
- func (s *Service) PrepareAddMember(ctx context.Context, r MemberRequest) (Command, error)
- func (s *Service) PrepareAddTeamMember(ctx context.Context, r TeamMemberRequest) (Command, error)
- func (s *Service) PrepareArchive(ctx context.Context, r LifecycleRequest) (Command, error)
- func (s *Service) PrepareAssignDynamicRole(ctx context.Context, r RoleBindingRequest) (Command, error)
- func (s *Service) PrepareAssignTeamDynamicRole(ctx context.Context, r TeamRoleBindingRequest) (Command, error)
- func (s *Service) PrepareCreate(ctx context.Context, r CreateRequest) (out Command, err error)
- func (s *Service) PrepareCreateDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
- func (s *Service) PrepareCreateTeam(ctx context.Context, r CreateTeamRequest) (Command, error)
- func (s *Service) PrepareDeleteDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
- func (s *Service) PrepareDeleteTeam(ctx context.Context, r DeleteTeamRequest) (Command, error)
- func (s *Service) PrepareDomainEvidence(ctx context.Context, r DomainEvidenceRequest, observer DomainEvidenceObserver) (out DomainEvidenceCommand, err error)
- func (s *Service) PrepareLeaveMember(ctx context.Context, r LeaveRequest) (Command, error)
- func (s *Service) PrepareOwnerTransfer(ctx context.Context, r OwnerTransferRequest) (out Command, err error)
- func (s *Service) PrepareRemoveMember(ctx context.Context, r MemberRequest) (Command, error)
- func (s *Service) PrepareRemoveTeamMember(ctx context.Context, r TeamMemberRequest) (Command, error)
- func (s *Service) PrepareReserveDomain(ctx context.Context, r DomainClaimRequest) (Command, error)
- func (s *Service) PrepareRestore(ctx context.Context, r LifecycleRequest) (Command, error)
- func (s *Service) PrepareRevokeDomainEvidence(ctx context.Context, r DomainEvidenceRequest, key DomainProofKey) (out DomainEvidenceCommand, err error)
- func (s *Service) PrepareRevokeDynamicRole(ctx context.Context, r RoleBindingRequest) (Command, error)
- func (s *Service) PrepareRevokeTeamDynamicRole(ctx context.Context, r TeamRoleBindingRequest) (Command, error)
- func (s *Service) PrepareUpdate(ctx context.Context, r UpdateRequest) (out Command, err error)
- func (s *Service) PrepareUpdateDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
- func (s *Service) PrepareUpdateMember(ctx context.Context, r MemberRequest) (Command, error)
- func (s *Service) PrepareUpdateTeam(ctx context.Context, r UpdateTeamRequest) (Command, error)
- func (s *Service) PrepareWithdrawDomain(ctx context.Context, r DomainClaimRequest) (Command, error)
- type StoreResult
- type Team
- type TeamConfig
- type TeamMember
- type TeamMemberRequest
- type TeamReadRequest
- type TeamRoleBinding
- type TeamRoleBindingRequest
- type UnitOfWork
- type UpdateRequest
- type UpdateTeamRequest
- type View
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidInput rejects invalid configuration or bounded request syntax. ErrInvalidInput = errors.New("organization: invalid input") // ErrForbidden deliberately conflates absence, inactive authority and denial. ErrForbidden = errors.New("organization: forbidden") // ErrConflict rejects duplicate or stale optimistic transitions. ErrConflict = errors.New("organization: conflict") // ErrLastOwner denies removal or demotion of the final recovery-capable owner. ErrLastOwner = errors.New("organization: last owner") // ErrLimit denies a configured organization or membership cardinality limit. ErrLimit = errors.New("organization: limit exceeded") ErrUnavailable = errors.New("organization: unavailable") // ErrSensitiveSerialization prevents implicit export of runtime custody. ErrSensitiveSerialization = errors.New("organization: sensitive serialization forbidden") )
Functions ¶
func CanonicalDomain ¶
CanonicalDomain implements this profile's deterministic ASCII-only name policy: 2 or more LDH labels, 1..63 bytes each, at most 253 canonical bytes, and a final label containing at least one ASCII letter. ASCII case folds and one terminal root dot is removed. Whitespace, wildcard, IP literals, Unicode and implicit IDNA conversion are rejected, not trimmed or interpreted. An ASCII A-label is treated as supplied ASCII; this function makes no IDNA conformance claim.
func ValidateRoleStatements ¶
func ValidateRoleStatements(c DynamicRoleConfig, statements []RoleStatement) error
ValidateRoleStatements rejects unknown or ambiguous statements before storage and again before evaluation. Empty statements intentionally grant nothing.
Types ¶
type Authentication ¶
type Authentication struct {
TenantID identity.TenantID
Bearer authentication.BearerCredential
}
Authentication selects only explicit bearer transport. Cookie/CSRF workflows require the session owner's native browser composition and are not emulated.
func (Authentication) MarshalJSON ¶
func (Authentication) MarshalJSON() ([]byte, error)
func (Authentication) MarshalText ¶
func (Authentication) MarshalText() ([]byte, error)
type Command ¶
type Command struct {
// contains filtered or unexported fields
}
Command is immutable Service-issued preparation, not a transaction/receipt. Zero is invalid. Only a native adapter's public service composes Execute with its own invocation-scoped UnitOfWork; applications need no workflow glue.
func (Command) Input ¶
func (c Command) Input() (CommandInput, error)
func (Command) MarshalJSON ¶
func (Command) MarshalText ¶
type CommandInput ¶
type CommandInput struct {
Binding identity.CommandBinding
Operation Operation
Organization Organization
Actor, Target Member
TargetUser identity.User
Role Role
Session session.GetResult
Bearer authentication.BearerCredential
MaximumMembers, MaximumPerUser, MaximumPerTenant uint64
Invitation InvitationInput
Team Team
TeamMember TeamMember
Teams TeamConfig
DomainClaim DomainClaim
DomainProof DomainProof
Domains DomainConfig
DynamicRole DynamicRole
RoleBinding RoleBinding
TeamRoleBinding TeamRoleBinding
DynamicRoles DynamicRoleConfig
OwnerTransferProof authentication.ReauthenticationProof
Lifecycle LifecycleConfig
LifecycleState LifecycleState
LifecycleReason string
LifecycleProof authentication.ReauthenticationProof
}
CommandInput is the trusted adapter projection of a Service-issued command. It contains original private session admission and bearer custody: do not log, persist or automatically serialize it. Adapters map every field into the sole durable owner's keyed command; none alone grants mutation permission.
func (CommandInput) MarshalJSON ¶
func (CommandInput) MarshalJSON() ([]byte, error)
func (CommandInput) MarshalText ¶
func (CommandInput) MarshalText() ([]byte, error)
type Config ¶
type Config struct {
Clock clock.Clock
MaximumDuration time.Duration
PolicyID string
PolicyVersion uint64
MaximumMembers, MaximumPerUser, MaximumPerTenant uint64
ValidateCanonicalID func(context.Context, ID) error
Teams TeamConfig
Domains DomainConfig
DynamicRoles DynamicRoleConfig
Lifecycle LifecycleConfig
// OwnerTransferAudience explicitly selects the signed primary-proof audience.
// Empty disables ownership transfer; it is independent of session audience.
OwnerTransferAudience string
}
Config is explicit immutable policy. Limits are finite and enforced again by the durable adapter under its own locks. MaxMembers follows the reference organization.max_members range; MaxPerUser follows organization.max_per_user. MaximumPerTenant is an additional deployment-selected cap, not a reference default. Canonical validation preserves, rather than transforms, supplied IDs.
type CreateRequest ¶
type CreateRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID ID
Slug, Name, CorrelationID string
}
CreateRequest preallocates the canonical ID and preserves CommandID across retries. Slugs are lowercase ASCII labels of 1..63 bytes, unique per tenant; names are 1..256 UTF-8 bytes without control characters. They are never logs.
type CreateTeamRequest ¶
type CreateTeamRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, TeamID ID
OrganizationVersion uint64
Name, CorrelationID string
}
CreateTeamRequest creates a named bounded team without adding members. IDs preserve canonical caller identities and are unique within an organization.
type DeleteTeamRequest ¶
type DeleteTeamRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, TeamID ID
OrganizationVersion, TeamVersion uint64
CorrelationID string
}
DeleteTeamRequest permanently retires this team identity at exact epochs. Existing member bindings cease to grant access without per-member fan-out; recreating the ID is forbidden. Historical command recovery remains separate.
type DomainClaim ¶
type DomainClaim struct {
ID, OrganizationID ID
TenantID identity.TenantID
Domain string
Version uint64
State DomainClaimState
}
DomainClaim is a primary custody snapshot bound to an immutable claim identity and exact tenant/organization. Withdrawal advances Version and retains the original Domain and ID forever; a later reservation requires a new ID.
type DomainClaimReadRequest ¶
type DomainClaimReadRequest struct {
Authentication Authentication
OrganizationID, ClaimID ID
CorrelationID string
}
DomainClaimReadRequest selects only an own-organization immutable claim ID, including its withdrawn tombstone. It cannot search for a competing owner.
type DomainClaimRequest ¶
type DomainClaimRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, ClaimID ID
OrganizationVersion, ClaimVersion uint64
Domain, CorrelationID string
}
DomainClaimRequest freezes an exact tenant/org, immutable ClaimID, canonical Domain and expected organization epoch. Reserve requires ClaimVersion zero; withdraw requires the exact current requested version. Preserve CommandID and the original prepared command for replay; never retry Unknown with a new ID.
type DomainClaimState ¶
type DomainClaimState string
DomainClaimState is the closed reservation-only lifecycle. Neither state is domain ownership evidence. Future challenge/proof profiles remain unselected.
const ( DomainRequested DomainClaimState = "requested" DomainWithdrawn DomainClaimState = "withdrawn" )
type DomainConfig ¶
type DomainConfig struct {
Version, MaximumClaims uint64
// EvidenceMaximumAge explicitly enables proof issuance and bounds original
// observation lifetime. identity-platform/REFERENCE_CONFIGURATION.md's
// sso.domain_proof.ttl allows 15m..48h;
// zero preserves reservation-only behavior. Observers may return less time.
EvidenceMaximumAge time.Duration
}
DomainConfig explicitly selects reservation custody and, independently, an optional bounded evidence lifetime. Zero disables it. Version binds immutable deployed policy; MaximumClaims bounds all retained claims (including withdrawn tombstones) per organization to 1..10,000. There is no expiry or automatic takeover.
func (DomainConfig) Validate ¶
func (c DomainConfig) Validate() error
type DomainEvidenceCommand ¶
type DomainEvidenceCommand struct {
// contains filtered or unexported fields
}
DomainEvidenceCommand is immutable organization-issued observation custody. Zero is invalid. Persist its safe Recovery binding before Apply; never repeat an external observation to recover an ambiguous outcome.
func (DomainEvidenceCommand) Command ¶
func (c DomainEvidenceCommand) Command() Command
Command exposes the trusted storage-neutral projection for native composition, never another observation or a caller-constructible mutation grant.
func (DomainEvidenceCommand) MarshalJSON ¶
func (DomainEvidenceCommand) MarshalJSON() ([]byte, error)
func (DomainEvidenceCommand) MarshalText ¶
func (DomainEvidenceCommand) MarshalText() ([]byte, error)
type DomainEvidenceObserver ¶
type DomainEvidenceObserver interface {
ObserveDomain(context.Context, DomainClaim) (DomainObservation, error)
}
DomainEvidenceObserver is a deployment-selected external observation seam, called once outside all durable locks. It is not a competing proof authority. DNS/HTTPS adapters must enforce their own bounded challenge verification. Implementations must honor cancellation and support concurrent invocations.
type DomainEvidenceRequest ¶
type DomainEvidenceRequest struct {
Claim DomainClaimRequest
ProofVersion uint64
}
DomainEvidenceRequest selects an existing requested claim and exact current proof version. This finite profile issues once (zero -> one), then optionally terminally revokes (one -> two); renewal/takeover requires a new claim identity.
type DomainEvidenceResult ¶
type DomainEvidenceResult struct {
StoreResult
Proof DomainProof
}
DomainEvidenceResult retains the sole identity command outcome. Proof is set only for committed outcomes and is the identical original historical proof.
type DomainEvidenceTransition ¶
type DomainEvidenceTransition interface {
ApplyDomainEvidence(context.Context, DomainEvidenceCommand) (DomainEvidenceResult, error)
RecoverDomainEvidence(context.Context, identity.CommandID) (DomainEvidenceResult, error)
}
DomainEvidenceTransition is invocation-scoped authenticated transition custody. Apply attempts an already observed exact command; Recover never observes or reexecutes it. Unknown and not-committed outcomes carry no proof.
type DomainMethod ¶
type DomainMethod string
DomainMethod names the explicitly supported observer profiles. A method name is not verification: only the configured trusted observer may produce evidence.
const ( DomainDNS DomainMethod = "dns-txt" DomainHTTPS DomainMethod = "https" )
type DomainObservation ¶
type DomainObservation struct {
Claim DomainClaim
Method DomainMethod
ObservedAt, ExpiresAt time.Time
Verified bool
}
DomainObservation is a trusted observer's bounded outcome for the exact claim. The observer, not a request field or method label, must verify the external challenge. Raw challenge material must not be returned, logged or persisted.
type DomainProof ¶
type DomainProof struct {
TenantID identity.TenantID
OrganizationID, ClaimID ID
Domain string
ClaimVersion, ProofVersion uint64
Method DomainMethod
ObservedAt, ExpiresAt time.Time
Revoked bool
}
DomainProof is an organization-owned immutable authoritative snapshot, not a bearer grant. Current use requires GetDomainProof; historical command recovery intentionally returns the original snapshot even after expiry or revocation. Times are UTC microseconds (PostgreSQL precision); expiry is exclusive.
type DomainProofKey ¶
type DomainProofKey DomainProof
DomainProofKey binds every authority dimension of an exact proof. Zero is invalid. Construct it by converting an authority-issued DomainProof; changing any field never selects a different authority or renews its freshness.
type DomainProofReader ¶
type DomainProofReader interface {
GetDomainProof(context.Context, DomainProofKey) (DomainProof, error)
}
DomainProofReader consults primary current authority, never a cached allow.
type DynamicRole ¶
type DynamicRole struct {
ID, OrganizationID ID
TenantID identity.TenantID
Name string
Version uint64
Statements []RoleStatement
}
DynamicRole is a current bounded custom role snapshot, never a static role. Updating replaces all statements immediately for every current binding; deleting terminally retires its ID and denies all of its bindings.
type DynamicRoleConfig ¶
type DynamicRoleConfig struct {
Version, MaximumRoles uint64
Catalog []Permission
// TeamBindingsVersion1 opts into direct+team effective role evaluation and
// team-target role.assign/revoke. Zero preserves direct-only command bytes.
TeamBindingsVersion uint64 `json:",omitempty"`
}
DynamicRoleConfig selects the custom-role profile. Zero disables it. MaximumRoles bounds retained role identities per organization (1..100), including deleted tombstones, so delete/create churn cannot grow storage. Catalog is copied at construction, has 1..128 distinct entries, and is part of durable command identity. Changing it requires a deployment policy epoch. Custom management permissions remain unsupported.
func (DynamicRoleConfig) Fingerprint ¶
func (c DynamicRoleConfig) Fingerprint() string
Fingerprint identifies this complete immutable policy, not a source revision.
func (DynamicRoleConfig) Validate ¶
func (c DynamicRoleConfig) Validate() error
Validate accepts the disabled zero policy or a bounded complete catalog.
type DynamicRoleReadRequest ¶
type DynamicRoleReadRequest struct {
Authentication Authentication
OrganizationID, RoleID ID
TargetUserID identity.UserID
// TargetTeamID selects one current team binding; it is mutually exclusive
// with TargetUserID and requires TeamBindingsVersion1. List rejects both.
TargetTeamID ID
Cursor string
Limit uint32
CorrelationID string
}
DynamicRoleReadRequest selects one exact role or an exclusive ID-keyset page. Reads require current static owner/admin authority. List requires Limit 1..100 and empty RoleID/target selectors; Get requires RoleID, zero Limit and empty Cursor. Get's optional TargetUserID returns that exact organization membership and its absent/live/tombstone RoleBinding, including versions for a fresh manager. Removed membership state remains explicit; a stored binding is never authority.
type DynamicRoleRequest ¶
type DynamicRoleRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, RoleID ID
OrganizationVersion, RoleVersion uint64
Name, CorrelationID string
Statements []RoleStatement
}
DynamicRoleRequest replaces Name/Statements for create/update. Delete accepts neither replacement field and retires all bindings without reassignment. RoleVersion is zero only for create; OrganizationVersion must always match.
type ID ¶
type ID string
ID preserves a canonical organization identifier, including existing ULIDs. It carries neither ownership nor membership authority. IDs are case-sensitive.
type Invitation ¶
type Invitation struct {
ID, OrganizationID ID
TenantID identity.TenantID
RecipientUserID identity.UserID
RecipientIdentifierID identity.IdentifierID
RecipientIdentifierVersion uint64
CreatedBy identity.UserID
Role Role
Status InvitationStatus
Version uint64
// IssuedVersion is the last pending version bound to an issued proof.
// Zero preserves legacy source projections and means first issuance (one).
// Pending/natural-expired Version equals it; terminal Version is one later.
IssuedVersion uint64
ExpiresAt time.Time
}
Invitation is safe scalar metadata. It contains neither a transport address nor proof/digest/ciphertext. It grants no access and never authenticates its recipient. Versions and IDs are exact tenant/organization scoped values.
type InvitationAcceptRequest ¶
type InvitationAcceptRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion, InvitationVersion uint64
Proof capability.Proof
CorrelationID string
}
InvitationAcceptRequest supplies the exact invitation, current organization and invitation versions and privately held capability. Authentication must independently resolve its intended verified recipient; proof is never login.
func (InvitationAcceptRequest) MarshalJSON ¶
func (InvitationAcceptRequest) MarshalJSON() ([]byte, error)
func (InvitationAcceptRequest) MarshalText ¶
func (InvitationAcceptRequest) MarshalText() ([]byte, error)
type InvitationCancelRequest ¶
type InvitationCancelRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion, InvitationVersion uint64
CorrelationID string
}
InvitationCancelRequest selects an exact live pending invitation and both original aggregate versions. The current owner/administrator is authenticated independently; cancellation never needs the recipient's bearer or proof.
type InvitationConfig ¶
type InvitationConfig struct {
Audience string
Lifetime time.Duration
MaximumPending uint64
// ExpirationReasons enables explicit expiry for these registered, non-secret
// codes only. Empty disables expiry, preserving existing profiles. At most
// 32 unique 1..64-byte codes are accepted and copied at construction.
ExpirationReasons []identity.PolicyReason
}
InvitationConfig selects owner-send/member-accept, recipient rejection and administrator cancellation/registered expiry for existing verified email recipients. Lifetime follows reference bounds15m..30d; MaximumPending follows1..10000. Zero is invalid. The composition selects48h/100 explicitly, and must enlarge capability cryptographic lifetime limits to match; the root never weakens the capability owner's defaults or creates signing keys.
type InvitationCursor ¶
type InvitationCursor string
InvitationCursor is an opaque, non-authoritative continuation. Empty starts a page; return a supplied continuation unchanged, never across subjects.
type InvitationDelivery ¶
type InvitationDelivery struct {
Invitation Invitation
EffectID delivery.IntentID
State delivery.DeliveryState
}
InvitationDelivery combines safe invitation metadata with the existing delivery owner's state. Accepted is provider acceptance, not Delivered; an ambiguous delivery never rolls back an already committed invitation. A missing effect is represented by empty EffectID and zero State, never by inventing provider failure/success. Command outcomes distinguish no queue commitment from an unresolved commit.
type InvitationExpireRequest ¶
type InvitationExpireRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion, InvitationVersion uint64
Reason identity.PolicyReason
CorrelationID string
}
InvitationExpireRequest terminalizes an exact pending invitation. Reason is a registered non-secret code, never free-form text. Independent owner/admin authentication is required; recipient credentials and proof are not authority.
type InvitationInput ¶
type InvitationInput struct {
Record Invitation
RecipientIdentifier identity.Identifier
MaximumPending uint64
Proof capability.Proof
ExpirationReason identity.PolicyReason
}
InvitationInput is trusted immutable command custody for the native adapter. Record is safe metadata; RecipientIdentifier contains sensitive canonical email and must enter only authenticated encrypted native preparation custody, never command safe_fields, audit, invitation rows or metadata responses.
func (InvitationInput) MarshalJSON ¶
func (InvitationInput) MarshalJSON() ([]byte, error)
func (InvitationInput) MarshalText ¶
func (InvitationInput) MarshalText() ([]byte, error)
type InvitationListMineQuery ¶
type InvitationListMineQuery struct {
TenantID identity.TenantID
RecipientID identity.UserID
After ID
Limit uint32
}
InvitationListMineQuery is the trusted self scope selected after native session authentication. Read at most Limit+1 rows after the exclusive ID; Limit is 1..200. Tenant+invitation ID is the installed schema's unique key.
type InvitationListMineReader ¶
type InvitationListMineReader interface {
ReadInvitationsMine(context.Context, InvitationListMineQuery) (InvitationListMineSnapshot, error)
}
InvitationListMineReader is an optional additive repository capability. Existing InvitationRepository implementations need not implement it unless listing is selected. Read current primary state, honor ctx, and release rows before returning; never retain a positive authority cache or external locks.
type InvitationListMineRequest ¶
type InvitationListMineRequest struct {
Authentication Authentication
Cursor InvitationCursor
Limit uint32
CorrelationID string
}
InvitationListMineRequest binds self through Authentication, never a claimed recipient. Limit is 1..200; Cursor is empty or a returned <=512-byte locator. Current verified identifier ID/version matches are required for every state.
type InvitationListMineResult ¶
type InvitationListMineResult struct {
Invitations []Invitation
NextCursor InvitationCursor
}
InvitationListMineResult owns safe invitation metadata only, without email, capability, delivery custody or permission to accept. All retained installed states are included; live pending rows project Expired at exclusive expiry. Pages use tenant-unique invitation IDs in bytewise C order over current state, not a retained snapshot. Earlier additions require restarting the listing.
type InvitationListMineSnapshot ¶
type InvitationListMineSnapshot struct {
Recipient identity.User
IdentifierAuthorityVersion uint64
Identifiers []InvitationRecipientIdentifier
Invitations []Invitation
}
InvitationListMineSnapshot transfers independently owned primary projections. Identifiers contains the complete bounded (<=128) current verified-email ID/version set, sorted by ID, and IdentifierAuthorityVersion is its directory owner's current epoch. No membership is required. Returned invitations must match Recipient and a current identifier exactly; unknown states fail closed.
type InvitationPage ¶
type InvitationPage struct {
Organization Organization
Actor Member
Invitations []InvitationDelivery
NextCursor ID
}
InvitationPage is a current primary keyset page, not a retained snapshot. Actor and Organization are current policy inputs, never returned grants.
type InvitationQuery ¶
type InvitationQuery struct {
Operation Operation
TenantID identity.TenantID
ActorID, RecipientUserID identity.UserID
OrganizationID, InvitationID ID
RecipientIdentifierID identity.IdentifierID
Cursor ID
Limit uint32
}
InvitationQuery is a trusted bounded primary projection selected after real authentication. Send selects a current verified existing email identifier; acceptance does not require the recipient to be a member before mutation.
type InvitationReadRequest ¶
type InvitationReadRequest struct {
Authentication Authentication
OrganizationID, ID ID
Cursor ID
Limit uint32
CorrelationID string
}
InvitationReadRequest selects owner-only safe metadata. Get requires ID and zero pagination; List requires no ID, Limit1..100 and an exclusive invitation ID cursor in bytewise C order. Pages are current, not retained snapshots.
type InvitationRecipientIdentifier ¶
type InvitationRecipientIdentifier struct {
ID identity.IdentifierID
Version uint64
}
InvitationRecipientIdentifier is a current verified email's safe identifier projection. It carries no address or proof and cannot authenticate a subject.
type InvitationRejectRequest ¶
type InvitationRejectRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion, InvitationVersion uint64
CorrelationID string
}
InvitationRejectRequest selects an exact pending invitation and original versions. Authentication must independently identify its current verified recipient. Rejection needs neither membership nor the invitation bearer.
type InvitationRepository ¶
type InvitationRepository interface {
ReadInvitation(context.Context, InvitationQuery) (InvitationSnapshot, error)
ListInvitations(context.Context, InvitationQuery) (InvitationPage, error)
}
InvitationRepository is the storage-neutral trusted preparation/read port. Returned values are independently owned and bounded. It never authenticates sessions or consumes a capability. Implementations must support cancellation and concurrent independent reads without any positive membership cache.
type InvitationResendRequest ¶
type InvitationResendRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion, InvitationVersion uint64
CorrelationID string
}
InvitationResendRequest selects an exact pending invitation and organization policy epoch. The original recipient, verified identifier, static member role and exclusive deadline are preserved; callers cannot redirect delivery or extend the grant. Retain CommandID and the prepared command for exact retries.
type InvitationSendRequest ¶
type InvitationSendRequest struct {
Authentication Authentication
CommandID identity.CommandID
ID, OrganizationID ID
OrganizationVersion uint64
RecipientUserID identity.UserID
RecipientIdentifierID identity.IdentifierID
CorrelationID string
}
InvitationSendRequest binds a caller-preallocated canonical invitation ID, organization/version and exact existing verified recipient identifier. Only the static member role is selected; no caller role/team or address is accepted.
type InvitationService ¶
type InvitationService struct {
// contains filtered or unexported fields
}
InvitationService borrows the existing root service/session/policy and explicit repository/verifier. It owns no store, transaction, token engine, delivery worker or goroutine. Immutable construction supports concurrency.
func NewInvitationService ¶
func NewInvitationService(base *Service, repository InvitationRepository, verifier InvitationVerifier, c InvitationConfig) (*InvitationService, error)
NewInvitationService validates the explicit finite profile without IO. The caller owns borrowed collaborators and their shutdown; none may be mutated concurrently with calls. Invalid or zero configuration has no defaults.
func (*InvitationService) Get ¶
func (s *InvitationService) Get(ctx context.Context, r InvitationReadRequest) (out InvitationDelivery, err error)
Get returns safe delivery/invitation metadata only to a current genuine owner. It never reveals the canonical address, bearer proof or encrypted custody.
func (*InvitationService) List ¶
func (s *InvitationService) List(ctx context.Context, r InvitationReadRequest) (out InvitationPage, err error)
List returns an independently owned, bounded page of owner-only metadata. Actor removal/current policy is rechecked on every request, without caching.
func (*InvitationService) ListMine ¶
func (s *InvitationService) ListMine(ctx context.Context, r InvitationListMineRequest) (out InvitationListMineResult, err error)
ListMine authenticates the actual human recipient and current self-list policy. It needs no organization membership or recipient-selected address. Both decisions precede live session and exact recipient/page revalidation; withdrawal, outage, cancellation or original freshness expiry releases no page.
func (*InvitationService) PrepareAccept ¶
func (s *InvitationService) PrepareAccept(ctx context.Context, r InvitationAcceptRequest) (out Command, err error)
PrepareAccept verifies but never consumes. Native execution must repeat current recipient/session/policy admission and atomically consume the shared capability with invitation, membership, scoped authority, audit and events.
func (*InvitationService) PrepareCancel ¶
func (s *InvitationService) PrepareCancel(ctx context.Context, r InvitationCancelRequest) (out Command, err error)
PrepareCancel freezes current owner/administrator admission. The native owner must repeat it under its existing transaction and terminally advance the invitation version; cryptographic validity alone must never bypass that row.
func (*InvitationService) PrepareExpire ¶
func (s *InvitationService) PrepareExpire(ctx context.Context, r InvitationExpireRequest) (out Command, err error)
PrepareExpire admits explicit expiry before or after the natural deadline. The operation catalog's pending-row transition differs from natural expiry's pending-version projection: native execution must atomically persist the next terminal version, reason, canonical audit and event, invalidating every proof.
func (*InvitationService) PrepareReject ¶
func (s *InvitationService) PrepareReject(ctx context.Context, r InvitationRejectRequest) (out Command, err error)
PrepareReject freezes recipient admission without consuming a capability. Native execution must repeat current session, recipient and organization admission and atomically terminalize the pending row with audit and events.
func (*InvitationService) PrepareResend ¶
func (s *InvitationService) PrepareResend(ctx context.Context, r InvitationResendRequest) (out Command, err error)
PrepareResend freezes current owner/administrator and original recipient admission without issuing a proof or writing state. The native adapter must atomically supersede the predecessor and issue/enqueue exactly one successor for version+1 through the existing capability, delivery and coordinator owners. The predecessor remains usable until that single commit, never alongside its successor. Historical recovery must not regenerate or redeliver either grant.
func (*InvitationService) PrepareSend ¶
func (s *InvitationService) PrepareSend(ctx context.Context, r InvitationSendRequest) (out Command, err error)
type InvitationSnapshot ¶
type InvitationSnapshot struct {
Organization Organization
Actor, Target Member
RecipientUser identity.User
RecipientIdentifier identity.Identifier
Record InvitationDelivery
PendingCount uint64
}
InvitationSnapshot is adapter input, not a public metadata response or a permission/proof. Recipient fields are sensitive native owner projections; automatic serialization is denied. Durable application must fence their original verified identifier and independent security epochs with its owner.
func (InvitationSnapshot) MarshalJSON ¶
func (InvitationSnapshot) MarshalJSON() ([]byte, error)
func (InvitationSnapshot) MarshalText ¶
func (InvitationSnapshot) MarshalText() ([]byte, error)
type InvitationStatus ¶
type InvitationStatus uint8
InvitationStatus describes the selected durable lifecycle. Zero is invalid. Natural expiry retains its last issued version; explicit expiry is the next durable record version. IssuedVersion distinguishes those projections after resend, while legacy first-issuance rows retain version1/version2 semantics. No terminal state can become pending again.
const ( InvitationPending InvitationStatus = iota + 1 InvitationAccepted InvitationExpired InvitationCancelled InvitationRejected )
type InvitationVerifier ¶
type InvitationVerifier interface {
Verify(context.Context, capability.Proof, capability.Purpose, string) (capability.Grant, error)
}
InvitationVerifier consumes the existing capability owner's non-consuming cryptographic verification contract. A verified grant is not permission or one-use consumption; those remain the native transaction owner's obligation.
type LeaveRequest ¶
type LeaveRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID ID
OrganizationVersion uint64
CorrelationID string
}
LeaveRequest removes only the authenticated human's current membership in the explicitly selected organization. OrganizationVersion is its exact policy epoch; the current membership version is captured during preparation, never supplied as a target override. The final recovery-capable owner cannot leave. Keep CommandID across retries. Historical recovery still requires current membership; a retained receipt is not permission to read after leaving.
type LifecycleConfig ¶
LifecycleConfig selects native archive/restore, not hard deletion or external integration cascades. Zero disables it. Version1 requires the same explicit signed-proof audience in both operation-specific password primary sources.
func (LifecycleConfig) Validate ¶
func (c LifecycleConfig) Validate() error
Validate accepts the disabled zero policy or the explicit version1 audience.
type LifecycleRequest ¶
type LifecycleRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID ID
OrganizationVersion uint64
Reason, CorrelationID string
Proof authentication.ReauthenticationProof
}
LifecycleRequest changes one exact organization policy version. Reason is a bounded visible-ASCII code, not free text. Proof must be freshly issued for this exact action, current owner and session by the actual password owner. Copies of visible proof fields do not authenticate their signed provenance.
func (LifecycleRequest) MarshalJSON ¶
func (LifecycleRequest) MarshalJSON() ([]byte, error)
func (LifecycleRequest) MarshalText ¶
func (LifecycleRequest) MarshalText() ([]byte, error)
type LifecycleState ¶
type LifecycleState string
LifecycleState is current primary state, never authority inferred from a retained receipt. Deleted organizations are not discoverable in this profile.
const ( LifecycleActive LifecycleState = "active" LifecycleArchived LifecycleState = "archived" )
type ListOrganizationsRequest ¶
type ListOrganizationsRequest struct {
Authentication Authentication
Cursor OrganizationCursor
Limit uint32
CorrelationID string
}
ListOrganizationsRequest lists only the current authenticated human's active organizations. Limit is 1..200 with no default (the operation's typed catalog bound). Cursor is empty or a canonical <=512-byte returned continuation. Pages use bytewise organization-ID order over current committed state; earlier additions require restarting. Unknown authority/errors yield no partial page.
type ListOrganizationsResult ¶
type ListOrganizationsResult struct {
Organizations []Organization
NextCursor OrganizationCursor
}
ListOrganizationsResult owns its bounded organization snapshots. NextCursor derives only from the last returned visible ID and is empty at the observed end. Neither a snapshot nor continuation is current authorization evidence.
type Member ¶
type Member struct {
OrganizationID ID
TenantID identity.TenantID
UserID identity.UserID
Role Role
Version, AuthorizationVersion uint64
Active bool
}
Member is a tenant/organization-bound membership snapshot. Removed bindings retain their version and organization-scoped authorization epoch as tombstones. Neither Role nor this structural value authenticates its human user.
type MemberRequest ¶
type MemberRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID ID
UserID identity.UserID
Role Role
OrganizationVersion, MemberVersion uint64
CorrelationID string
}
MemberRequest binds an exact target and organization/member optimistic versions. Add requires Role and preserves an existing removed membership's version (zero only for a never-admitted user). Remove requires the active member's version; it never treats arbitrary absence as successful removal. Update requires a different valid static Role and the exact active membership version. Only owners may grant owner or change an owner; at least one owner (the static profile's recovery administrator) must survive every transition.
type Operation ¶
type Operation string
Operation is the canonical callable operation, never selected from free text.
const ( // ApplyDomainProof admits one trusted observation for an existing claim. ApplyDomainProof Operation = "identity.organization.domain.evidence.apply" // RevokeDomainProof terminally retires that exact proof without observing. RevokeDomainProof Operation = "identity.organization.domain.evidence.revoke" )
const ( CreateDynamicRole Operation = "identity.organization.role.create" UpdateDynamicRole Operation = "identity.organization.role.update" DeleteDynamicRole Operation = "identity.organization.role.delete" GetDynamicRole Operation = "identity.organization.role.get" ListDynamicRoles Operation = "identity.organization.role.list" AssignDynamicRole Operation = "identity.organization.role.assign" RevokeDynamicRole Operation = "identity.organization.role.revoke" CheckPermission Operation = "identity.organization.permission-check" )
const ( InvitationSend Operation = "identity.organization.invitation-send" InvitationAccept Operation = "identity.organization.invitation.accept" InvitationCancel Operation = "identity.organization.invitation.cancel" InvitationReject Operation = "identity.organization.invitation.reject" InvitationExpire Operation = "identity.organization.invitation.expire" InvitationResend Operation = "identity.organization.invitation.resend" InvitationGet Operation = "identity.organization.invitation.get" InvitationList Operation = "identity.organization.invitation.list" )
const ( Create Operation = "identity.organization.create" Update Operation = "identity.organization.update" AddMember Operation = "identity.organization.member.add" UpdateMember Operation = "identity.organization.member.update" RemoveMember Operation = "identity.organization.member.remove" LeaveMember Operation = "identity.organization.member.leave" Get Operation = "identity.organization.get" ListMembers Operation = "identity.organization.member.list" )
const ( CreateTeam Operation = "identity.organization.team.create" AddTeamMember Operation = "identity.organization.team.member-add" RemoveTeamMember Operation = "identity.organization.team.member-remove" GetTeam Operation = "identity.organization.team.get" UpdateTeam Operation = "identity.organization.team.update" DeleteTeam Operation = "identity.organization.team.delete" ListTeams Operation = "identity.organization.team.list" ListMyTeams Operation = "identity.organization.team.list-mine" ListTeamMembers Operation = "identity.organization.team.member-list" )
const InvitationListMine Operation = "identity.organization.invitation.list-mine"
InvitationListMine is the authenticated recipient's safe invitation listing, not an organization membership check or an administrator's recipient lookup.
const ListOrganizations Operation = "identity.organization.list"
ListOrganizations is the current authenticated subject's organization read. It is not an active-organization selection or an arbitrary-user lookup.
const OwnerTransfer Operation = "identity.organization.owner-transfer"
OwnerTransfer atomically exchanges the authenticated owner's role with an existing nonowner member. It never creates membership or adds another owner.
func (Operation) Descriptor ¶
func (o Operation) Descriptor() identity.FeatureOperation
Descriptor identifies the one versioned storage-neutral mutation schema. Unknown and read operations return zero, which identity rejects.
type Organization ¶
type Organization struct {
ID ID
TenantID identity.TenantID
Slug, Name string
Version uint64
Active bool
}
Organization is one immutable primary snapshot, not an access decision. Version is also the organization policy/authority epoch in this profile.
type OrganizationCursor ¶
type OrganizationCursor string
OrganizationCursor is an opaque, non-authoritative keyset locator. Empty starts a listing; only use a returned cursor unchanged. It binds tenant, authenticated subject and deployed policy, not a snapshot or membership grant.
type OrganizationListEntry ¶
type OrganizationListEntry struct {
Organization Organization
Member Member
}
OrganizationListEntry is an owned current active organization/self-member projection. Native readers must also verify that Member.AuthorizationVersion is the current organization-scoped authority, not an unrelated global epoch.
type OrganizationListQuery ¶
type OrganizationListQuery struct {
TenantID identity.TenantID
ActorID identity.UserID
After ID
MaximumRows uint32
}
OrganizationListQuery is a trusted storage query generated after session authentication. MaximumRows is the configured per-user membership cap (1..1000), not the requested output size. Return at most MaximumRows+1 candidates after the exclusive ID in ascending bytewise order; the extra row detects a changed deployment cap without falsely declaring EOF. No arbitrary target is exposed through the public authenticated list request.
type OrganizationListReader ¶
type OrganizationListReader interface {
ReadOrganizations(context.Context, OrganizationListQuery) ([]OrganizationListEntry, error)
}
OrganizationListReader is an additive optional repository capability. Existing Repository implementations remain source-compatible; selecting listing on a reader without this capability returns ErrUnavailable. Reads must honor ctx, release rows/locks before returning, and use current primary state without a positive cache. The authenticated service owns policy filtering/disclosure.
type OwnerTransferRequest ¶
type OwnerTransferRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID ID
TargetUserID identity.UserID
OrganizationVersion, SourceVersion, TargetVersion uint64
CorrelationID string
// Proof is the original password owner's operation-bound reauthentication
// projection, not authenticated merely by these visible fields. The native
// primary owner must authenticate and consume its exact original record.
Proof authentication.ReauthenticationProof
}
OwnerTransferRequest binds the organization policy epoch and both membership versions. The source is always the authenticated session subject, never an actor supplied by the caller. TargetUserID must identify a different active member or administrator in the same organization. The former owner becomes RoleMember; both membership and scoped authorization versions advance. Preserve CommandID and the prepared command for retries or exact recovery.
type Permission ¶
type Permission struct {
ID string
Action authorization.Action
ResourceType authorization.ResourceType
}
Permission registers one exact action/resource type in the deployment's immutable custom-permission ceiling. No wildcard or organization-management action is admitted: custom roles never confer static owner/admin authority.
type PermissionCheckRequest ¶
type PermissionCheckRequest struct {
Authentication Authentication
OrganizationID ID
OrganizationVersion uint64
Action authorization.Action
ResourceType authorization.ResourceType
ResourceID authorization.ResourceID
CorrelationID string
}
PermissionCheckRequest checks the authenticated member's effective custom roles, never another subject. Team bindings participate only under explicit selection. OrganizationVersion is a required current policy fence. Static roles grant management only, not implicit application-resource access.
type Query ¶
type Query struct {
Operation Operation
TenantID identity.TenantID
ActorID identity.UserID
OrganizationID ID
TargetID identity.UserID
Cursor identity.UserID
Limit uint32
TeamID ID
TeamCursor string
DomainClaimID ID
DynamicRoleID ID
RoleCursor string
IncludeTeamRoles bool
// Lifecycle permits owner-only archived discovery for Get/Archive/Restore.
// It must never broaden an ordinary member/team/permission query.
Lifecycle bool
}
Query is a bounded primary read generated by Service after authentication. Adapters must recheck membership on each call; there is no positive cache. TargetID is used only for native identity-owner reads when preparing mutation.
type ReadRequest ¶
type ReadRequest struct {
Authentication Authentication
OrganizationID ID
Cursor identity.UserID
Limit uint32
CorrelationID string
}
ReadRequest chooses an exact organization. Cursor is an exclusive UserID in bytewise database C collation; Limit must be 1..100 for member listing.
type Repository ¶
Repository reads only authoritative owned organization state and delegates target identity reads to identity's native owner. It owns no authentication engine. Implementations must honor deadlines and safely support concurrency.
type RoleBinding ¶
type RoleBinding struct {
RoleID, OrganizationID ID
TenantID identity.TenantID
UserID identity.UserID
Version, OrganizationMemberVersion uint64
Active bool
}
RoleBinding binds one role to an exact current organization membership epoch. Removal/readmission or any static-role transition invalidates old bindings. Active describes the stored assignment state, not independent permission: current active membership and matching OrganizationMemberVersion still apply.
type RoleBindingRequest ¶
type RoleBindingRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, RoleID ID
UserID identity.UserID
OrganizationVersion, RoleVersion, OrganizationMemberVersion, BindingVersion uint64
CorrelationID string
}
RoleBindingRequest assigns/revokes one direct role for an active member. BindingVersion is zero for first assignment, otherwise the current tombstone or live version; all supplied organization, role and member epochs must match.
type RoleStatement ¶
type RoleStatement struct {
PermissionID string
ResourceID authorization.ResourceID
Effect authorization.Outcome
}
RoleStatement references only registered permissions, an exact resource ID, and Allow or Deny. Conditions and wildcards remain unselected; optional team inheritance evaluates these same bounded statements without expanding them.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service owns bounded authentication and pure policy/preparation, not durable transactions. A native adapter supplies the scoped UnitOfWork to Execute. NewService retains borrowed immutable collaborators and starts no goroutines.
func NewService ¶
func NewService(sessions *session.SessionService, repository Repository, policy authorization.Service, c Config) (*Service, error)
func (*Service) CheckPermission ¶
func (s *Service) CheckPermission(ctx context.Context, r PermissionCheckRequest) (out authorization.Decision, err error)
CheckPermission never caches an allow. A policy callback can veto the check; the existing RBAC/deny-overrides engine decides only current exact statements. Returned Revision is the organization policy version, not a reusable lease.
func (*Service) Execute ¶
func (s *Service) Execute(ctx context.Context, c Command, work UnitOfWork) (out StoreResult, err error)
Execute repeats current action policy with the original Service custody before borrowing the adapter's one-command work. Policy callbacks run before protected SQL; later lock waits require native final admission. It never retries an unknown result or replaces its command identity.
func (*Service) GetDomainClaim ¶
func (s *Service) GetDomainClaim(ctx context.Context, r DomainClaimReadRequest) (out View, err error)
GetDomainClaim discloses current custody only to a current owner/admin after current policy and a second primary membership/session read. It is not proof.
func (*Service) GetDynamicRole ¶
GetDynamicRole returns one current custom role after late authority revalidation.
func (*Service) GetLifecycle ¶
GetLifecycle exposes active/archived metadata only to a current owner with a genuine session and current organization.get policy. Ordinary reads continue denying archived organizations. Use this exact version to prepare restoration.
func (*Service) ListDynamicRoles ¶
ListDynamicRoles returns only current custom roles, not the closed static Role constants.
func (*Service) ListMembers ¶
func (*Service) ListMyTeams ¶
func (*Service) ListOrganizations ¶
func (s *Service) ListOrganizations(ctx context.Context, r ListOrganizationsRequest) (out ListOrganizationsResult, err error)
ListOrganizations authenticates self and filters only explicit initial Deny decisions. Captured allows must still allow at final policy admission; current session, exact organization/member snapshots and original freshness are then rechecked after callbacks. Scan work is bounded by MaximumPerUser, never by an unbounded search for a full output page. No mutation or selection is performed.
func (*Service) ListTeamMembers ¶
func (*Service) PrepareAddMember ¶
func (*Service) PrepareAddTeamMember ¶
func (*Service) PrepareArchive ¶
PrepareArchive freezes owner admission without changing authority. Execute atomically denies the organization and terminally cancels pending invitations.
func (*Service) PrepareAssignDynamicRole ¶
func (s *Service) PrepareAssignDynamicRole(ctx context.Context, r RoleBindingRequest) (Command, error)
PrepareAssignDynamicRole freezes a direct grant for one exact active membership.
func (*Service) PrepareAssignTeamDynamicRole ¶
func (s *Service) PrepareAssignTeamDynamicRole(ctx context.Context, r TeamRoleBindingRequest) (Command, error)
PrepareAssignTeamDynamicRole freezes a team-targeted role.assign command. TeamBindingsVersion1 and terminal team lifecycle must be selected explicitly.
func (*Service) PrepareCreate ¶
func (*Service) PrepareCreateDynamicRole ¶
func (s *Service) PrepareCreateDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
PrepareCreateDynamicRole freezes a new role without reserving or persisting it.
func (*Service) PrepareCreateTeam ¶
func (*Service) PrepareDeleteDynamicRole ¶
func (s *Service) PrepareDeleteDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
PrepareDeleteDynamicRole freezes terminal retirement, including all effective bindings.
func (*Service) PrepareDeleteTeam ¶
func (*Service) PrepareDomainEvidence ¶
func (s *Service) PrepareDomainEvidence(ctx context.Context, r DomainEvidenceRequest, observer DomainEvidenceObserver) (out DomainEvidenceCommand, err error)
PrepareDomainEvidence performs one explicitly trusted observation after current claim/session/policy admission. Execute must fence the original expiry again after lock waits. An observer failure leaves no durable command or authority.
func (*Service) PrepareLeaveMember ¶
PrepareLeaveMember authenticates self, checks current membership/action policy and freezes its exact membership snapshot without writing. Durable adapters must fence that same actor and the final owner under the shared aggregate lock.
func (*Service) PrepareOwnerTransfer ¶
func (s *Service) PrepareOwnerTransfer(ctx context.Context, r OwnerTransferRequest) (out Command, err error)
PrepareOwnerTransfer requires a fresh, current session and current owner membership. Preparation writes nothing. The adapter must protect both exact memberships, target identity and session through its sole commit boundary.
func (*Service) PrepareRemoveMember ¶
func (*Service) PrepareRemoveTeamMember ¶
func (*Service) PrepareReserveDomain ¶
func (*Service) PrepareRestore ¶
PrepareRestore enables only surviving native child state. It never recreates removed members, deleted teams/roles, withdrawn claims or canceled invitations.
func (*Service) PrepareRevokeDomainEvidence ¶
func (s *Service) PrepareRevokeDomainEvidence(ctx context.Context, r DomainEvidenceRequest, key DomainProofKey) (out DomainEvidenceCommand, err error)
PrepareRevokeDomainEvidence freezes terminal revocation of the exact primary proof. It performs no external observation and cannot refresh original times.
func (*Service) PrepareRevokeDynamicRole ¶
func (s *Service) PrepareRevokeDynamicRole(ctx context.Context, r RoleBindingRequest) (Command, error)
PrepareRevokeDynamicRole freezes removal of one exact current direct binding.
func (*Service) PrepareRevokeTeamDynamicRole ¶
func (s *Service) PrepareRevokeTeamDynamicRole(ctx context.Context, r TeamRoleBindingRequest) (Command, error)
PrepareRevokeTeamDynamicRole freezes removal of one exact team-role binding.
func (*Service) PrepareUpdate ¶
PrepareUpdate authenticates the human actor and checks current organization membership and action policy. Preparation writes nothing; the native adapter must recheck current authority and the expected version under its own locks.
func (*Service) PrepareUpdateDynamicRole ¶
func (s *Service) PrepareUpdateDynamicRole(ctx context.Context, r DynamicRoleRequest) (Command, error)
PrepareUpdateDynamicRole freezes a complete replacement at exact role/organization epochs.
func (*Service) PrepareUpdateMember ¶
PrepareUpdateMember freezes one exact active membership's static role change. Current owners and administrators may change nonowners; only owners may grant or demote owners. Preparation writes nothing. The native owner must serialize the last-owner invariant with removal, leave and ownership transfer and advance both organization policy and the changed subject's scoped authority atomically.
func (*Service) PrepareUpdateTeam ¶
func (*Service) PrepareWithdrawDomain ¶
type StoreResult ¶
type StoreResult struct {
Receipt identity.CommandResult
OrganizationID ID
MemberID identity.UserID
// InvitationID is set only for invitation commands, including unknown
// outcomes. It identifies the original command, never a delivery claim.
InvitationID ID
}
StoreResult retains the existing identity-owned outcome protocol. A committed result is historical, not current membership, a fresh grant or a new session. Unknown must be reconciled using the same command; never allocate a retry ID.
type Team ¶
Team is a tenant/organization-bound snapshot. Version advances on membership changes; Organization.Version is the shared policy epoch, not this local value.
type TeamConfig ¶
type TeamConfig struct {
Version, MaximumTeams, MaximumMembers uint64
// LifecycleVersion 1 selects get/update/terminal-delete after the native
// forward migration. Zero preserves the original membership-only profile
// and its serialized configuration and command framing.
LifecycleVersion uint64 `json:",omitempty"`
}
TeamConfig explicitly selects the finite membership-only profile. Zero disables it. Version identifies the immutable deployed team policy; quotas have no defaults. Teams never grant organization roles or independent permissions. MaximumTeams follows REFERENCE_CONFIGURATION organization.max_teams (10,000). MaximumMembers is a local storage/cardinality budget capped at the existing 100,000 organization-member ceiling, not a protocol-defined team default.
func (TeamConfig) Validate ¶
func (c TeamConfig) Validate() error
type TeamMember ¶
type TeamMember struct {
TeamID, OrganizationID ID
TenantID identity.TenantID
UserID identity.UserID
Version, OrganizationMemberVersion uint64
Active bool
}
TeamMember retains removal tombstones. OrganizationMemberVersion binds the exact admission, so removing and readmitting an org member cannot revive teams.
type TeamMemberRequest ¶
type TeamMemberRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, TeamID ID
UserID identity.UserID
OrganizationVersion, TeamVersion, OrganizationMemberVersion, MembershipVersion uint64
CorrelationID string
}
TeamMemberRequest binds exact organization/team/member epochs. Add requires zero MembershipVersion for a never-bound user or the previous tombstone version. Remove requires the current binding; replay uses the original prepared command.
type TeamReadRequest ¶
type TeamReadRequest struct {
Authentication Authentication
OrganizationID, TeamID ID
Cursor string
Limit uint32
CorrelationID string
}
TeamReadRequest selects an exact team or a paginated team read. GetTeam requires TeamID, Limit zero, and an empty Cursor. Paginated reads use exclusive bytewise ID keysets, 1..100 per page; only ListTeamMembers requires TeamID. Members may read their own team's members; only owners/admins may read all organization teams or other teams.
type TeamRoleBinding ¶
type TeamRoleBinding struct {
RoleID, TeamID, OrganizationID ID
TenantID identity.TenantID
Version uint64
Active bool
}
TeamRoleBinding is one organization-scoped custom-role assignment to a terminal team identity. Active is stored assignment state, not a membership grant: effective access also requires current compatible org/team membership. Version zero denotes never assigned; revoked bindings retain their version.
type TeamRoleBindingRequest ¶
type TeamRoleBindingRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, RoleID, TeamID ID
OrganizationVersion, RoleVersion, TeamVersion, BindingVersion uint64
CorrelationID string
}
TeamRoleBindingRequest assigns/revokes one role for an exact current team. OrganizationVersion, RoleVersion, TeamVersion and BindingVersion are obtained from GetDynamicRole with TargetTeamID, including retained binding tombstones. It never names or impersonates a human target and confers no manager authority.
type UnitOfWork ¶
type UnitOfWork interface {
Execute(context.Context, Command) (StoreResult, error)
Recover(context.Context, identity.CommandID) (StoreResult, error)
}
UnitOfWork is invocation-scoped, storage-neutral mutation/recovery authority. The native adapter binds it immutably to one original command and current admitted caller. Recover must reject any other ID, never perform global lookup or replay effects, and preserve committed/not-committed/unknown distinctions.
type UpdateRequest ¶
type UpdateRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID ID
OrganizationVersion uint64
Name, Slug, CorrelationID string
}
UpdateRequest replaces only Name and Slug using CreateRequest's bounds and case-sensitive semantics; it neither clears nor accepts other metadata. OrganizationVersion is the exact current organization/policy epoch. Owners and administrators may update; identical metadata returns ErrConflict without a transition, new epoch, audit or lifecycle event. Preserve CommandID across retries and reconcile ambiguous outcomes using the native adapter's recovery.
type UpdateTeamRequest ¶
type UpdateTeamRequest struct {
Authentication Authentication
CommandID identity.CommandID
OrganizationID, TeamID ID
OrganizationVersion, TeamVersion uint64
Name, CorrelationID string
}
UpdateTeamRequest replaces only the bounded Name. Both epochs must match; identical names conflict without advancing epochs or emitting effects.
type View ¶
type View struct {
Organization Organization
Actor, Target Member
TargetUser identity.User
OwnerCount uint64
Members []Member
NextCursor identity.UserID
Team Team
TeamMember TeamMember
Teams []Team
TeamMembers []TeamMember
NextTeamCursor string
DomainClaim DomainClaim
DynamicRole DynamicRole
DynamicRoles []DynamicRole
RoleBinding RoleBinding
TeamRoleBinding TeamRoleBinding
NextRoleCursor string
LifecycleState LifecycleState
LifecycleReason string
}
View is an independently owned primary snapshot. OwnerCount includes active owners only; it is advisory until rechecked under the mutation's aggregate lock.