code
Clone this repository
https://tangled.org/bretton.dev/coves
git@knot.bretton.dev:bretton.dev/coves
For self-hosted knots, clone URLs may differ based on your setup.
The latest indigo (Nov 27, 2025) requires Go 1.25 which isn't available
in Docker Hub yet. Pin to the Oct 10, 2025 commit which is the last
Go 1.24-compatible version.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The local Go 1.25.1 is a pre-release version not available in Docker Hub.
Set minimum go version to 1.24 with toolchain directive for local dev.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement DPoP (RFC 9449) token binding for OAuth access tokens.
Features:
- DPoP proof verification with ES256 signing
- NonceCache for jti-based replay protection
- JWK thumbprint calculation per RFC 7638
- Middleware integration with Stop() for clean shutdown
- X-Forwarded-Proto support for reverse proxy deployments
Security:
- DPoP is additional security, never a fallback
- Tokens with cnf.jkt require valid DPoP proof
- 5-minute proof validity window
- Replay attack prevention via jti tracking
- Add github.com/google/uuid for DPoP proof jti generation
- Add .cache/ to .gitignore for Go build cache
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Document DPoP token binding implementation:
- Explain DPoP security model and why it's not a fallback
- Add flow diagrams for DPoP verification process
- Document replay protection with NonceCache
- Add code examples for DPoP verification
- List implemented security features and future enhancements
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
JWT improvements:
- Add Confirmation field for DPoP cnf.jkt claim binding
- Reorder Claims struct fields for optimal memory alignment
Test improvements:
- Replace os.Setenv/os.Unsetenv with t.Setenv for cleaner tests
- Use t.Cleanup for automatic environment restoration
- Use UUID for DPoP proof jti to ensure test uniqueness
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhance AtProtoAuthMiddleware with DPoP token binding support:
- Add Stop() method to prevent goroutine leaks on shutdown
- Require DPoP proof when token has cnf.jkt claim
- Treat DPoP-bound tokens without proof as unauthenticated in OptionalAuth
- Honor X-Forwarded-Proto header for URI verification behind proxies
Security model:
- DPoP is ADDITIONAL security, never a fallback for failed verification
- Token signature must be verified BEFORE checking DPoP binding
- Missing DPoP proof for bound tokens results in rejection
Tests added for:
- Middleware Stop() cleanup
- OptionalAuth with DPoP-bound tokens
- X-Forwarded-Proto handling
- DPoP replay protection integration
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add proof-of-possession verification for OAuth access tokens:
- DPoPVerifier for validating DPoP proof JWTs
- NonceCache for replay attack prevention with background cleanup
- JWK thumbprint calculation per RFC 7638
- Support for ES256 signing algorithm
- Configurable clock skew and proof age limits
Security features:
- Validates htm (HTTP method) and htu (HTTP URI) claims
- Enforces iat freshness within 5-minute window
- Tracks jti values to prevent proof reuse
- Calculates and validates JWK thumbprints for token binding
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add ES256 federation support and JWT config caching:
- DID-based key fetcher for verifying tokens from any PDS
- O(1) issuer whitelist lookups with cached config
- Environment configuration documentation
馃 Generated with [Claude Code](https://claude.com/claude-code)
Document the dual JWT verification methods (HS256 + ES256) in environment
configuration files:
- HS256: For your own PDS (fast, shared secret, no network calls)
- ES256: For federated users (DID resolution, works with any PDS)
Updates:
- .env.dev: Add HS256_ISSUERS for local development
- .env.prod.example: Add JWT Authentication section with documentation
- docker-compose.prod.yml: Pass PDS_JWT_SECRET and HS256_ISSUERS to appview
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Cache HS256_ISSUERS, PDS_JWT_SECRET, and IS_DEV_ENV at startup instead
of reading environment variables on every token verification request.
- Add jwtConfig struct with sync.Once initialization
- Use map[string]struct{} for O(1) issuer whitelist lookups
- Add InitJWTConfig() for explicit startup initialization
- Add ResetJWTConfigForTesting() for test isolation
- Update main.go to call InitJWTConfig() at startup
Before: 2-3 os.Getenv() calls + O(n) string iteration per request
After: Single pointer dereference + O(1) map lookup per request
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>