Guardhouse.SDK 1.0.0-beta16

Prefix Reserved
This is a prerelease version of Guardhouse.SDK.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Guardhouse.SDK --version 1.0.0-beta16
                    
NuGet\Install-Package Guardhouse.SDK -Version 1.0.0-beta16
                    
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="Guardhouse.SDK" Version="1.0.0-beta16" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Guardhouse.SDK" Version="1.0.0-beta16" />
                    
Directory.Packages.props
<PackageReference Include="Guardhouse.SDK" />
                    
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 Guardhouse.SDK --version 1.0.0-beta16
                    
#r "nuget: Guardhouse.SDK, 1.0.0-beta16"
                    
#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 Guardhouse.SDK@1.0.0-beta16
                    
#: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=Guardhouse.SDK&version=1.0.0-beta16&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Guardhouse.SDK&version=1.0.0-beta16&prerelease
                    
Install as a Cake Tool

Guardhouse SDK for .NET

Official .NET SDK for https://guardhouse.cloud platform. Use it for .NET clients when you already configured everything in Guardhouse Cloud.

Installation

Install via NuGet:

dotnet add package Guardhouse.SDK

Or via NuGet Package Manager Console:

Install-Package Guardhouse.SDK

Supported Frameworks: .NET 6.0, 7.0, 8.0, 9.0, 10.0

Quick Start

Client Application (Requesting Access Tokens)

Configure your application as a Client to request access tokens:

using Guardhouse.SDK.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGuardhouseClient(options =>
{
    options.Authority = "https://your-guardhouse-server.com";
    options.ClientId = "your-client-id";
    options.ClientSecret = "your-client-secret";
    options.Scope = "api";
    options.EnableTokenCaching = true;
    options.EnableTokenRefresh = true;
});

var app = builder.Build();

// Example: Get access token and call protected API
app.MapGet("/api/call-protected", async (IGuardhouseTokenService tokenService) =>
{
    var accessToken = await tokenService.GetAccessTokenAsync();

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization =
        new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);

    var response = await client.GetAsync("https://protected-api.com/data");
    var data = await response.Content.ReadAsStringAsync();

    return Results.Ok(new
    {
        Response = data,
        AccessTokenPreview = accessToken.Substring(0, Math.Min(20, accessToken.Length)) + "..."
    });
});

app.Run();

Minimal configuration:

builder.Services.AddGuardhouseClient(
    authority: "https://your-guardhouse-server.com",
    clientId: "your-client-id",
    clientSecret: "your-client-secret",
    scope: "api"
);

Resource Server (Protecting APIs)

Configure your API as a Resource to validate incoming tokens:

using Guardhouse.SDK.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGuardhouseResource(options =>
{
    options.Authority = "https://your-guardhouse-server.com";
    options.Audience = "my_resource_api";
    options.ValidationMode = TokenValidationMode.JwtSignature;
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

// Protected endpoint
app.MapGet("/api/protected", [Authorize] () =>
{
    return new { Message = "This is protected data", Timestamp = DateTime.UtcNow };
});

app.Run();

With Token Introspection (RFC 7662):

builder.Services.AddGuardhouseResource(options =>
{
    options.Authority = "https://your-guardhouse-server.com";
    options.Audience = "my_resource_api";
    options.ValidationMode = TokenValidationMode.Introspection;
    options.IntrospectionClientId = "your-introspection-client-id";
    options.IntrospectionClientSecret = "your-introspection-client-secret";
});

Configuration

Client Options

builder.Services.AddGuardhouseClient(options =>
{
    options.Authority = "https://your-guardhouse-server.com";       // Required
    options.ClientId = "your-client-id";                          // Required
    options.ClientSecret = "your-client-secret";                    // Required
    options.Scope = "api";                                        // Default: "api"

    // Optional features
    options.EnableTokenCaching = true;                              // Default: true
    options.CacheExpirationBufferSeconds = 60;                         // Default: 60
    options.EnableTokenRefresh = true;                                // Default: true

    // Resilience
    options.EnableHttpResilience = true;                             // Default: true
    options.RequestTimeoutSeconds = 30;                                // Default: 30
    options.MaxRetryAttempts = 3;                                     // Default: 3
});

Resource Options

builder.Services.AddGuardhouseResource(options =>
{
    options.Authority = "https://your-guardhouse-server.com";       // Required
    options.Audience = "my_resource_api";                        // Required

    // Validation mode: JWT Signature or Introspection
    options.ValidationMode = TokenValidationMode.JwtSignature;    // Default: JWT Signature

    // Required for Introspection mode
    options.IntrospectionClientId = "your-client-id";          // Required for introspection
    options.IntrospectionClientSecret = "your-client-secret";    // Required for introspection

    // Token validation settings
    options.ValidateIssuer = true;                                 // Default: true
    options.ValidateAudience = true;                               // Default: true
    options.ValidateLifetime = true;                                // Default: true
    options.ValidateIssuerSigningKey = true;                        // Default: true

    // JWT validation
    options.ValidAlgorithms = new[] { "RS256" };                 // Default: RS256
    options.TokenTypes = new[] { "JWT" };                          // Default: JWT

    // JWKS caching
    options.JwksCacheDurationHours = 24;                           // Default: 24 hours
    options.JwksRefreshIntervalMinutes = 5;                        // Default: 5 minutes

    // Introspection caching (micro-cache for burst traffic)
    options.IntrospectionCacheTtlSeconds = 5;                     // Default: 5 seconds

    // HTTPS metadata
    options.RequireHttpsMetadata = true;                            // Default: derived from authority
});

Features

Token Management

Automatic Token Caching - Tokens cached in memory with configurable expiration buffer

Automatic Token Refresh - Seamless token renewal using refresh tokens

HTTP Resilience - Built-in retry policies with exponential backoff

Introspection Support - RFC 7662 token introspection for resource servers

Security

Strict Algorithm Enforcement - Only RS256 allowed (prevents algorithm confusion)

Token Type Validation - Validates typ header to prevent type confusion

Comprehensive Validation - Validates issuer, audience, lifetime, and signature

JWKS with Lazy Refresh - Automatic refresh on unknown keys with rate limiting

Embedded Key Protection - Prevents embedded key attacks

Key ID Injection Protection - Prevents path traversal in kid injection

Psychic Signature Protection - Library validates ECDSA signatures correctly

None Algorithm Prevention - Rejects "none" algorithm tokens

Developer Experience

Configuration Validation - Fails fast at startup for missing required settings

Clear Error Messages - Helpful messages for introspection credentials

Dependency Injection - Full .NET DI support with extension methods

Logging Integration - Built-in logging for debugging and monitoring

API Reference

Client Service

public interface IGuardhouseTokenService
{
    Task<string> GetAccessTokenAsync(CancellationToken cancellationToken = default);
    Task<TokenResponse> RequestTokenAsync(CancellationToken cancellationToken = default);
    Task<TokenResponse> RefreshTokenAsync(string refreshToken, CancellationToken cancellationToken = default);
    Task<IntrospectionResponse> IntrospectTokenAsync(string token, CancellationToken cancellationToken = default);
    Task<bool> IsTokenActiveAsync(string token, CancellationToken cancellationToken = default);
}

Resource Service

public interface IGuardhouseResourceService
{
    Task<ClaimsPrincipal?> ValidateTokenAsync(string token, CancellationToken cancellationToken = default);
    Task<IntrospectionResponse> IntrospectTokenAsync(string token, CancellationToken cancellationToken = default);
    Task<AuthenticationScheme?> GetDefaultSchemeAsync(CancellationToken cancellationToken = default);
}

Security Features

Validation Modes

JWT Signature Mode (Default):

  • Uses JWKS endpoint for token validation
  • Automatic key rotation support with lazy refresh
  • Validates signature, issuer, audience, lifetime, algorithm, token type

Introspection Mode (RFC 7662):

  • Validates tokens via Guardhouse introspection endpoint
  • Client credentials required for introspection calls
  • Micro-cache (5 seconds) for burst traffic handling

Protected Attack Vectors

  1. ✅ Validates everything (signature, audience, issuer, lifetime, algorithm, type)
  2. ✅ Strict RS256 enforcement prevents algorithm confusion
  3. ✅ Issuer/audience validation prevents confused deputy attacks
  4. ✅ JWKS library handles embedded key attacks
  5. ✅ Valid algorithms list prevents algorithm confusion
  6. ✅ "none" algorithm prevention
  7. ✅ No fallback between validation methods
  8. ✅ Token type (typ) validation prevents type confusion
  9. ✅ Library prevents key ID injection (path traversal)
  10. ✅ Library validates ECDSA/psychic signatures correctly

JWKS Caching with Lazy Refresh

The SDK implements "Lazy Refresh on Unknown Key" strategy:

  1. Extract kid (Key ID) from incoming JWT token header
  2. Check local cache for key
  3. If key exists: Validate signature (fast path)
  4. If key missing: Trigger JWKS refresh from /.well-known/jwks.json
  5. Rate limit refresh (configurable, default 5 minutes)
  6. Re-check cache and validate with new keys

This ensures your API accepts valid tokens even after key rotation, while protecting against DoS attacks via rate limiting.

Introspection Micro-Cache Strategy

The SDK implements a micro-cache for introspection results:

  • Default TTL: 5 seconds
  • Purpose: Handles burst traffic (e.g., page loads with multiple API calls)
  • Security: Maintains near-real-time revocation security by rapidly refreshing
  • Trade-off: Minimal delay (5 seconds) vs. significant performance improvement for burst scenarios

Use introspection mode when you need real-time token revocation checking, but be aware of the network request overhead.

Examples

Calling Protected APIs

public class ExternalApiService
{
    private readonly IGuardhouseTokenService _tokenService;

    public ExternalApiService(IGuardhouseTokenService tokenService)
    {
        _tokenService = tokenService;
    }

    public async Task<string> CallProtectedEndpoint()
    {
        var accessToken = await _tokenService.GetAccessTokenAsync();

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);

        var response = await client.GetAsync("https://protected-api.com/data");
        return await response.Content.ReadAsStringAsync();
    }
}

Protecting Endpoints

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult GetAll()
    {
        return Ok(new[] { "Product 1", "Product 2" });
    }

    [HttpPost]
    [Authorize]
    public IActionResult Create([FromBody] CreateProductRequest request)
    {
        return CreatedAtAction(nameof(GetById), new { id = 1 }, request);
    }

    [HttpDelete("{id}")]
    [Authorize]
    public IActionResult Delete(int id)
    {
        return Ok(new { Message = $"Product {id} deleted" });
    }
}

Authorization Policies

builder.Services.AddAuthorization(options =>
{
    // Require specific scope
    options.AddPolicy("ReadAccess", policy =>
        policy.RequireClaim("scope", "read"));

    // Require admin role
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireRole("admin"));

    // Require multiple conditions
    options.AddPolicy("CanManage", policy =>
        policy.RequireClaim("scope", "manage")
              .RequireRole("manager"));
});

[HttpGet("admin")]
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminEndpoint()
{
    return Ok("Admin data");
}

Dependencies

  • .NET 6.0 or later (supports .NET 6.0, 7.0, 8.0, 9.0, 10.0)
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Http
  • Microsoft.Extensions.Http.Polly
  • Microsoft.Extensions.Caching.Memory
  • Microsoft.Extensions.Options
  • Microsoft.AspNetCore.Authentication.JwtBearer
  • System.IdentityModel.Tokens.Jwt
  • System.Text.Json
  • NodaTime
  • Polly

Troubleshooting

Configuration Errors

Error: "IntrospectionClientId is required when ValidationMode is set to Introspection"

Add introspection credentials to your configuration:

builder.Services.AddGuardhouseResource(options =>
{
    options.ValidationMode = TokenValidationMode.Introspection;
    options.IntrospectionClientId = "your-client-id";
    options.IntrospectionClientSecret = "your-client-secret";
});

Token Validation Issues

Error: "401 Unauthorized"

  1. Verify your Guardhouse credentials are correct
  2. Check that Authority URL matches your Guardhouse instance
  3. Ensure client is enabled in Guardhouse Cloud
  4. Verify token hasn't expired

JWKS Refresh Issues

Error: "kid not found" or signature validation fails

  1. Check your Authority URL is correct
  2. Verify Guardhouse server is accessible
  3. Check that JwksRefreshIntervalMinutes is appropriate (default 5)
  4. Check application logs for JWKS refresh errors

Documentation

License

Licensed under Apache License 2.0

Support

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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.0.3 123 5/27/2026
1.0.2 584 4/24/2026
1.0.1 398 3/2/2026
1.0.0 339 2/20/2026
1.0.0-beta17 289 1/4/2026
1.0.0-beta16 126 1/4/2026
1.0.0-beta15 120 1/2/2026
1.0.0-beta14 117 1/2/2026
1.0.0-beta1 122 1/2/2026

1.0.0-beta13 - beta release of Guardhouse SDK for .NET.

           Features:
           - JWT signature validation with JWKS caching and lazy refresh (RFC 7515)
           - Token introspection support (RFC 7662)
           - Comprehensive security validations (algorithm, token type, issuer, audience, lifetime)
           - Configurable validation modes (JWT Signature or Introspection)
           - Client credentials flow support with automatic token refresh
           - HTTP resilience and retry policies with Polly
           - Configuration validation with clear error messages
           - Support for .NET 6.0, 7.0, 8.0, 9.0, and 10.0
           - Protection against 10+ JWT security attack vectors