IT.Legends.Zitadel.AccessTokenManagement 1.1.5

dotnet add package IT.Legends.Zitadel.AccessTokenManagement --version 1.1.5
                    
NuGet\Install-Package IT.Legends.Zitadel.AccessTokenManagement -Version 1.1.5
                    
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="IT.Legends.Zitadel.AccessTokenManagement" Version="1.1.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IT.Legends.Zitadel.AccessTokenManagement" Version="1.1.5" />
                    
Directory.Packages.props
<PackageReference Include="IT.Legends.Zitadel.AccessTokenManagement" />
                    
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 IT.Legends.Zitadel.AccessTokenManagement --version 1.1.5
                    
#r "nuget: IT.Legends.Zitadel.AccessTokenManagement, 1.1.5"
                    
#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 IT.Legends.Zitadel.AccessTokenManagement@1.1.5
                    
#: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=IT.Legends.Zitadel.AccessTokenManagement&version=1.1.5
                    
Install as a Cake Addin
#tool nuget:?package=IT.Legends.Zitadel.AccessTokenManagement&version=1.1.5
                    
Install as a Cake Tool

IT.Legends.Zitadel.AccessTokenManagement

A library that aims to make accessing ZITADEL APIs easy. Provides automatic service account token management — so your application can call ZITADEL APIs or other ZITADEL-protected APIs without managing tokens by hand.

NuGet NuGet Downloads


Why this package?

  • Minimal dependencies - only Duende.AccessTokenManagement.
  • Batteries-included token management - tokens are acquired, cached, and refreshed automatically via Duende.AccessTokenManagement.
  • Supports external JWT signing — the private key never has to touch your application. Signing can be offloaded to an external key vault (e.g. Azure Key Vault).
  • Named accounts — configure multiple independent service accounts in one application for multi-tenant or multi-API scenarios.

Installation

dotnet add package IT.Legends.Zitadel.AccessTokenManagement

Service Account Authentication

A ZITADEL service account is a non-human identity used to call the ZITADEL API or any API protected by ZITADEL. Three authentication methods are supported — configure exactly one per service account.

Method When to use
Personal Access Token (PAT) Simple scripts, local tooling, static tokens
Client Credentials Standard OAuth2 client_id + client_secret flow
JWT Profile Asymmetric key, no secret over the wire

For examples please check out the examples directory.


Setup

Call ConfigureZitadelServiceAccount() once during startup to register the service account, then attach it to any IHttpClientBuilder (including gRPC clients) with WithZitadelServiceAccount().

Personal Access Token

builder.Services.ConfigureZitadelServiceAccount(o =>
{
    o.Pat = new ZitadelServiceAccount.PatProfile
    {
        AccessToken = "<your-personal-access-token>",
    };
});

Client Credentials

builder.Services.ConfigureZitadelServiceAccount(o =>
{
    o.Authority = "https://<your-instance>.zitadel.cloud";
    o.Scopes = ["openid", "urn:zitadel:iam:org:project:id:<project-id>:aud"];
    o.ClientCredentials = new ZitadelServiceAccount.ClientCredentialsProfile
    {
        ClientId = "<client-id>",
        ClientSecret = "<client-secret>",
    };
});
builder.Services.ConfigureZitadelServiceAccount(o =>
{
    o.Authority = "https://<your-instance>.zitadel.cloud";
    o.Scopes = ["openid", "urn:zitadel:iam:org:project:id:<project-id>:aud"];
    o.Jwt = new ZitadelServiceAccount.JwtProfile
    {
        UserId = "<service-account-user-id>",
        KeyId = "<key-id>",
        // Provide either a static private key...
        Key = "-----BEGIN RSA PRIVATE KEY-----\nMY SUPER SECRET KEY\n-----END RSA PRIVATE KEY-----\n",
        // ...or offload signing to an external vault (e.g. Azure Key Vault)
        SignJwtAsync = async (services, data, ct) =>
        {
            var keyId = "https://my-vault.vault.azure.net/keys/zitadel-sa/123456789012345678";
            var client = new CryptographyClient(new Uri(keyId), new DefaultAzureCredential());
            return (await client.SignDataAsync(SignatureAlgorithm.RS256, data, ct)).Signature;
        },
    };
});

The JWT credentials JSON can be downloaded from the ZITADEL console when you create a service account key.

Inject and use the client directly — no manual token handling required:

public class UserSyncService(UserService.UserServiceClient users)
{
    public async Task<GetUserByIDResponse> GetAsync(string userId, CancellationToken ct)
        => await users.GetUserByIDAsync(new GetUserByIDRequest { UserId = userId }, cancellationToken: ct);
}

The full list of available clients follows ZITADEL's API versioning — see the ZITADEL API Reference for what each service exposes.


Calling ZITADEL-Protected APIs

The service account token management is not limited to ZITADEL's own APIs. Any HttpClient can be wired up the same way:

builder.Services
    .ConfigureZitadelServiceAccount(o => { /* ... */ })
    .AddHttpClient<MyApiClient>(o =>
    {
        o.BaseAddress = new Uri("https://my-internal-api.example.com");
    })
    .WithZitadelServiceAccount();

Calling ZITADEL APIs

Add the IT.Legends.Zitadel.Clients package and register the client you need with AddGrpcClient<T>(), then attach the service account with WithZitadelServiceAccount(). Token acquisition and refresh happen automatically.

builder.Services
    .ConfigureZitadelServiceAccount(o => { /* ... */ })
    .AddGrpcClient<UserService.UserServiceClient>(o =>
    {
        o.Address = new Uri("https://<your-instance>.zitadel.cloud");
    })
    .WithZitadelServiceAccount();

Multiple Service Accounts

Use named accounts when your application needs to authenticate as different identities — for instance, one account per downstream API or organization:

builder.Services
    .ConfigureZitadelServiceAccount("billing-api", o => { /* ... */ })
    .ConfigureZitadelServiceAccount("reporting-api", o => { /* ... */ });

builder.Services
    .AddGrpcClient<BillingService.BillingServiceClient>(o => { /* ... */ })
    .WithZitadelServiceAccount("billing-api");

builder.Services
    .AddHttpClient<ReportingClient>(o => { /* ... */ })
    .WithZitadelServiceAccount("reporting-api");

Configuration Reference

ZitadelServiceAccount

Property Type Description
Authority string Full URL of the authority that issues the tokens (not required when using PAT)
TokenPath string Path to retrieve the token relative to the authority.
Scopes string[] Scopes to request. Defaults to ["openid"]
Pat PatProfile? Personal Access Token configuration
ClientCredentials ClientCredentialsProfile? Client credentials configuration
Jwt JwtProfile? JWT Profile configuration (recommended)

Exactly one of Pat, ClientCredentials, or Jwt must be set — startup validation will fail otherwise.

ZitadelServiceAccount.JwtProfile

Property Type Description
UserId string Service account user ID from the downloaded key JSON
KeyId string Key ID from the downloaded key JSON
Key string? PEM-encoded RSA private key. Required unless SignJwtAsync is set
SignJwtAsync SignJwtAsync? Delegate to offload signing to an external vault

Package Purpose
IT.Legends.Zitadel.Abstractions Shared types, claim constants, and credential models — no external dependencies
IT.Legends.Zitadel.AspNetCore ASP.NET Core authentication middleware (OIDC, OAuth2 introspection, fake auth)
IT.Legends.Zitadel.Clients Generated gRPC clients to access the ZITADEL APIs
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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.5 284 9/10/2026
1.1.4 235 8/22/2026
1.1.3 373 7/18/2026
1.1.2 322 6/22/2026
1.1.1 124 6/22/2026
1.1.0 2,521 4/23/2026
1.0.0 134 4/22/2026