1. Problem Statement
Our Go implementation of eSignet currently has the Userinfo, Authorize, Token endpoints, and Client Registration implemented, but lacks a consent enforcement mechanism to ensure users explicitly grant permission before their PII (Personally Identifiable Information) is shared with Relying Parties (RPs).
The current flow allows authorization codes and tokens to be issued without:
- Collecting explicit user consent for each claim (essential vs voluntary)
- Persisting consent decisions for audit/compliance
- Enforcing that only consented claims are returned in the Userinfo endpoint
This violates OpenID Connect Core Specification §5.5.1 which requires consent enforcement for claims sharing, and creates compliance risks for PII data protection.
2. Goals
- Implement a consent enforcer that intercepts the authorization flow and collects user consent for PII claims before issuing authorization codes
- Differentiate between essential claims (mandatory, user must grant) and voluntary claims (optional, user can skip)
- Persist consent decisions to a database for audit trails and re-use across sessions
- Enforce consent at the Userinfo endpoint to return only claims the user has explicitly granted
- Match the existing eSignet (Java) consent logic to ensure feature parity with the reference implementation
3. Out of Scope (OOS)
- User authentication mechanisms (OTP, biometric, etc.) — assume authentication is already handled by an external identity provider
- Client registration UI — assume clients are registered via the existing Client Registration API
- Consent revocation UI — revoke consent API
- Third-party identity provider integrations — assume a single identity provider backbone exists
- Audit logging infrastructure beyond consent record persistence
- Consent Page UI Implementation — UI rendering will be handled in a separate subtask; this issue focuses on backend logic only
4. Acceptance Criteria
| # |
Criteria |
Verification Method |
| 4.1 |
Authorization request with claims parameter is parsed and essential/voluntary claims are separated |
Unit test parsing {"userinfo":{"name":{"essential":true},"picture":{"essential":false}}} |
| 4.2 |
Consent enforcer correctly validates that all essential claims are granted by user |
Unit test: validation rejects consent if essential claims are missing |
| 4.3 |
Consent decision is persisted to database with client_id, user_id, granted_claims, timestamp |
Unit test: query database after consent submission |
| 4.4 |
Authorization code is issued only after consent is granted |
Unit test: verify code is not issued when consent is denied |
| 4.5 |
Authorization request returns error=consent_denied with redirect_uri when user denies consent |
Unit test: verify error response format per OIDC spec §4.1.2.1 |
| 4.6 |
Userinfo endpoint returns only claims the user granted consent for |
Unit test: query userinfo with access token, verify response matches granted_claims |
| 4.7 |
If user previously granted consent for the same client, consent check skips and authorization code is issued immediately |
Unit test: simulate duplicate authorization request, verify consent skip |
| 4.8 |
Consent record includes essential_only flag to track whether user granted only essential claims or all claims |
Unit test: query consent record, verify essential_only field |
| 4.9 |
Well-known OIDC discovery endpoint (/.well-known/openid-configuration) includes claims_parameter_supported: true |
Manual test: fetch well-known endpoint, verify field |
| 4.10 |
All consent-related API endpoints return proper error codes (400, 401, 403, 500) with OIDC-compliant error messages |
Unit test: verify error response codes and messages |
5. Task Details
Task 1: Add verified_claims support in Thunder
- Needs discussion with Thunder team.
- Do we need verified_claims support right now as there is no identity verification flow yet?
- Does thunder has support for returning verified_claims? Do we need to implement that as well?
- Does UI sdk handles verified_claims for consent?
TBA
Task 2: Encode all claims parameter data in the flow runtime data and pass it to ConsentEnforcer in Thunder.
- How to encode the claims parameter? One string of normalised json?
TBA
Task 3: Add implementation for consent enforcer in eSignet.
TBA
Task 4: Add database migration script for consent changes
TBA
Task 5: Add prompt=consent support in Thunder
- Requesting consent for all claims part is clear but how to store consent need discussion.
Task 6: Add prompt=consent support in eSignet
Task 7: Add Unit Tests
Task 8: Add Integration Tests
Testing Strategy
| Test Type |
Description |
Tools |
| Unit Tests |
Parse claims, validate consent, repository operations |
go test, testify |
| Integration Tests |
Full authorization flow with consent enforcement |
go test, pgtest |
| Manual Tests |
API endpoint behavior verification |
curl, Postman |
| OIDC Compliance Tests |
Verify error responses match OIDC spec |
oidc-test library |
6. Definition of Done
The issue is considered DONE when:
| # |
Criteria |
Verification |
| 6.1 |
All acceptance criteria (Section 4) are met and verified |
QA team validates all 10 criteria |
| 6.2 |
All new files created |
Code review confirms file structure |
| 6.3 |
Database schema migration created and tested |
Migration runs successfully |
| 6.4 |
Unit tests cover all new functions with ≥80% test coverage |
go test -cover shows ≥80% |
| 6.5 |
Integration tests pass for full authorization flow with consent |
Integration test passes |
| 6.6 |
Code passes linting (golangci-lint) without errors |
Lint check OK |
| 6.7 |
Code is reviewed and approved by at least 2 team members |
GitHub PR has 2+ approvals |
| 6.8 |
Code is merged into the main branch |
PR merged to main |
| 6.9 |
Documentation is updated (README, API docs) |
README includes consent flow docs |
| 6.10 |
OIDC well-known endpoint includes claims_parameter_supported: true |
Manual test OK |
| 6.11 |
No breaking changes to existing endpoints |
Existing tests pass |
| 6.12 |
Consent Page UI subtask is created and linked |
GitHub issue reference in PR |
1. Problem Statement
Our Go implementation of eSignet currently has the Userinfo, Authorize, Token endpoints, and Client Registration implemented, but lacks a consent enforcement mechanism to ensure users explicitly grant permission before their PII (Personally Identifiable Information) is shared with Relying Parties (RPs).
The current flow allows authorization codes and tokens to be issued without:
This violates OpenID Connect Core Specification §5.5.1 which requires consent enforcement for claims sharing, and creates compliance risks for PII data protection.
2. Goals
3. Out of Scope (OOS)
4. Acceptance Criteria
claimsparameter is parsed and essential/voluntary claims are separated{"userinfo":{"name":{"essential":true},"picture":{"essential":false}}}client_id,user_id,granted_claims,timestamperror=consent_deniedwithredirect_uriwhen user denies consentessential_onlyflag to track whether user granted only essential claims or all claimsessential_onlyfield/.well-known/openid-configuration) includesclaims_parameter_supported: true5. Task Details
Task 1: Add verified_claims support in Thunder
TBA
Task 2: Encode all claims parameter data in the flow runtime data and pass it to ConsentEnforcer in Thunder.
TBA
Task 3: Add implementation for consent enforcer in eSignet.
TBA
Task 4: Add database migration script for consent changes
TBA
Task 5: Add prompt=consent support in Thunder
Task 6: Add prompt=consent support in eSignet
Task 7: Add Unit Tests
Task 8: Add Integration Tests
Testing Strategy
go test,testifygo test,pgtestoidc-testlibrary6. Definition of Done
The issue is considered DONE when:
go test -covershows ≥80%golangci-lint) without errorsmainclaims_parameter_supported: true