Skip to content

Conversation

@leifj
Copy link
Contributor

@leifj leifj commented Nov 25, 2025

This implements OIDC RP support for the issuer. It allows the issuer to create an issue credentials based on an openid authentication flow. The RP is implemented in a way analogous to the SAML SP and support dynamic client registration with OPs

Implements Priority 11 from ROADMAP: OIDC RP integration for issuing
credentials via external OIDC Provider authentication.

Features:
- OAuth2 authorization code flow with PKCE (S256)
- OIDC Provider discovery via .well-known/openid-configuration
- ID token verification (signature, nonce, issuer, audience)
- Session management with automatic expiration
- Protocol-agnostic claim transformation
- Support for Google, Azure AD, Keycloak, and any OIDC provider
- Conditional compilation with -tags oidcrp

Files added:
- pkg/oidcrp/ - Core OIDC RP implementation
  - session.go - Session store with PKCE state management
  - service.go - OIDC provider discovery and OAuth2 flow
  - transformer.go - Claim transformation with dot-notation
  - oidcrp_test.go - Unit tests (7 test cases, all passing)
- internal/apigw/httpserver/ - HTTP endpoints and routing
  - endpoints_oidcrp.go - Initiate and callback endpoints
  - routes_oidcrp.go - Route registration (enabled)
  - routes_oidcrp_disabled.go - Stub routes (disabled)
  - oidcrp_enabled.go - Service type (enabled)
  - oidcrp_disabled.go - Service stub (disabled)
- cmd/apigw/ - Service initialization
  - oidcrp_enabled.go - Init logic (enabled)
  - oidcrp_disabled.go - Init stub (disabled)
- docs/OIDC_RP.md - Comprehensive documentation

Files modified:
- pkg/model/config.go - Added OIDCRPConfig with validation
- internal/apigw/httpserver/service.go - Added oidcrpService field
- cmd/apigw/main.go - Added OIDC RP initialization
- config.yaml - Added configuration examples
- go.mod, go.sum - Added dependencies (go-oidc, oauth2)
- vendor/ - Vendored dependencies

Build verification:
✓ go build -tags=oidcrp ./cmd/apigw/
✓ go build ./cmd/apigw/
✓ go test -tags=oidcrp ./pkg/oidcrp/

Security features:
- PKCE mandatory (S256 method)
- Cryptographic nonce validation
- State parameter for CSRF protection
- ID token signature verification
- Session expiration and cleanup

Note: Integration tests will be added in a follow-up commit.
This commit adds dynamic client registration capability to the OIDC RP
implementation, allowing automatic registration with OIDC Providers that
support RFC 7591.

Changes:
- New dynamic_registration.go: Client-side RFC 7591 implementation
  - DynamicRegistrationClient for performing registration
  - RegistrationRequest/Response structs (RFC 7591 compliant)
  - BuildRegistrationRequest() to convert config to registration format
  - Support for optional initial access tokens (required by Keycloak)

- New cache.go: Credential caching to avoid re-registration
  - CachedCredentials struct for persistence
  - loadCachedCredentials() with expiration checking
  - saveCachedCredentials() with secure 0600 permissions
  - JSON-based storage with configurable path

- Modified service.go: Integration with Service.New()
  - Check for dynamic_registration.enabled flag
  - Load cached credentials or perform new registration
  - Extract registration_endpoint from provider discovery
  - Fallback to static credentials if registration fails

- Modified config.go: Configuration model updates
  - DynamicRegistrationConfig struct (enabled, initial_access_token, storage_path)
  - Made ClientID/ClientSecret optional when dynamic registration enabled
  - Added client metadata fields (client_name, client_uri, logo_uri, etc.)
  - Updated Validate() to require either static OR dynamic credentials

- Updated docs/OIDC_RP.md:
  - New 'Dynamic Client Registration (RFC 7591)' section
  - Provider-specific notes (Google, Azure AD, Keycloak)
  - Configuration examples with/without initial access token
  - Cached credentials format and security notes
  - Fallback to static credentials pattern

- Updated config.yaml:
  - Added commented dynamic registration example configuration
  - Shows client metadata fields usage
  - Demonstrates Keycloak initial_access_token setup

- Tests (14 new test cases, all passing):
  - dynamic_registration_test.go: Registration flow tests
    * BuildRegistrationRequest with full/minimal config
    * Successful registration with mock server
    * Initial access token handling
    * Server error responses
    * Invalid endpoint handling
  - cache_test.go: Credential persistence tests
    * Save/load credentials with proper permissions
    * Expiration checking (expired, no expiration, future expiration)
    * Empty path handling
    * Missing file handling

Test results: 21/21 tests passing (5.037s)
Build verification: Successful with -tags=oidcrp

The implementation reuses RFC 7591 struct definitions from the existing
verifier-proxy server-side implementation to ensure spec compliance.

Providers supported:
- Google: Dynamic registration without initial access token
- Keycloak: Dynamic registration with initial access token
- Azure AD: Does NOT support RFC 7591 (must use static credentials)

Resolves: Enhancement request for dynamic client registration
…piv1

- Refactored pkg/oidcrp/session.go to use ttlcache instead of custom session storage
- Moved OIDC RP business logic from httpserver to apiv1 layer
- Created internal/apigw/apiv1/handlers_oidcrp.go with business logic methods
- Created internal/apigw/apiv1/handlers_oidcrp_stub.go for non-OIDC builds
- Simplified internal/apigw/httpserver/endpoints_oidcrp.go to thin HTTP wrappers
- Updated Apiv1 interface with OIDCRPInitiate and OIDCRPCallback methods

Addresses review comments from masv3971 in PR dc4eu#217
@masv3971 masv3971 merged commit 1162d2e into dc4eu:main Nov 26, 2025
1 check passed
leifj added a commit to sirosfoundation/vc that referenced this pull request Nov 26, 2025
… Credentials API) as completed

- Priority 10: W3C Digital Credentials API Support in Verifier - COMPLETED
  - Full implementation with browser-based flows
  - Enhanced UI and session preference management
  - Documentation in docs/DIGITAL_CREDENTIALS_API.md

- Priority 11: OpenID Connect Relying Party - COMPLETED
  - Complete OIDC RP implementation with PKCE and dynamic registration
  - Layered architecture (httpserver → apiv1 → pkg)
  - Session management with ttlcache
  - Documentation in docs/OIDC_RP.md

Both features merged to main via upstream PRs dc4eu#217 and dc4eu#218
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants