Skip to content

eSignet<>Thunder: Implement the consent enforcer in eSignet in Golang #1976

@rachik-hue

Description

@rachik-hue

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

Metadata

Metadata

Assignees

Labels

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions