feat: implement scope-based audience mapping and RFC 9728 support

This commit removes hardcoded Keycloak audience mappers and implements
dynamic audience assignment based on OAuth client scopes and RFC 8707
resource indicators.

## MCP Server Changes

### Protected Resource Metadata (app.py)
- Change resource field from client_id to URL (RFC 9728 compliance)
- Use `{mcp_server_url}/mcp` as resource identifier
- Update DCR registration to include all Nextcloud API scopes
- Add resource_url parameter to client registration

### Client Registration (auth/client_registration.py)
- Add resource_url parameter to register_client()
- Pass resource_url to DCR endpoint
- Support RFC 9728 resource metadata

### Browser OAuth Routes (auth/browser_oauth_routes.py)
- Enhanced error logging for token exchange failures
- Log HTTP status code and response body for debugging
- Improved error messages for OAuth provisioning issues

### Token Verifier (auth/progressive_token_verifier.py)
- Add introspection_uri and client_secret parameters
- Initialize HTTP client for introspection requests
- Enable opaque token validation support

## Keycloak Configuration

### realm-export.json
- **Remove** hardcoded `audience-mcp-server` protocol mapper
- Audience now determined by client scopes:
  - External clients: RFC 8707 resource parameter → `aud: {resource_url}`
  - MCP Server: `token-exchange-nextcloud` scope → `aud: "nextcloud"`

### OIDC App (third_party/oidc)
- Updated submodule with RFC 9728 support
- Added resource_url database field
- Enhanced introspection authorization logic

## Architecture

Two separate audience flows:

1. **Gemini CLI → MCP Server**
   - Client requests: `resource=http://localhost:8002/mcp`
   - Token audience: `aud: "http://localhost:8002/mcp"`
   - MCP server validates via progressive_token_verifier

2. **MCP Server → Nextcloud APIs**
   - MCP server includes: `scope=token-exchange-nextcloud`
   - Token audience: `aud: "nextcloud"` (via scope mapper)
   - Nextcloud user_oidc validates via SelfEncodedValidator

## Benefits
-  RFC 8707 compliant (resource indicators)
-  RFC 9728 compliant (protected resource metadata)
-  Dynamic audience based on OAuth context
-  Fixes Gemini CLI authentication failures
-  Maintains Nextcloud API access for background jobs
-  Clear security boundaries between flows

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2025-11-04 05:28:58 +01:00
parent 10dffd0c10
commit de99296779
6 changed files with 207 additions and 28 deletions
-11
View File
@@ -229,17 +229,6 @@
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"protocolMappers": [
{
"name": "audience-mcp-server",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-mapper",
"consentRequired": false,
"config": {
"included.custom.audience": "nextcloud-mcp-server",
"access.token.claim": "true",
"id.token.claim": "false"
}
},
{
"name": "sub",
"protocol": "openid-connect",