DcsvIo.D2.AuthContext.Abstractions
0.1.1
dotnet add package DcsvIo.D2.AuthContext.Abstractions --version 0.1.1
NuGet\Install-Package DcsvIo.D2.AuthContext.Abstractions -Version 0.1.1
<PackageReference Include="DcsvIo.D2.AuthContext.Abstractions" Version="0.1.1" />
<PackageVersion Include="DcsvIo.D2.AuthContext.Abstractions" Version="0.1.1" />
<PackageReference Include="DcsvIo.D2.AuthContext.Abstractions" />
paket add DcsvIo.D2.AuthContext.Abstractions --version 0.1.1
#r "nuget: DcsvIo.D2.AuthContext.Abstractions, 0.1.1"
#:package DcsvIo.D2.AuthContext.Abstractions@0.1.1
#addin nuget:?package=DcsvIo.D2.AuthContext.Abstractions&version=0.1.1
#tool nuget:?package=DcsvIo.D2.AuthContext.Abstractions&version=0.1.1
DcsvIo.D2.AuthContext.Abstractions
Read-only IAuthContext interface — the typed contract domain code uses to reason about caller identity, organization, scopes, and impersonation context. Codegen-emitted from the auth-context contract spec by DcsvIo.D2.Context.SourceGen. Plus hand-written IAuthContextExtensions convenience helpers.
This is the domain-safe slice. Heavier runtime (HTTP middleware, JWT validation, population) is host-supplied. Sibling public package DcsvIo.D2.Context.Abstractions holds request-context interfaces + MutableRequestContext + propagation codecs.
Install
dotnet add package DcsvIo.D2.AuthContext.Abstractions
Public API
| Type / member | Contents |
|---|---|
IAuthContext (generated) |
Generated interface — re-emitted on every build from the auth-context contract spec; do not hand-edit |
IAuthContextExtensions |
Hand-written convenience helpers — HasScope, HasAnyScope, HasAllScopes, IsStaff, IsAdmin, IsForcedImpersonation, IsConsentImpersonation, IsImpersonatorStaff, IsImpersonatorAdmin |
Spec → emitted shape
The auth-context contract spec declares 5 sections:
- Token + Trust:
IsAuthenticated(trinary),Audience(IReadOnlyList<string>per RFC 7519 §4.1.3),SessionId,TokenIssuedAt,TokenExpiresAt,ActorChain(RFC 8693 flattened outermost-first) - Identity:
Subject(rawsub),UserId(subparsed as Guid),Username,RequestedByClientId(RFC 8693 §4.3 / RFC 9068 — client that requested THIS token),ImmediateCallerClientId(derived — outermost Service in chain),OriginatingClientId(derived — most-deeply-nested Service in chain, fallback to Subject for pure service-identity tokens),IsServiceIdentity(derived) - Organization:
OrgId,OrgName,OrgType,OrgRole - Impersonation:
IsImpersonating(derived),ImpersonationKind(derived),ImpersonatedBy(derived),ImpersonationSessionId(derived),ImpersonatorOrgId/ImpersonatorOrgName/ImpersonatorOrgType/ImpersonatorOrgRole(derived) - Scopes:
Scopes
All D²-custom claim-mapped properties use d2_-prefixed claim names. Standard OAuth/OIDC claims (sub, aud, iat, exp, client_id, scope, act) keep their canonical names.
The five identity properties — when to use which
| Property | Source | When meaningful |
|---|---|---|
Subject |
sub claim (raw) |
Always (when authenticated). For user tokens: a Guid string. For service-identity tokens: the OAuth client_id of the calling service. |
UserId |
sub claim parsed as Guid |
When the token represents a user. Null for pure service-identity tokens. |
RequestedByClientId |
client_id claim (RFC 8693 §4.3) |
The client that requested THIS specific token from the AS. Changes only when a token exchange occurs (RFC 8693 §4.3); under the forward-unchanged model an ordinary internal hop does NOT exchange, so this is the boundary-mint client — set once at the Edge mint and forwarded unchanged the whole way down. It changes only at a deliberate exception exchange (e.g. impersonation), where it becomes the client that triggered that exchange — never the originating client (OriginatingClientId). |
ImmediateCallerClientId |
Outermost Service entry in ActorChain |
The service that immediately called this handler. Null when the user is calling directly with no service intermediary. |
OriginatingClientId |
Most-deeply-nested Service entry in ActorChain, fallback to Subject for pure service tokens |
The primary audit identifier for end-to-end traceability across multi-hop sync + async chains. The first service that started this call chain. |
Extension methods (hand-written)
auth.HasScope("auth.password.change");
auth.HasAnyScope(Scopes.Self.Read, Scopes.Self.Write);
auth.HasAllScopes(Scopes.Auth.User.Impersonate.Consent, Scopes.Auth.Password.Change);
auth.IsStaff(); // OrgType is Admin or Support
auth.IsAdmin(); // OrgType is Admin
auth.IsForcedImpersonation(); // ImpersonationKind == Force
auth.IsConsentImpersonation(); // ImpersonationKind == Consent
auth.IsImpersonatorStaff(); // ImpersonatorOrgType is Admin or Support
auth.IsImpersonatorAdmin(); // ImpersonatorOrgType is Admin
Edge cases / gotchas
HasAllScopes()with zero arguments returnstrue(vacuous truth —[].All(...)istrue). Callers that pass a runtime-built array should guard the empty-input case if absence-of-scopes should be a denial.- Scope comparison is case-sensitive per RFC 6749 §3.3. The runtime
MutableRequestContextusesStringComparer.Ordinalwhen building the set; consumers must pass exact-case scope names. IsImpersonator*helpers are correct when not impersonating —ImpersonatorOrgTypeisnulloutside an impersonation context, sois OrgType.Admin or OrgType.Supportshort-circuits tofalsecleanly. Callers that want "this user is staff (regardless of impersonation)" should useIsStaff()instead.IsForcedImpersonation()andIsConsentImpersonation()are mutually exclusive but neither impliesIsImpersonating— when not impersonating, both returnfalse. Combine withIsImpersonatingif your branch logic needs both flavor and presence.
Telemetry
None — this lib is read-only abstractions + pure-function extension methods. Callers (auth middleware, handlers, audit emitters) are responsible for any auth-related spans / counters.
Dependencies
DcsvIo.D2.Auth.Abstractions—OrgType,Role,ActorKind,ImpersonationKind,ActorEntryDcsvIo.D2.Context.SourceGen— emitsIAuthContext.g.cs(analyzer-only)
Sister packages: DcsvIo.D2.Auth.Abstractions, DcsvIo.D2.Context.Abstractions.
| 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
- DcsvIo.D2.Auth.Abstractions (>= 0.1.1)
- DcsvIo.D2.Utilities (>= 0.1.1)
- dotenv.net (>= 4.0.2)
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.7)
- Microsoft.IdentityModel.Tokens (>= 8.16.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on DcsvIo.D2.AuthContext.Abstractions:
| Package | Downloads |
|---|---|
|
DcsvIo.D2.Context.Abstractions
Spec-driven request-context primitives for D2 — IRequestContext, MutableRequestContext, and the cross-hop propagation codecs. |
GitHub repositories
This package is not used by any popular GitHub repositories.