Rwd.IAM.Client 2.0.2

dotnet add package Rwd.IAM.Client --version 2.0.2
                    
NuGet\Install-Package Rwd.IAM.Client -Version 2.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Rwd.IAM.Client" Version="2.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Rwd.IAM.Client" Version="2.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Rwd.IAM.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Rwd.IAM.Client --version 2.0.2
                    
#r "nuget: Rwd.IAM.Client, 2.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Rwd.IAM.Client@2.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Rwd.IAM.Client&version=2.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Rwd.IAM.Client&version=2.0.2
                    
Install as a Cake Tool

Rwd.IAM.Client

Small .NET 10 library for backend services: validate IAM access tokens, read realm metadata (JWKS / discovery), and optionally call IAM with client_credentials (e.g. organization path APIs). Full admin REST surface stays for direct HTTP / OpenAPI—not wrapped here except the org helpers below.


What consuming services typically need from IAM

Need This package
JWKS (GET /v1/auth/realms/{realm}/certs) to verify JWT signatures (kid) IIamRealmMetadataClient.GetJsonWebKeySetAsync (cached)
OpenID discovery (GET …/.well-known/openid-configuration) for issuer / jwks_uri / endpoints IIamRealmMetadataClient.GetOpenIdConfigurationAsync
Validate access token (signature, exact trusted iss, lifetime, optional aud) IIamAccessTokenValidator.ValidateAsync
Permission claims (permission = e.g. users:view) IamAccessTokenClaims, HasIamPermission / GetIamPermissions extensions
Organization read APIs (GET …/organizations/{id}, POST …/paths, POST …/existence) with client_credentials AddRwdIamOrganizationApiClient → IIamOrganizationsClient
HTTP errors from metadata endpoints (with IAM error_code, request_id) IamApiException and subclasses

Optional: add Rwd.IAM.Client.AspNetCore for [RequireIamPermission("resource", "scope")] (MVC) and .RequireIamPermission(...) (minimal APIs) — see src/Rwd.IAM.Client.AspNetCore/README.md.


Install

dotnet add package Rwd.IAM.Client

The public packages are available from NuGet.org. GitHub Packages can also be used when the organization feed and permissions are configured.


Outbound: machine client for organization APIs

When your service must call IAM (not only validate incoming JWTs), register AddRwdIamOrganizationApiClient. It acquires an access token with grant_type=client_credentials (cached until near expiry), attaches Bearer to requests, retries once on 401, and exposes IIamOrganizationsClient for:

  • GetPathAsync → GET /v1/auth/organizations/{id}
  • GetPathsAsync → POST /v1/auth/organizations/paths (body { "node_ids": [...] })
  • CheckExistenceAsync → POST /v1/auth/organizations/existence
using Microsoft.Extensions.DependencyInjection;
using Rwd.IAM.Client;

builder.Services.AddRwdIamOrganizationApiClient(o =>
{
    o.BaseUrl = new Uri(builder.Configuration["Iam:ApiBaseUrl"]!);
    o.RealmName = builder.Configuration["Iam:Realm"]!;
    o.ClientId = builder.Configuration["Iam:Integration:ClientId"]!;
    o.ClientSecret = builder.Configuration["Iam:Integration:ClientSecret"]!;
});

// …
var orgs = app.Services.GetRequiredService<IIamOrganizationsClient>();
var path = await orgs.GetPathAsync(someOrgId);

OrganizationPathDto exposes the Arabic Name, English NameEn, and Type as { Id, Name } (for example { "id": 1, "name": "general_directorate" }).

Use a confidential IAM client whose token includes whatever IAM needs for those routes (today they only require a valid authenticated JWT; still use a dedicated integration client in production). You can use AddRwdIamAccessTokenValidation and AddRwdIamOrganizationApiClient together (separate options objects: RwdIamJwtValidationOptions vs RwdIamClientCredentialsOptions).


Why two NuGet packages?

Package Depends on Use when
Rwd.IAM.Client HTTP + IdentityModel only Any .NET host: validate JWTs, read permission claims, call discovery/JWKS. No ASP.NET Core required (workers, tests, gRPC hosts, etc.).
Rwd.IAM.Client.AspNetCore Rwd.IAM.Client + Microsoft.AspNetCore.App ASP.NET Core only: [RequireIamPermission], minimal API .RequireIamPermission(...).

Keeping them split avoids forcing a framework reference to ASP.NET Core on services that only need validation in a console or worker. Version the two packages together (same tag publishes both).


End-to-end flow (consumer API)

  1. SPA talks to IAM directly for login / refresh; the browser sends Authorization: Bearer <access_token> to your API.
  2. In Program.cs, call AddRwdIamAccessTokenValidation with BaseUrl (IAM API URL), IssuerUrl (canonical issuer URL), and RealmName (same realm the token was issued for).
  3. Authenticate each request: either
    • use Rwd.IAM.Client.AspNetCore UseIamBearerAuthentication() middleware (see AspNetCore README), or
    • read the bearer token yourself, call ValidateAsync, and assign HttpContext.User.
  4. Authorize: IAM permissions are on claims with type permission (e.g. users:view). Either:
    • use User.HasIamPermission(...) / policies / RequireClaim, or
    • add Rwd.IAM.Client.AspNetCore and use [RequireIamPermission("resource", "scope")] or .RequireIamPermission(...) on endpoints.
  5. Optional: call IIamRealmMetadataClient.GetOpenIdConfigurationAsync at startup or for health checks (not required on every request for validation).
  6. JWKS is fetched by the SDK when validating; results are cached in memory per process (JwksCacheDuration).
[Browser] --token from IAM--> [Your API]
                |
                +--> AddRwdIamAccessTokenValidation (DI)
                +--> Middleware: Bearer --> ValidateAsync --> HttpContext.User
                +--> [Authorize] + [RequireIamPermission] / policies --> action runs

Registration

using Microsoft.Extensions.Hosting;
using Rwd.IAM.Client;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddRwdIamAccessTokenValidation(o =>
{
    o.BaseUrl = new Uri(builder.Configuration["Iam:ApiBaseUrl"]!);
    o.IssuerUrl = new Uri(builder.Configuration["Iam:IssuerUrl"]!);
    o.RealmName = builder.Configuration["Iam:Realm"]!;
    // o.JwksCacheDuration = TimeSpan.FromMinutes(5); // default
    // o.JwtClockSkew = TimeSpan.FromMinutes(2);     // default
});

using var app = builder.Build();

var validator = app.Services.GetRequiredService<IIamAccessTokenValidator>();

Validate a bearer token

using System.Security.Claims;

IIamAccessTokenValidator validator = /* from DI */;

ClaimsPrincipal principal = await validator.ValidateAsync(
    accessToken,
    audience: "your-api-audience", // or null to skip audience check
    cancellationToken: default);

// principal: roles use ClaimTypes.Role; permissions use IamAccessTokenClaims.Permission ("permission")
if (principal.HasIamPermission("users:view")) { … }

Validation compares the token’s iss claim with an exact canonical issuer ({IssuerUrl}/realms/{realm_name}), then loads keys from the IAM API base URL’s realm JWKS endpoint. The JWT header must include kid matching a JWK entry. IAM access tokens contain iam-api and dms-api audiences; user tokens also contain {realm_name}-api, while client-credentials tokens contain audit-log-api.

Multi-realm validation for central services

Central services that accept tokens from more than one IAM realm should configure every trusted realm explicitly. The SDK derives the exact issuer for each configured realm and selects the matching realm JWKS endpoint from the token’s iss claim:

builder.Services.AddRwdIamAccessTokenValidation(o =>
{
    o.BaseUrl = new Uri("https://iam.dev.res.moj.iq/");
    o.IssuerUrl = new Uri("https://iam.moj.iq/");
    o.TrustedRealmNames = ["citizens", "main", "master"];
});

builder.Services.AddIamBearerAuthentication(o =>
{
    o.Audience = "dms-api";
});

Do not trust an issuer supplied by the token or accept a URL prefix. Each central service should require its own audience (for example, dms-api).

Permissions (resource:scope strings on the token)

IAM emits each resolved permission as its own JWT claim: type permission, value e.g. users:view. Helpers: IamAccessTokenClaims.Permission, ClaimsPrincipal extensions GetIamPermissions, HasIamPermission, HasAnyIamPermission, HasAllIamPermissions.

Protecting endpoints: combine [Authorize] (authentication) with policies / HasIamPermission, or install Rwd.IAM.Client.AspNetCore and use [RequireIamPermission("districts", "view")] (MVC) or .RequireIamPermission("districts", "view") (minimal APIs). Keep strings aligned with IAM (source of truth). See Rwd.IAM.Client.AspNetCore/README.md.


Discovery only (e.g. issuer pinning or docs)

IIamRealmMetadataClient meta = app.Services.GetRequiredService<IIamRealmMetadataClient>();
var doc = await meta.GetOpenIdConfigurationAsync();
// doc.Issuer, doc.JwksUri, doc.TokenEndpoint, …

Configuration (RwdIamJwtValidationOptions)

Property Description
BaseUrl IAM API base URL used for discovery and JWKS routes (e.g. https://iam.dev.res.moj.iq/).
IssuerUrl Canonical issuer base URL used to validate iss (e.g. https://iam.moj.iq/). If omitted, BaseUrl is used.
RealmName Realm segment in /v1/auth/realms/{realm_name}/….
TrustedRealmNames Exact realm allowlist for multi-realm consumers. If empty, RealmName is trusted.
JwksCacheDuration TTL for cached JWKS (default 5 minutes). Set TimeSpan.Zero to disable caching (always refetch).
JwtClockSkew Passed to token validation (default 2 minutes).

Publishing

Tag sdk-dotnet-v* → .github/workflows/sdk-publish.yml.


License

Rwd.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Rwd.IAM.Client:

Package Downloads
Rwd.IAM.Client.AspNetCore

ASP.NET Core helpers for IAM: bearer JWT middleware, permission filters, minimal API extensions (Rwd.IAM.Client).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.2 117 8/30/2026
2.0.1 165 8/28/2026
2.0.0 105 8/28/2026