Cirreum.Authentication.External
1.0.4
dotnet add package Cirreum.Authentication.External --version 1.0.4
NuGet\Install-Package Cirreum.Authentication.External -Version 1.0.4
<PackageReference Include="Cirreum.Authentication.External" Version="1.0.4" />
<PackageVersion Include="Cirreum.Authentication.External" Version="1.0.4" />
<PackageReference Include="Cirreum.Authentication.External" />
paket add Cirreum.Authentication.External --version 1.0.4
#r "nuget: Cirreum.Authentication.External, 1.0.4"
#:package Cirreum.Authentication.External@1.0.4
#addin nuget:?package=Cirreum.Authentication.External&version=1.0.4
#tool nuget:?package=Cirreum.Authentication.External&version=1.0.4
Cirreum Authentication - External (BYOID)
Multi-tenant external IdP (BYOID) authentication scheme for the Cirreum framework
Overview
Cirreum.Authentication.External enables a single API to accept JWT bearer tokens from multiple customer Identity Providers (Okta, Auth0, customer Entra tenants, etc.) without federating those IdPs into yours. The customer's existing IdP issues tokens; your API validates them per-tenant using the resolved tenant configuration.
Use this package when your customers want to sign in to your API with their own IdP credentials. Use Cirreum.Authentication.Oidc or Cirreum.Authentication.Entra instead when you have a single, configured-by-you IdP.
How it works
- The inbound request carries a tenant indicator — a header (
X-Tenant-Id), a path segment (/tenants/{slug}/...), or a subdomain ({tenant}.api.example.com). - The package's
IExternalTenantResolver(your implementation) maps that indicator to the tenant's configuration: Authority URL, Audience, etc. - JWKS metadata is fetched from the tenant's
.well-known/openid-configurationand cached perJwksCacheDurationMinutes. - The inbound
Authorization: Bearer {jwt}is validated against the resolved per-tenant configuration. - On success, the
ClaimsPrincipalreflects the tenant's claims.
The dynamic forward resolver picks this scheme (via ExternalAuthenticationSchemeSelector — SchemeCategory.Tenant) when both a tenant indicator and a Bearer token are present on the request.
Installation
dotnet add package Cirreum.Authentication.External
Configuration
{
"Cirreum": {
"Authentication": {
"Providers": {
"External": {
"Instances": {
"default": {
"Enabled": true,
"TenantIdentifierSource": "Header",
"TenantHeaderName": "X-Tenant-Id",
"JwksCacheDurationMinutes": 60,
"RequireHttpsMetadata": true,
"TenantNotFoundBehavior": "Reject",
"ClockSkewSeconds": 30,
"DetailedErrors": false
}
}
}
}
}
}
}
Then register your tenant resolver:
builder.Services.AddSingleton<IExternalTenantResolver, MyTenantResolver>();
Implementing the tenant resolver
public sealed class MyTenantResolver(IDbConnection db) : IExternalTenantResolver {
public async Task<ExternalTenantConfig?> ResolveAsync(
string tenantIdentifier,
CancellationToken cancellationToken) {
var row = await db.QueryFirstOrDefaultAsync(
"SELECT Authority, Audience FROM Tenants WHERE Slug = @Slug AND IsActive = 1",
new { Slug = tenantIdentifier });
if (row is null) {
return null;
}
return new ExternalTenantConfig {
Authority = row.Authority,
Audience = row.Audience
};
}
}
What changed
Selector-based dispatch
ExternalAuthenticationSchemeSelector implements ISchemeSelector with SchemeCategory.Tenant. The dynamic forward resolver picks External when:
- A tenant indicator is present (per configured
TenantIdentifierSource) - An
Authorization: Bearerheader is present
The legacy static ExternalSchemeSelector helper class is retired. Detection logic survives as static methods on the new instance class for apps that compose conflict-detection at startup.
Security considerations
- Tenant configuration trust — your
IExternalTenantResolvermust return only verified, currently-active tenant configurations. Cache invalidation on tenant deactivation is your responsibility. - HTTPS enforcement —
RequireHttpsMetadata: true(default) blocks JWKS fetches over plain HTTP. - Clock skew —
ClockSkewSeconds: 30is a reasonable default; tighten for high-trust tenants. - TenantNotFoundBehavior —
Rejectis the safe default;Fallbackis only appropriate when your fallback is your own IdP under your control.
License
MIT — see LICENSE.
Cirreum Foundation Framework Layered simplicity for modern .NET
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Cirreum.AuthenticationProvider (>= 1.2.1)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.19.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Cirreum.Authentication.External:
| Package | Downloads |
|---|---|
|
Cirreum.Runtime.Authentication
App-facing umbrella for the Authentication pillar. Provides AddAuthentication() and the CirreumAuthenticationBuilder type. Transitively references all six Cirreum.Authentication.* schemes (ApiKey, SignedRequest, SessionTicket, OIDC, Entra, External) — apps install this single package to get the full Authentication track. |
GitHub repositories
This package is not used by any popular GitHub repositories.