---
title: "Orleans.Lattice.Membership.Entra"
url: "https://nsta1.github.io/Orleans.Lattice/docs/lattice.membership.entra/README.html"
source: "https://github.com/NSTA1/Orleans.Lattice/blob/release/9.9/docs/lattice.membership.entra/README.md"
package: "Orleans.Lattice.Membership.Entra"
version: "9.9.0"
documents: "Orleans.Lattice 9.9.0 (release line 9.9)"
built: "2026-10-04"
all-pages: "https://nsta1.github.io/Orleans.Lattice/llms.txt"
bundle: "https://nsta1.github.io/Orleans.Lattice/docs/lattice.membership.entra/llms-full.txt"
---
# Orleans.Lattice.Membership.Entra

Part of the [documentation map](../index.md).

Microsoft Entra ID (Azure AD) credential authenticator for [Orleans.Lattice.Membership](../lattice.membership/README.md).

## What is it?

`Orleans.Lattice.Membership.Entra` adds a Microsoft Entra ID authenticator (`EntraCredentialAuthenticator`, registered through `AddEntraCredentialAuthenticator`) that plugs into the membership credential-authenticator seam. It specializes the built-in JWT authenticator rather than reimplementing token validation, so it inherits the same issuer, audience, signing-key, and lifetime checks and only layers on the Entra-specific concerns. The Entra dependency stack stays out of the core `Orleans.Lattice.Membership` package.

## What it does

- **Tenant-aware OIDC metadata discovery and signing-key rotation.** Validation parameters are resolved from the Entra v2.0 authority's OpenID Connect metadata endpoint. The JSON Web Key Set is cached and refreshed on its own interval through a configuration manager, so signing keys rotate automatically without a metadata fetch on every call.
- **Single- and multi-tenant issuer validation.** The authenticator validates the token issuer against a configured tenant allow-list and the templated Entra v2.0 issuer. For multi-tenant applications it checks the token's tenant id against the allow-list and accepts the templated issuer for any allowed tenant. A token whose issuer or tenant is outside the allow-list is not handled by this authenticator on issuer/tenant grounds, so resolution falls through to the next authenticator or anonymous. **Caveat:** a configured `SchemeHint` short-circuits this - when a credential's scheme matches the hint, the authenticator claims the credential before the tenant/issuer checks run, so a scheme-tagged token from a disallowed tenant is owned by this authenticator and, if it then fails validation, resolves to the anonymous subject rather than falling through to another authenticator.
- **Entra v2.0 claim conventions.** The subject is taken from the object id (`oid`, falling back to `sub`), the tenant from `tid`, and both the `groups` claim and the application roles in `roles` contribute token-asserted group ids. A validated token with no usable subject, or one equal to a reserved anonymous or system subject id, resolves to the anonymous subject. The scope (`scp`) and authorized-party (`azp`) claims, when present, are copied verbatim into the subject's flat claim bag alongside every other token claim; the authenticator does not branch its behaviour on whether the token is delegated or application-only.
- **Groups-overage handling.** When `GroupResolutionMode` is `ResolveOnOverage` and a token's group membership overflows - Entra emits the overage markers in place of the `groups` claim, so the token carries `_claim_names` and no `groups` claim - full membership is resolved through a pluggable resolver abstraction (`IEntraGroupResolver`). The resolver receives an `EntraGroupResolutionContext` (the caller's `SubjectId`, `TenantId`, and any `TokenAssertedGroups` the token still carried), and the groups it returns are unioned with the token-asserted groups. In the default `TokenOnly` mode, or with no resolver registered, the authenticator applies a documented, dependency-free token-only fallback and never throws; `TokenOnlyEntraGroupResolver` is a registrable implementation of that same fallback, echoing back the token-asserted groups.

## Transparent token freshness

An inbound token's lifetime is checked by the inherited lifetime validation (with `ValidateLifetime` at its `true` default) every time the caller's subject is resolved afresh. Between those resolutions the membership resolution cache serves the resolved subject for at most `LatticeMembershipOptions.ResolutionCacheTtl` and never past the token's own expiry, so an expired token is never honoured from the cache. Resolving overflowed group membership through Microsoft Graph is an opt-in concern handled by the separate `Orleans.Lattice.Membership.Entra.Graph` package, which keeps the Graph SDK dependency out of this package.

## Registration and ordering

The authenticator is registered on the silo builder after the base membership services. Registration guards this ordering and fails fast with a clear message when the base membership services are not present. When the add-on is not registered it has zero runtime cost.

## Reference

- [Configuration](configuration.md) - every public options property, its type, and its default.
- [Azure CLI setup guide](entra-setup.md) - provision an app registration and wire the authenticator into a silo, end to end.
- [Membership documentation](../lattice.membership/README.md) - the base identity and authorization add-on this package extends.
- [Graph group resolver](../lattice.membership.entra.graph/README.md) - the opt-in Microsoft Graph-backed overflow resolver.
