home / skills / stuartf303 / sorcha / jwt
/.claude/skills/jwt
This skill helps secure service-to-service and user authorization by implementing JWT Bearer authentication with shared settings and configurable token types.
npx playbooks add skill stuartf303/sorcha --skill jwtReview the files below or copy the command above to add this skill to your agents.
---
name: jwt
description: |
Implements JWT Bearer authentication for service-to-service and user authorization.
Use when: Configuring authentication, creating authorization policies, issuing/validating tokens, or troubleshooting 401/403 errors.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, mcp__context7__resolve-library-id, mcp__context7__query-docs
---
# 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
```csharp
// 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
```csharp
// 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.
```csharp
// 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.
```csharp
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](references/patterns.md) - Token generation, validation, policies
- [workflows](references/workflows.md) - 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"This skill implements JWT Bearer authentication for service-to-service and user authorization using the Tenant Service as the issuer. It centralizes token validation and shared JwtSettings so all services use a consistent signing key, claims model, and lifetimes. The skill supports user, service, and delegated token types and provides helpers to register authentication and authorization policies in a Sorcha service.
Add the provided AddJwtAuthentication extension to wire up JWT Bearer with the shared JwtSettings. Services call AddBlueprintAuthorization to register common policies. Middleware ordering is critical: the app must call UseAuthentication() before UseAuthorization(). Tokens contain claims like token_type and org_id and are validated with a symmetric signing key (dev auto-generated, production via Key Vault).
What token types are supported and how are they distinguished?
The skill supports user, service, and delegated tokens, distinguished by the token_type claim (e.g., "user" or "service").
How should I store the signing key in production?
Store the HMAC signing key in a secure secret store such as Azure Key Vault and load it into JwtSettings; do not use dev auto-generated keys in production.