jwt

SKILL.md

JWT Authentication Skill

Sorcha uses JWT Bearer authentication with the Tenant Service as the token issuer. All services validate tokens using shared JwtSettings from Sorcha.ServiceDefaults. Tokens support three types: user (email/password), service (client credentials), and delegated (service acting on behalf of user).

Quick Start

Service Authentication Setup

// Program.cs - Any Sorcha service
var builder = WebApplication.CreateBuilder(args);

// 1. Add JWT authentication (shared key auto-generated in dev)
builder.AddJwtAuthentication();

// 2. Add service-specific authorization policies
builder.Services.AddBlueprintAuthorization();

var app = builder.Build();

// 3. CRITICAL: Order matters!
app.UseAuthentication();
app.UseAuthorization();

app.MapBlueprintEndpoints();
app.Run();

Protect an Endpoint

// Minimal API pattern
group.MapPost("/", CreateBlueprint)
    .WithName("CreateBlueprint")
    .RequireAuthorization("CanManageBlueprints");

Key Concepts

Concept Usage Example
Token Types Differentiate user vs service token_type claim: "user" or "service"
Organization Scope Isolate tenant data org_id claim in token
Signing Key Symmetric HMAC-SHA256 Auto-generated in dev, Azure Key Vault in prod
Token Lifetime Configurable per type Access: 60min, Refresh: 24hr, Service: 8hr

Common Patterns

Custom Authorization Policy

When: Endpoint requires specific claims beyond role-based auth.

// AuthenticationExtensions.cs
options.AddPolicy("CanManageBlueprints", policy =>
    policy.RequireAssertion(context =>
    {
        var hasOrgId = context.User.Claims.Any(c => c.Type == "org_id" && !string.IsNullOrEmpty(c.Value));
        var isService = context.User.Claims.Any(c => c.Type == "token_type" && c.Value == "service");
        return hasOrgId || isService;
    }));

Extract Claims in Handler

When: Need user/org context in endpoint logic.

async Task<IResult> HandleRequest(ClaimsPrincipal user, ...)
{
    var userId = user.FindFirst(JwtRegisteredClaimNames.Sub)?.Value;
    var orgId = user.FindFirst("org_id")?.Value;
    
    if (string.IsNullOrEmpty(orgId))
        return Results.Forbid();
    
    // Use orgId for data isolation
}

See Also

  • patterns - Token generation, validation, policies
  • workflows - Setup, testing, troubleshooting

Related Skills

  • See the minimal-apis skill for endpoint configuration with .RequireAuthorization()
  • See the aspire skill for shared configuration via ServiceDefaults
  • See the redis skill for token revocation tracking
  • See the yarp skill for gateway-level authentication

Documentation Resources

Fetch latest JWT/authentication documentation with Context7.

How to use Context7:

  1. Use mcp__context7__resolve-library-id to search for "asp.net core authentication jwt"
  2. Prefer website documentation (IDs starting with /websites/) over source code repositories
  3. Query with mcp__context7__query-docs using the resolved library ID

Recommended Queries:

  • "JWT Bearer authentication setup"
  • "authorization policies claims"
  • "token validation parameters"
Weekly Installs
23
First Seen
Jan 27, 2026
Installed on
cursor23
gemini-cli22
opencode21
codebuddy21
github-copilot21
codex21