Table of Contents

Namespace Tharga.Team

Classes

AllRolesVisibleTenantRoleVisibilityProvider

Default ITenantRoleVisibilityProvider that makes every tenant role visible for every team. Registered unless a consumer supplies its own provider, keeping the visibility hook non-breaking.

ApiKeyLifecycleContext

Information handed to an IApiKeyLifecycleHandler when an API key is created, recycled, or deleted. On Created and Recycled the PrivateToken carries the raw key value — the only moment it is available programmatically. The host is responsible for protecting anything it captures; Tharga Team never persists, logs, or exposes the token elsewhere.

ApiKeyOptions

Configuration options for API key management.

ApiKeyScopes

Scope constants for API key management.

AuditScopes

Scope constants for the audit log.

CircuitPrincipal

Reads the caller from an AuthenticationStateProvider without assuming there is a circuit to read from.

ConsentOptions

Data-access consent options — controls cross-team access granted by a team to global roles.

DefaultIconSource

Built-in IIconSource that resolves a user subject to a configured generic default image (DefaultUserIconUrl), when set. Registered after GravatarIconSource, so it applies when Gravatar is disabled or produced nothing. Returns null when no default is configured (the avatar then falls back to initials).

DirectoryClaimTypes

Claim types carrying the external-directory object id (Microsoft Entra ID's oid), in both the raw JWT form and the .NET-mapped form.

DirectoryUser

A user as known by the external directory (e.g. Microsoft Entra ID).

DirectoryVerificationResult

Result of verifying a local user against the external directory.

DynamicTenantRoleOptions

Options for runtime-defined (dynamic) tenant roles, configured via AddThargaDynamicTenantRoles(IServiceCollection, Action<DynamicTenantRoleOptions>).

GravatarIconSource

Built-in IIconSource that resolves a user subject with an email to its Gravatar image, when enabled via IconSettings. Registered after StoredIconSource and any consumer sources, so an explicitly uploaded user icon (and custom sources) take precedence and Gravatar is a fallback. Returns null for team subjects, users without an email, or when disabled.

IconCapability

Whether the icon feature can actually do what a surface is about to promise.

IconContent

The bytes and content type of a stored icon, as returned by LoadAsync(string, CancellationToken).

IconImage

A resolved icon image to render — a URL, whether the platform's own serving endpoint or an address a custom IIconSource supplied.

IconInitials

Derives the initials shown as an avatar fallback when no icon image is resolved. One letter for a single word, first+last for multiple; falls back to "?" for an empty name.

IconOptions

Limits applied when accepting an icon (upload or downloaded URL). Configured on the platform options and enforced by IconValidation.

IconResolver

Default IIconResolver: returns the first non-null image from the registered IIconSources, in registration order. The built-in StoredIconSource is registered first, so an explicitly-set (platform-stored) icon takes precedence; consumer sources run after it and fill in only when no icon has been set.

IconRoute

The route the platform serves stored icons from. Shared between the built-in StoredIconSource (which builds the URL) and the hosting layer (which maps the endpoint), so the two never drift.

IconSettings

Runtime-adjustable icon display/behavior settings. Registered as a singleton, so a host can configure initial values at startup (via the platform options) and change them live. Distinct from IconOptions, which holds the upload limits.

IconSubject

The thing an icon is being resolved for, passed to each IIconSource. Carries what a source might key off: the kind and key, a display name (for an initials fallback), any explicitly-set icon reference, and — for user icons (Phase B) — the email and directory id.

IconValidation

Shared size + content-type validation for icons, used by the store and by the operations that accept an upload or a downloaded URL, so the same rules apply on every path.

IconValidationResult

Outcome of validating an icon against IconOptions.

InMemoryTeamCache

The built-in ITeamCache: entries held in this process, with no expiry, dropped only when a write invalidates them. Registered as a singleton by the toolkit unless a host registered its own.

Invitation
InvitationOptions

Invitation policy — how long an invitation stays acceptable.

InvitationPolicy

When an invitation expires. The single copy of that rule.

InviteModel
InviteToken

Generates the code that authorizes accepting an invitation.

InviteUserModel
MemberNameChangedArgs

Arguments for the OnMemberNameChanged callback fired by TeamComponent after a successful inline edit of Name.

NoOpIconProcessor

Default IIconProcessor: returns icon bytes unchanged. Registered by the built-in store so processing is a no-op until a real processor (e.g. the Tharga.Team.Images downsizer) is registered.

RequireAccessLevelAttribute

Declares the minimum access level required to call this method.

RequireScopeAttribute

Declares the scope required to call this method.

ResilientMemberLookup

Resilient lookup against in-memory sequences that are expected to contain at most one match but where duplicate rows have been observed in production data (see GitHub issue Tharga/Team#64). Returns the first match and logs a warning when more than one match is present, instead of throwing the way Single<TSource>(IEnumerable<TSource>, Func<TSource, bool>) would. Duplicates are surfaced via ILogger so they can be found and cleaned up out of band.

ScopeDefinition

Defines a scope with its default minimum access level and an optional human-readable description (shown as a tooltip in the scope picker).

ScopeRegistry

Stores scope definitions and resolves effective scopes for a given access level. Owner and Administrator get all registered scopes. User gets scopes registered at User or Viewer level. Viewer gets only scopes registered at Viewer level. Custom gets no base scopes at all (exempt from the Owner/Administrator all-scopes rule); its effective scopes come solely from roles and scope overrides. Grant-only scopes (RegisterGrantOnly(string, string)) are granted by no access level, Owner and Administrator included; they too are held solely through roles and scope overrides. Role scopes are unioned with access level scopes.

SelectTeamEventArgs
SelectedTeamChangedEventArgs

The selection a SelectedTeamChangedEvent is reporting.

SetOwnerResult

What a set-owner did: whether it changed anything, and which owners it displaced.

StoredIconSource

Built-in IIconSource that serves an explicitly-set icon: when the subject has an IconReference, it resolves to that icon's serving-endpoint URL; otherwise null. Registered first, ahead of any consumer sources, so a platform-stored icon takes precedence.

SupportAnswer

What an assistant had to say about a case.

SupportCase

A support conversation belonging to a team.

SupportCaseActors

Identities the toolkit itself acts under on a support case.

SupportCaseLimits

What bounds a support case, so an embedded transcript cannot grow without limit.

SupportCasePage

A page of support cases, with an explicit cursor for the next one.

SupportCaseUpdatedEventArgs

Something happened to a support case.

SupportChannelBinding

A projection of a support case onto an external system — a Slack thread, an email thread.

SupportMessage

One entry in a support case's transcript.

SupportMessagePage

A page of a support case's transcript, with an explicit cursor for the next one.

SystemRoleRegistry

Maps app/global role names to system scopes. Role names are matched case-insensitively.

SystemScopeDefinition

Defines a system-level scope (a global capability granted to system API keys and, via role mapping, to privileged users). Unlike team scopes, system scopes have no access-level hierarchy — they are a flat set.

SystemScopeRegistry

Stores system-level scope definitions. A flat set (no access level) — system keys carry an explicit list, and privileged roles map to a subset.

SystemSupportScopes

System-level scope constants for support cases that belong to no team.

SystemTeamScopes

System-level (cross-team) scope constants for team operations. Unlike the in-team TeamScopes (which authorize only the caller's own team), these authorize across any team and are granted to system API keys or privileged roles. The toolkit defines them; the consumer applies them as they see fit (e.g. o.ConfigureSystemRoles mapping a role to the scope, or a system API key's scope list).

SystemUserScopes

System-level scope constants for user administration. Like SystemTeamScopes, these authorize cross-team operations and are granted to privileged roles or system API keys. The toolkit defines them; the consumer applies them as they see fit (e.g. o.ConfigureSystemRoles mapping a role to the scope).

Tag

A system-set key-value tag on an API key. Tags are a list (not a map), so the same Key may appear more than once (e.g. a combination key tagged with multiple types). Each tag is surfaced as a tag.{Key} claim on the authenticated principal.

TeamCacheWiring

Whether the services a host registered are actually using the ITeamCache the container resolves — the one way the cache seam can be configured and silently not take effect.

TeamClaimTypes

Claim type constants for team-based authorization.

TeamInvitation

What an invite code resolves to. Everything an invitation screen needs, and nothing more.

TeamManagementService<TMember>

Delegates to Tharga.Team.ITeamService for all operations, enforcing team:read on the reads.

Mutations are enforced downstream, by AuthorizationTeamServiceDecorator over Tharga.Team.ITeamService. Reads are enforced here, because that decorator deliberately does not gate reads: the claims pipeline reads team data while building the principal, so a gate there would be circular and break sign-in.

The [RequireScope] attributes on ITeamManagementService are documentation. They would be enforced by ScopeProxy<T> if this were registered through AddTeamService, and it is not — so nothing derives from them at runtime. Do not add a read to this class and assume the attribute covers it.

Generic methods (GetTeamsAsync, DeleteTeamAsync, RenameTeamAsync) call non-generic internal versions since the proxy resolves the member type from the team data.

TeamMemberTypeResolver

Works out which ITeamMember type a team service is built around, when the host did not say so explicitly.

TeamModel
TeamOwnership

Decides who may be made the owner of a team, and which sitting owners that displaces.

TeamScopes

Scope constants for team and member management.

TeamServiceBase
TeamServiceFacets

The interfaces a caller injects to reach a team, all implemented by one object.

TeamStorageException

A team's underlying storage could not be removed. Carries the team key and the store's own failure as InnerException.

TeamsListChangedEventArgs
TenantRoleDefinition

Defines a tenant role with its associated scopes and an optional human-readable description (shown as a tooltip in the role picker, alongside the scopes the role grants).

TenantRoleRegistry

Stores tenant role definitions and resolves scopes for assigned roles.

TenantRoleService

Default ITenantRoleService: merges code-registered roles (ITenantRoleRegistry) with a team's runtime-defined custom roles (read via Tharga.Team.ITeamService) and unions their scopes on top of the access-level and override scopes resolved by IScopeRegistry. The role registry and scope registry are optional (null when the consumer configured neither).

TenantRoleServiceCollectionExtensions

Extension methods for registering tenant roles.

ThargaTeamRegistration

Vestigial registration entry point that never registered anything.

UserCreatedEventArgs

The user record created on someone's first sign-in, and the principal it was created from.

UserDeleteResult

Result of DeleteUserAsync(string, bool, CancellationToken). The local delete (all team memberships and the user record) has always completed when this is returned — a failure there throws instead.

UserNameChangeResult

Result of SetUserNameAsync(string, string, CancellationToken). The local write has always completed when this is returned — a failure there throws instead.

UserServiceBase
UserServiceCompleteness

Finds persistence extension points a host has left un-overridden.

UserServiceGap

A persistence extension point on UserServiceBase whose default silently does nothing.

UserVerificationResult

Per-user item in a bulk verification stream (VerifyAllAsync(CancellationToken)).

Structs

CachedValue<T>

The result of a cache lookup: whether an entry existed, and its value.

SupportMailPosition

How far this deployment has read the support mailbox.

Interfaces

IApiKey

Represents an API key with associated metadata.

IApiKeyAdministrationService

Service for managing and validating API keys.

IApiKeyLifecycleHandler

Opt-in hook that receives an API key's private token at the moment it exists — on create and on recycle/regenerate — plus a tokenless signal on delete. Register one or more implementations with AddThargaApiKeyLifecycleHandler<T>(); they are invoked after the corresponding operation succeeds.

The token is handed only to in-process code the host explicitly registered. If the handler throws, the originating operation (create/recycle/delete) throws too — capture failures are not swallowed.

IApiKeyManagementService

User-facing management of a team's API keys. Every operation names the team it acts on as its first argument, and requires the Manage scope on that team — holding the scope for one team does not authorize acting on another.

IIconProcessor

Optional pre-processing applied to icon bytes before they are stored — e.g. downscaling an oversized image so it fits the configured limits. The built-in store runs the registered processor before validating/persisting. Register an implementation (e.g. AddThargaImageProcessing from the Tharga.Team.Images package) to enable it; without one, icons are stored as-is.

IIconResolver

Resolves the image to display for a subject by running the registered IIconSources in order and returning the first non-null result. Returns null when no source supplies an image — the caller (e.g. an avatar component) then renders an initials/default fallback via IconInitials. Built-in; consumers customize resolution by registering sources, not by replacing the resolver.

IIconSource

A source of icon images. This is the sourcing seam — where a displayed image comes from, separate from where bytes are stored (IIconStore). The platform runs the built-in StoredIconSource first (an explicitly-set icon wins), then the registered sources (via o.AddIconSource<T>()) in order, so a consuming system can supply icons for subjects that have no platform-stored icon — returning null to defer to the next source.

IIconStore

Pluggable storage for icon bytes. The built-in default (MongoIconStore in Tharga.Team.MongoDB) stores icons in the database; a consuming system can replace it via o.AddIconStore<T>() to store elsewhere (Azure Blob, S3, an existing DMS, …). This is the storage seam — where bytes live; where a displayed image is sourced from is the separate IIconSource seam.

IScopeRegistry

Registry of all known scopes. Used at runtime to resolve effective scopes for an access level.

ISupportCaseNotifier

Tells the host when a support case changed, whichever side changed it.

ISupportCaseStore

The persistence port for support cases — what the domain needs from a store, in the domain's language.

ISupportChannel

Projects a support case onto an external system, and carries messages to it.

ISupportEventLedger

Remembers which inbound channel events have already been handled, so a redelivery is not applied twice.

ISupportMailPositionStore

Remembers how far the support mailbox has been read, so a restart does not re-read it from the start.

ISupportPresence

Whether anybody is on support right now.

ISupportResponder

Answers a support case on behalf of an assistant.

ISystemApiKeyManagementService

User-facing management of system API keys — keys not bound to any team. All methods require the SystemManage scope and no team need be selected.

ISystemRoleRegistry

Maps app/global roles (e.g. "Developer", "Administrator") to system-level scopes, so privileged users gain those scopes as claims — the user-side counterpart to a system API key's explicit scope list.

ISystemScopeRegistry

Registry of system-level (global) scopes — the capabilities a system API key (or a privileged role) may hold. Separate from the team IScopeRegistry, which is access-level based and team-scoped.

ITeam
ITeamCache

Where the toolkit keeps the three lookups its claims path performs on every authenticating request: the caller, their membership in the selected team, and that team's custom roles.

ITeamClaimsEnricher

Implement to inject custom claims (e.g. global roles) before team consent evaluation. Register via AddClaimsEnricher<T>() on ThargaBlazorOptions. Called once per request inside TeamServerClaimsTransformation, before member lookup and consent check.

ITeamDirectoryService

The caller's own teams — the interface a component, controller or MCP provider should inject to list them. Scope-filtered rather than scope-gated: each team is included only if the caller's membership in that team grants team:read.

ITeamEmailSender

Sends the invitation email. Implement it to use your own mail infrastructure (SendGrid, Azure, an existing pipeline) instead of the built-in SMTP sender.

ITeamInvitationService

Resolves an invite code to the invitation it names — the interface an invitation screen should inject.

ITeamLifecycleService

Team lifecycle operations that precede a team existing, and so cannot be authorized against one.

ITeamManagementService

The scope-checked entry point for team operations — the interface a component, controller or MCP provider should inject. Every member carries a [RequireScope] attribute enforced by ScopeProxy, so a caller lacking the scope is refused before the operation runs.

ITeamMember
ITeamOversightService

Every team, regardless of membership — the interface a component, controller or MCP provider should inject for cross-team discovery. Requires the Read system scope.

ITeamPurgeParticipant

A store holding data for a team, which must be destroyed when that team is purged.

ITeam<TMember>
ITenantRoleRegistry

Registry of tenant role definitions. Used at runtime to resolve scopes for assigned roles.

ITenantRoleService

Team-aware view over tenant roles: composes the global code-registered roles (ITenantRoleRegistry) with a team's runtime-defined custom roles, and resolves the effective scopes for a member of a specific team. This is the resolution path that lets a member assigned a custom role receive that role's scopes — the team-blind ITenantRoleRegistry only knows code roles.

ITenantRoleVisibilityProvider

Decides whether a given tenant role should be offered in the role editor for a given team. Consulted by the team role editor before building its per-team role list, letting a consumer hide feature-gated roles from teams where the feature is disabled.

IUser
IUserCacheInvalidator

Implemented by a user store that caches resolved users, so something outside it can drop a stale entry. UserServiceBase implements it; a store written from scratch need not.

IUserDirectoryService

Pluggable connection to an external user directory (e.g. Microsoft Entra ID). Optional — registered via AddUserDirectoryService<T>() on the platform options; when not registered, directory features (verify, directory-only listing, directory delete) are unavailable and their UI is hidden.

IUserManagementService

User administration operations: directory verification and user deletion. Authorization is enforced in the service layer by an authorization decorator; the [RequireScope] attributes here document the scope each operation requires. All operations require the Manage system scope. Directory-backed operations require a registered IUserDirectoryService.

IUserService

The user store. Authorization is enforced in the service layer by AuthorizationUserServiceDecorator: resolving the current user and the invitation-accept name seeding are self-service; setting a display name is allowed on the caller's own record (otherwise users:manage); the [RequireScope]-annotated members document the scope they require.

Enums

AccessLevel
ApiKeyLifecycleReason

Why an IApiKeyLifecycleHandler is being invoked.

AuditMode

Whether a call through an enforcement proxy is recorded in the audit log, declared on the method rather than configured centrally.

DirectoryUserStatus

Outcome of verifying a local user against the external directory (VerifyUserAsync(IUser, CancellationToken)).

IconKind

What an icon belongs to. Lets a single IIconStore / IIconSource serve both teams and users.

InvitationStatus

Whether an invitation is still acceptable.

MembershipState
PrivateKeyScope

Controls which owner-scoped ("private") API keys a listing includes, on top of the normal team-wide keys. The actual entitlement is always intersected with the caller's identity, so these values can never reveal a key the caller isn't allowed to see.

SupportAssistance

Whether the person raising a case wants an assistant to answer it.

SupportAssistantState

Whether an assistant is answering a case, and whether it has handed over.

SupportCaseChange

What happened to a support case.

SupportCaseClosureReason

Why a support case is closed.

SupportCaseStatus

Where a support case is in its life.

SupportChannelType

An external system a support case can be projected onto.

SupportMessageDelivery

Whether a support message reached the case's external channel.

SupportMessageKind

Who produced a message in a support case.

SupportPresenceState

What is known about support being reachable.

TeamDeleteMode

What DeleteTeamAsync does to a team.