Skip to content

Commit 7ec509e

Browse files
committed
chore: Adds CLAUDE.md and AGENTS.md
1 parent cc6350f commit 7ec509e

8 files changed

Lines changed: 364 additions & 165 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,5 @@
1-
# Auth0 ASP.NET Core API - AI Agent Instructions
1+
# AI Agent Guidelines for Auth0.AspNetCore.Authentication.Api
22

3-
This is an **Auth0 authentication SDK** for ASP.NET Core APIs providing **JWT Bearer authentication with DPoP (Demonstration of Proof-of-Possession) support**. It wraps `Microsoft.AspNetCore.Authentication.JwtBearer` with Auth0-specific configuration and RFC 9449 DPoP validation.
3+
See @CLAUDE.md for all coding guidelines, commands, project structure, code style, testing conventions, and boundaries.
44

5-
## Architecture Overview
6-
7-
### Core Design Pattern: Fluent Builder with Extension Point
8-
- **Entry**: `ServiceCollectionExtensions.AddAuth0ApiAuthentication()` → returns `Auth0ApiAuthenticationBuilder`
9-
- **DPoP**: Optional via `builder.WithDPoP()` - adds validation services and event handlers
10-
- **Options**: `Auth0ApiOptions` wraps `JwtBearerOptions` + `Domain`; `DPoPOptions` configures DPoP behavior
11-
- **Validation Pipeline**: JWT Bearer events → DPoP event handlers (MessageReceived, TokenValidation, Challenge) → `DPoPProofValidationService`
12-
13-
### Key Components
14-
- **`src/Auth0.AspNetCore.Authentication.Api/`**: Main library
15-
- `ServiceCollectionExtensions.cs`: Primary API surface - `AddAuth0ApiAuthentication()`
16-
- `AuthenticationBuilderExtensions.cs`: DPoP enablement via `.WithDPoP()`, internal JWT Bearer setup
17-
- `Auth0ApiAuthenticationBuilder.cs`: Fluent builder returned from setup methods
18-
- **`DPoP/`**: Complete RFC 9449 implementation
19-
- `DPoPProofValidationService.cs`: Core validation logic (JWK extraction, signature, claims, thumbprint binding)
20-
- `EventHandlers/`: Intercept JWT Bearer events to inject DPoP validation
21-
- `DPoPOptions.cs`: Mode (`Allowed`/`Required`/`Disabled`), timing (`IatOffset`, `Leeway`)
22-
23-
### DPoP Enforcement Modes
24-
1. **Allowed** (default): Accept both Bearer and DPoP tokens - enables gradual migration
25-
2. **Required**: Reject Bearer tokens, only accept DPoP - strict security
26-
3. **Disabled**: Standard JWT Bearer only
27-
28-
## Development Workflows
29-
30-
### Building
31-
```bash
32-
dotnet restore Auth0.AspNetCore.Authentication.Api.sln
33-
dotnet build Auth0.AspNetCore.Authentication.Api.sln --configuration Release
34-
```
35-
36-
### Testing
37-
```bash
38-
# Unit tests (mocks, no Auth0 connection)
39-
dotnet test tests/Auth0.AspNetCore.Authentication.Api.UnitTests/
40-
41-
# Integration tests (requires Auth0 environment variables - see .github/workflows/build.yml for required secrets)
42-
dotnet test tests/Auth0.AspNetCore.Authentication.Api.IntegrationTests/
43-
```
44-
45-
**Integration test pattern**: `TestWebApplicationFactory` creates TestServer → `Auth0TokenHelper` obtains real tokens → `DPoPHelper` generates DPoP proofs with EC keys
46-
47-
### Playground Testing
48-
```bash
49-
cd Auth0.AspNetCore.Authentication.Api.Playground
50-
# Configure Auth0:Domain and Auth0:Audience in appsettings.json
51-
dotnet run
52-
# Open https://localhost:7190/swagger
53-
```
54-
Use `Auth0.AspNetCore.Authentication.Api.Playground.postman_collection.json` for pre-configured API calls
55-
56-
### Documentation Generation
57-
```bash
58-
./build-docs.sh # Builds project + runs docfx
59-
# View: sudo docfx serve docs → http://localhost:8080
60-
```
61-
62-
## Critical Patterns & Conventions
63-
64-
### Options Configuration Pattern
65-
```csharp
66-
// ALWAYS use this pattern - Auth0ApiOptions wraps JwtBearerOptions
67-
builder.Services.AddAuth0ApiAuthentication(options =>
68-
{
69-
options.Domain = "tenant.auth0.com"; // NO https:// prefix
70-
options.JwtBearerOptions = new JwtBearerOptions
71-
{
72-
Audience = "https://api-identifier",
73-
// Any standard JWT Bearer option works here
74-
};
75-
});
76-
```
77-
78-
### DPoP Header Validation Flow
79-
1. **MessageReceived** event: Extract DPoP proof from `DPoP` header, access token from `Authorization: DPoP <token>`
80-
2. **TokenValidated** event: Call `DPoPProofValidationService.ValidateAsync()` with `DPoPProofValidationParameters`
81-
3. **Validation checks**: JWK extraction → signature verification → `cnf` claim thumbprint match → `htm`/`htu`/`iat` claim validation
82-
4. **Challenge** event: Add `DPoP` to `WWW-Authenticate` on 401 failures
83-
84-
### Event Handler Chaining
85-
DPoP events **wrap** user-defined `JwtBearerEvents`. Example in `DPoPEventsFactory.Create()`:
86-
```csharp
87-
// Preserve user's custom event, execute DPoP handler first
88-
Events.OnMessageReceived = async context => {
89-
await dpopHandler.HandleMessageReceived(context);
90-
if (userEvents?.OnMessageReceived != null)
91-
await userEvents.OnMessageReceived(context);
92-
};
93-
```
94-
95-
### Error Handling Convention
96-
- DPoP errors use `Auth0Constants.DPoP.Error.Code.*` (e.g., `invalid_dpop_proof`, `invalid_request`)
97-
- Always fail request with `context.Fail()` + descriptive error in `DPoPProofValidationResult`
98-
- Log errors via `ILogger<T>` at ERROR level for failed validations
99-
100-
## Testing Guidelines
101-
102-
### Unit Tests
103-
- Use xUnit `[Fact]` and `[Theory]`
104-
- Mock `IDPoPProofValidationService` for event handler tests
105-
- Test each DPoP validator independently (see `DPoPProofValidationService.cs` internal methods)
106-
107-
### Integration Tests
108-
- Inherit from `IAsyncLifetime` for test setup/teardown
109-
- Use `Auth0Scenario` enum to configure different test environments (Basic, DPoPAllowed, DPoPRequired)
110-
- **Never hardcode tokens** - use `Auth0TokenHelper.GetClientCredentialsTokenAsync()` with environment variables
111-
- DPoP tests must create real EC keys: `ECDsa.Create(ECCurve.NamedCurves.nistP256)`
112-
113-
## Common Pitfalls
114-
115-
1. **Domain format**: Must be `tenant.auth0.com` NOT `https://tenant.auth0.com` - code auto-prepends `https://`
116-
2. **InternalsVisibleTo**: Tests access internal validators - declared in `.csproj` `<InternalsVisibleTo>`
117-
3. **DPoP mode confusion**: `Allowed` mode validates DPoP IF present, `Required` mode rejects Bearer tokens entirely
118-
4. **Event preservation**: When modifying `AuthenticationBuilderExtensions.cs`, ALWAYS preserve existing user events via `JwtBearerEventsFactory.CreateBaseEvents()`
119-
5. **Token validation timing**: Use `IatOffset` (default 300s) for clock skew, `Leeway` (default 30s) for lifetime checks
120-
121-
## File Organization
122-
123-
```
124-
src/Auth0.AspNetCore.Authentication.Api/
125-
├── ServiceCollectionExtensions.cs # IServiceCollection.AddAuth0ApiAuthentication()
126-
├── AuthenticationBuilderExtensions.cs # AuthenticationBuilder.AddAuth0ApiAuthentication(), .WithDPoP()
127-
├── Auth0ApiAuthenticationBuilder.cs # Fluent builder
128-
├── Auth0ApiOptions.cs # Domain + JwtBearerOptions wrapper
129-
├── Auth0JwtBearerPostConfigureOptions.cs # IPostConfigureOptions - sets Authority from Domain
130-
└── DPoP/
131-
├── DPoPProofValidationService.cs # Core RFC 9449 implementation
132-
├── DPoPOptions.cs # Mode, IatOffset, Leeway
133-
├── DPoPEventHandlers.cs # Coordinates MessageReceived, TokenValidated, Challenge
134-
└── EventHandlers/ # Individual event handler implementations
135-
```
136-
137-
## Auth0-Specific Behaviors
138-
139-
- **Authority construction**: Automatically creates `https://{Domain}` from `options.Domain`
140-
- **Audience validation**: Uses standard JWT Bearer audience validation (not Auth0-specific)
141-
- **Scope claims**: Auth0 includes scopes in `scope` claim as space-separated string (see `EXAMPLES.md`)
142-
- **DPoP support**: Auth0 DPoP tokens have `cnf.jkt` claim with JWK thumbprint (SHA-256 of public key)
143-
144-
## When Modifying Code
145-
146-
### Adding New DPoP Validators
147-
1. Create internal method in `DPoPProofValidationService.cs`
148-
2. Call from `ValidateAsync()` pipeline
149-
3. Set errors via `result.SetError(code, description)` using constants from `Auth0Constants.DPoP.Error`
150-
4. Add unit tests in `Auth0.AspNetCore.Authentication.Api.UnitTests`
151-
152-
### Changing DPoP Modes
153-
- Update `DPoPModes` enum
154-
- Modify `MessageReceivedHandler.cs` and `TokenValidationHandler.cs` switch statements
155-
- Add mode-specific tests in `tests/Auth0.AspNetCore.Authentication.Api.IntegrationTests/`
156-
157-
### Package Updates
158-
- Version in `Directory.Build.props` (`<VersionPrefix>`)
159-
- Release notes URL in `Auth0.AspNetCore.Authentication.Api.csproj` (`<PackageReleaseNotes>`)
160-
- Target framework is .NET 8.0+ only (no multi-targeting)
161-
162-
## Key Files for Understanding Features
163-
164-
- **Migration scenarios**: `MIGRATION.md` - 8 before/after examples
165-
- **Usage patterns**: `EXAMPLES.md` - 16 copy-paste scenarios
166-
- **DPoP validation**: `src/Auth0.AspNetCore.Authentication.Api/DPoP/DPoPProofValidationService.cs` (515 lines)
167-
- **Setup flow**: `src/Auth0.AspNetCore.Authentication.Api/AuthenticationBuilderExtensions.cs:ConfigureJwtBearerOptions()`
5+
This file exists so that non-Claude AI agents (Codex CLI, Gemini CLI, etc.) read the same instructions. All guidelines are maintained in a single place (`CLAUDE.md`) to avoid duplication and drift.

0 commit comments

Comments
 (0)