EasyAccess (EA) Consent Issuer – Developer Guide
Quick Navigation
This developer guide covers EA Consent Issuer API integration in 9 sections:
- Getting Started (1-2): Overview and integration flow
- API Operations (3): Self-contained operation reference (endpoints, request/response formats)
- Infrastructure (4-6): Monitoring, security, error handling
- Testing & Context (7-9): Debug tools, related components, versioning
New to EA Consent Issuer? Start with sections 1-3 to understand the basics. Each operation in section 3 is self-contained—everything you need for that endpoint is in one place.
Table of Contents
- EasyAccess (EA) Consent Issuer – Developer Guide
- Quick Navigation
- Audience and Assumptions
- 1. Overview
- 2. Integration Flow
- 3. API Operations
- 4. Monitoring Endpoints
- 5. Security & Authorization
- 6. Error Handling
- 7. Debug & Testing
- 8. Related Components
- 9. Versioning & Compatibility
- Additional Resources
Audience and Assumptions
This guide is for application developers who need to integrate with the EA Consent Issuer API.
Assumptions:
- You are developing an application that captures user consent and you want to be able to share them into the Privacy Network.
- You have access to a running EA Consent Issuer instance (URL and credentials provided by your administrator)
- You are not responsible for deploying or administering the EA Consent Issuer service
What you’ll learn:
- How to call the EA Consent Issuer APIs to issue EasyAccess Consents that are wrapped in Trust Blocks.
- Request and response formats for single and batch consent submission
- Error handling and debugging techniques
- How to verify the signatures of Trust Blocks and EA Consents
1. Overview
The EA Consent Issuer mints EasyAccess Consent credentials as W3C Verifiable Credentials (v2.0) and wraps them in Trust Block credentials (also W3C VCs v2.0) for sharing into the Privacy Network. From a developer’s perspective:
Input: You provide simplified EasyAccess Consent JSON with subject identity, consent decision, and optional evidence.
Processing: The service validates your input, generates all required identifiers, builds the full W3C VC 2.0 EA Consent and Trust Block structure, and signs the credential as a JWT.
Output: You receive a signed Trust Block JWT containing the EasyAccess Consent VC, ready to store or forward to downstream services like the EA Consent Delta Writer.
Key benefit: You don’t need to understand W3C VC structures, the complte EA Consent and Trust Block formats, or JWT signing—the service handles all standards compliance automatically.
2. Integration Flow
The EA Consent Issuer fits into the Privacy Network flow as a transformation layer between partner application consent formats and EA Consent and Trust Block formats.
Prerequisite: This guide assumes you’ve completed Phase 1 - adding EasyAccess consent language to your application. Your app is already capturing and storing consent data. This API is used in Phase 2 when you’re ready to publish those consents to the Privacy Network.
Phase 1: Consent Capture (Your Application - Already Complete)
Your application has already:
- Added EasyAccess consent language to your consent flows
- Captured user consents with the required EasyAccess language
- Stored consent data in your database
Phase 2: Privacy Network Publishing (This Guide)
1. Your Application
└─> Retrieves stored consent data from your database
2. EA Consent Issuer (This Service)
└─> Mints EA Consent VC and wraps it in a Trust Block (JWT)
3. EA Consent Delta Writer
└─> Receives Trust Block JWT
└─> Decodes, validates, and transforms into EA Consent Delta Sharing schema
└─> Writes to Delta tables: ea-consent-tb, ea-consent-verification-keys
4. Delta Sharing Server (External)
└─> Serves Delta tables via Delta Sharing protocol
└─> Authorized consumers query consent records and verify signatures using verification keys
Phase 2 workflow for developers:
When you’re ready to publish stored consents to the Privacy Network:
- Retrieve stored consent data from your database (captured during Phase 1)
- Build EA Consent Input JSON from your stored consent data (subject identity, consent decision, policies, evidence)
- POSTs EA Consent Input JSON to the EA Consent Issuer API endpoint
- Service validates input against JSON schema and business rules
- Service generates EA Consents and Trust Blocks with all required IDs and formatting
- Service signs credential as JWT and wraps it in a Trust Block (outer JWT)
- Service returns Trust Block JWT in the response (the credential you’ll use)
- Handle responses - check for success/partial success and process any errors
- Retry failed request if needed (based on error codes)
- Your app stores or forwards the Trust Block to downstream services (e.g., EA Consent Delta Writer for Privacy Network queries)
Trust Block Architecture:
The response contains a nested JWT structure:
- Outer JWT (Trust Block): Wraps the EA Consent VC and documents privacy operations
- Inner JWT (EA Consent VC): The original consent credential
Both JWTs are independently signed and can be verified separately. The Trust Block provides a layer for future privacy transformations while maintaining the integrity of the original consent.
3. API Operations
All API endpoints are prefixed with /ea-consent-issuer/api/v2 by default. If your administrator has configured a custom_uri_prefix, all paths will be prefixed with that value (e.g., /custom1/ea-consent-issuer/api/v2/consents).
3.1 Issue Single Consent
Issue a single EA Consent credential wrapped in a Trust Block.
Endpoint
| Method | Path | Auth |
|---|---|---|
POST |
/ea-consent-issuer/api/v2/consents |
🔒 |
🔒 Requires Authorization: Bearer <token> header (see Section 5: Security & Authorization)
Request Body
The EA Consent Issuer accepts the EA Consent Input Schema, a simplified, developer-friendly JSON format that abstracts away the complexity of the complete EA Consent, Trust Blocks, and W3C Verifiable Credentials.
Full Schema Documentation: See the EA Consent Input Data Model for complete field specifications, validation rules, and examples.
Content Type: application/json
Quick Reference
| Section | Required | Description |
|---|---|---|
subject |
Yes | Subject identity information and internal subject ID |
consent |
Yes | Consent decision and policy details |
evidence |
Yes | Supporting evidence for identity verification |
captured_by |
No | Optional provenance information about who captured the consent |
Minimal Example
{
"subject": {
"id": "user-123"
},
"consent": {
"agreed": true,
"summary_html": "I agree to the privacy policy",
"details_html": "<p>I agree to the privacy policy and terms of service.</p>",
"contains_ppn_consent": false
},
"evidence": [
{
"type": "AuthenticationEvidence",
"id_token": "eyJhbG...",
"verifies": ["email"]
}
]
}
For complete examples including batch requests, opt-out consents, and full field specifications, see the EA Consent Input Data Model.
Best Practice: Store the Trust Block JWT
Always store the returned trust_block JWT - this is the complete, signed, verifiable credential. You can verify it later using the issuer’s public key.
Response
Success Response (201 Created)
When you successfully submit consent, the service returns:
{
"trust_block": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"result": {
"status": "success",
"http_status": 201,
"trust_block_id": "https://issuer.example.org/trust-blocks/550e8400-e29b-41d4-a716-446655440000",
"consent_vc_id": "https://issuer.example.org/credentials/85389cfb-75c5-434e-b2e6-651fc75a6ae5",
"person_vc_id": "https://issuer.example.org/credentials/f3e4d5c6-b7a8-49d0-a1e2-f3a4b5c6d7e8",
"subject_id": "https://issuer.example.org/subjects/a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"created_at": "2025-11-13T15:30:00Z",
"warnings": []
},
"request_id": "req_01HGAF9P9KTYMZCJXCK6NZXQFD"
}
Response Fields
| Field | Description |
|---|---|
trust_block |
Primary credential to share. The compact JWT string of the signed Trust Block (outer credential) that wraps both the EA Consent VC and EA Person VC. This is what you’ll store or forward to downstream services. |
result.status |
Operation result (always "success" for 201 responses) |
result.http_status |
HTTP status code (always 201 for successful creation) |
result.trust_block_id |
Unique identifier for the Trust Block (outer credential) |
result.consent_vc_id |
Unique identifier for the EA Consent VC (first inner credential) |
result.person_vc_id |
Unique identifier for the EA Person VC (second inner credential) |
result.subject_id |
Credential subject identifier |
result.created_at |
ISO 8601 timestamp when the credential was issued |
result.warnings |
Array of non-fatal warnings (empty array if none) |
request_id |
Unique request identifier for tracking and log correlation |
What to Do with the Trust Block
The trust_block field contains the complete signed credential ready to use. You should:
- Store it in your database associated with the user/transaction
- Forward it to downstream services (e.g., EA Consent Delta Writer)
- Verify it if needed using the verification keys endpoints
Do not modify the Trust Block JWT—it’s cryptographically signed and any changes will break the signature.
3.2 Issue Batch Consents
Process multiple consents in a single request (1-50 items).
Endpoint
| Method | Path | Auth |
|---|---|---|
POST |
/ea-consent-issuer/api/v2/consent-batches |
🔒 |
🔒 Requires Authorization: Bearer <token> header (see Section 5: Security & Authorization)
Request Body
The batch endpoint accepts an array of consents, each following the same schema as the single consent operation (see Section 3.1), wrapped with a client_reference_id for correlation:
{
"consents": [
{
"client_reference_id": "your-reference-001",
"consent": {
"subject": { ... },
"consent": { ... },
"evidence": [ ... ]
}
},
{
"client_reference_id": "your-reference-002",
"consent": { ... }
}
]
}
client_reference_id: Your own identifier for correlating results with input itemsconsent: The full consent object as documented in Section 3.1
Response
When submitting multiple consents, you receive:
{
"trust_blocks": [
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
],
"results": [
{
"client_reference_id": "ref-001",
"status": "success",
"http_status": 201,
"trust_block_id": "https://issuer.example.org/trust-blocks/...",
"consent_vc_id": "https://issuer.example.org/credentials/...",
"person_vc_id": "https://issuer.example.org/credentials/...",
"subject_id": "https://issuer.example.org/subjects/...",
"created_at": "2025-11-13T15:30:00Z",
"warnings": []
},
{
"client_reference_id": "ref-002",
"status": "success",
"http_status": 201,
"trust_block_id": "https://issuer.example.org/trust-blocks/...",
"consent_vc_id": "https://issuer.example.org/credentials/...",
"person_vc_id": "https://issuer.example.org/credentials/...",
"subject_id": "https://issuer.example.org/subjects/...",
"created_at": "2025-11-13T15:30:00Z",
"warnings": []
}
],
"summary": {
"submitted": 2,
"succeeded": 2,
"failed": 0,
"duration_ms": 110
},
"request_id": "req_01HGAF9P9KTYMZCJXCK6NZXQFD"
}
Note: HTTP 207 (Multi-Status) is returned if some items succeed and others fail. Check each item’s status field in the results array.
3.3 Get Metadata
Retrieve issuer information and service endpoints for discovery.
Endpoint
| Method | Path | Auth |
|---|---|---|
GET |
/ea-consent-issuer/api/v2/metadata |
— |
No authentication required.
Response
{
"issuer": "https://issuer.example.org",
"issuer_name": "EasyAccess Authorization Server",
"service_version": "0.20.1",
"jwks_uri": "https://issuer.example.org/ea-consent-issuer/api/v2/keys",
"verification_keys_uri": "https://issuer.example.org/ea-consent-issuer/api/v2/verification-keys",
"consents_uri": "https://issuer.example.org/ea-consent-issuer/api/v2/consents",
"consent_batches_uri": "https://issuer.example.org/ea-consent-issuer/api/v2/consent-batches",
"metadata_uri": "https://issuer.example.org/ea-consent-issuer/api/v2/metadata"
}
3.4 Get Verification Keys (JWKS)
Retrieve verification keys in JWKS format (RFC 7517) for JWT signature verification.
Endpoint
| Method | Path | Auth |
|---|---|---|
GET |
/ea-consent-issuer/api/v2/keys |
— |
No authentication required.
Response
Returns a JSON Web Key Set (JWKS) containing the public keys used to sign Trust Blocks and EA Consent VCs. Use these keys to verify JWT signatures (match the kid in the JWT header to the key in the JWKS).
3.5 Get Combined Verification Keys
Retrieve combined metadata and verification keys in one response.
Endpoint
| Method | Path | Auth |
|---|---|---|
GET |
/ea-consent-issuer/api/v2/verification-keys |
— |
No authentication required.
Response
Returns a combined response containing both the service metadata and JWKS. Use this endpoint when you need both discovery information and verification keys in a single request.
4. Monitoring Endpoints
Health and status endpoints run on a separate monitoring port (default: 8081).
| Method | Endpoint | Description |
|---|---|---|
GET |
/ea-consent-issuer/health |
Health check (returns {"status": "healthy"}) |
GET |
/ea-consent-issuer/status |
System status including runtime statistics and error counts |
5. Security & Authorization
Client Authentication
Protected API endpoints require bearer token authentication. Your administrator will provide the token value.
Protected endpoints (require Authorization: Bearer <token> header):
POST /ea-consent-issuer/api/v2/consents- Issue single consentPOST /ea-consent-issuer/api/v2/consent-batches- Issue batch consents
Public endpoints (no authentication required):
GET /ea-consent-issuer/api/v2/metadata- Service discoveryGET /ea-consent-issuer/api/v2/keys- Verification keys (JWKS)GET /ea-consent-issuer/api/v2/verification-keys- Combined metadata and keys
Request format:
POST /ea-consent-issuer/api/v2/consents
Authorization: Bearer YOUR_TOKEN_HERE
Content-Type: application/json
Authentication error responses:
401 Unauthorized- Missing, malformed, or invalid bearer token- Includes
WWW-Authenticate: Bearerheader per RFC 6750
- Includes
Note: The EA Consent Issuer is designed to run within your company’s firewall or private network.
Trust Block and EA Consent Verification
The issued credentials (Trust Blocks and EA Consent VCs) are cryptographically signed JWTs. To verify them:
- Fetch verification keys from
/api/v2/keys(JWKS format) - Decode the JWT using a JWT library in your language
- Verify the signature using the public key matching the
kid(key ID) in the JWT header - Validate claims (
iss,nbf, expiration if present)
6. Error Handling
The EA Consent Issuer returns errors in a consistent structured format across all endpoints.
Error Response Structure
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable summary",
"description": "Detailed error information"
},
"request_id": "unique-request-identifier"
}
Error Codes and Developer Actions
| Code | HTTP Status | Meaning | Developer Action |
|---|---|---|---|
| 400 | BAD_REQUEST |
Malformed JSON, wrong Content-Type, or invalid request format | Fix JSON syntax and Content-Type header. Validate request structure before retrying. |
| 401 | AUTH_REQUIRED |
Missing or invalid authentication credentials (future feature) | Provide valid authentication token or certificate. |
| 403 | FORBIDDEN |
Authenticated but not authorized to perform this action (future feature) | Check permissions or scopes. Contact administrator if access is needed. |
| 404 | NOT_FOUND |
Resource not found | Verify endpoint path and method. Do not retry. |
| 422 | VALIDATION_ERROR |
Request format is valid but JSON schema validation or business rules failed | Read error.description for specific validation failures (e.g., "field '/consent': missing properties: 'summary_html'"). Fix the indicated fields and retry. |
| 429 | TOO_MANY_REQUESTS |
Rate limit exceeded (future feature) | Wait and retry with exponential backoff. Check Retry-After header if present. |
| 500 | INTERNAL_ERROR |
Unexpected server error | Retry with exponential backoff. If persists, report request_id to support. |
| 503 | SERVICE_UNAVAILABLE |
Service temporarily unavailable | Retry after delay. Check Retry-After header if present. |
Example Error Responses
Validation Error (422):
{
"error": {
"code": "VALIDATION_ERROR",
"message": "JSON schema validation failed",
"description": "field '/consent': missing properties: 'summary_html'"
},
"request_id": "d9e4f6a8-1234-5678-9abc-def012345678"
}
Internal Server Error (500):
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal Server Error",
"description": "Internal Server Error"
},
"request_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
Note: For 5xx errors, message and description are sanitized to prevent information leakage. Use the request_id to correlate with server logs when reporting issues to support.
Request ID Correlation
Every response includes a request_id field. This identifier also appears in:
- The
X-Request-IDresponse header - Server logs for this request
When reporting errors to your administrator or support team, always include the request_id to help diagnose the issue.
7. Debug & Testing
Local Testing
You can test the API locally using curl, Postman, or your preferred HTTP client.
Basic example (minimal consent):
curl -X POST "http://localhost:8080/ea-consent-issuer/api/v2/consents" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token-here>" \
-d '{
"subject": {
"id": "user-extract-001"
},
"consent": {
"agreed": true,
"summary_html": "I agree to the privacy policy",
"details_html": "<p>I agree to the privacy policy and terms of service.</p>",
"contains_ppn_consent": true
},
"evidence": [
{
"type": "AuthenticationEvidence",
"id_token": "header.payload.signature"
}
]
}
'
Batch example (multiple consents):
curl -X POST "http://localhost:8080/ea-consent-issuer/api/v2/consent-batches" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token-here>" \
-d '{
"consents": [
{
"client_reference_id": "abc-001",
"consent": {
"subject": {
"id": "user-001",
"email": "user001@example.com"
},
"consent": {
"agreed": true,
"summary_html": "I agree to the privacy policy",
"details_html": "<p>I agree to the privacy policy and terms of service.</p>",
"contains_ppn_consent": true,
"scope_code": "patient-consent",
"policies": [
{
"authority": "https://acmehealth.com",
"uri": "https://acmehealth.com/privacy-policy/v2"
}
]
},
"evidence": [
{
"type": "AuthenticationEvidence",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.sig1"
}
]
}
},
{
"client_reference_id": "abc-002",
"consent": {
"subject": {
"id": "user-002",
"email": "user002@example.com"
},
"consent": {
"agreed": true,
"summary_html": "I agree to the privacy policy",
"details_html": "<p>I agree to the privacy policy and terms of service.</p>",
"contains_ppn_consent": true,
"scope_code": "patient-consent",
"policies": [
{
"authority": "https://acmehealth.com",
"uri": "https://acmehealth.com/privacy-policy/v2"
}
]
},
"evidence": [
{
"type": "AuthenticationEvidence",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.sig2"
}
]
}
}
]
}'
Debug Options
The EA Consent Issuer provides a debug mode that includes decoded JWT payloads in the response for troubleshooting.
Using Debug Mode
Add the ?debug=true query parameter to any API request:
curl -X POST "http://localhost:8080/ea-consent-issuer/api/v2/consents?debug=true" \
-H "Content-Type: application/json" \
-d '{
"subject": {
"id": "user-extract-001",
"email": "user001@example.com"
},
"consent": {
"agreed": true,
"summary_html": "I agree to the privacy policy",
"details_html": "<p>I agree to the privacy policy and terms of service.</p>",
"contains_ppn_consent": true
},
"evidence": [
{
"type": "AuthenticationEvidence",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.sig2"
}
]
}
'
Debug Response
When debug mode is enabled, the response includes a debug object with decoded JWT payloads:
{
"trust_block": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"result": {
"status": "success",
"http_status": 201,
"trust_block_id": "https://issuer.example.org/trust-blocks/...",
"consent_vc_id": "https://issuer.example.org/credentials/...",
"person_vc_id": "https://issuer.example.org/credentials/...",
"subject_id": "https://issuer.example.org/subjects/...",
"created_at": "2025-11-13T15:30:00Z",
"warnings": []
},
"debug": {
"trust_block": {
"json": {
"jti": "https://issuer.example.org/trust-blocks/...",
"iss": "https://issuer.example.org",
"nbf": 1728565800,
"vc": {
"@context": ["https://www.w3.org/ns/credentials/v2", "..."],
"type": ["VerifiableCredential", "WebShieldTrustBlock"],
"credentialSubject": { "...": "..." }
}
}
},
"consent_vc": {
"json": {
"jti": "https://issuer.example.org/credentials/...",
"iss": "https://issuer.example.org",
"nbf": 1728565800,
"vc": {
"@context": ["https://www.w3.org/ns/credentials/v2", "..."],
"type": ["VerifiableCredential", "EAConsentVerifiableCredential"],
"credentialSubject": { "...": "..." }
}
}
},
"input_consent_json": {
"subject": {"id": "user-123"},
"consent": {
"agreed": true,
"summary_html": "I agree to the terms"
}
}
},
"request_id": "req_01HGAF9P9KTYMZCJXCK6NZXQFD"
}
Debug Mode Requirements
Important: The ?debug=true query parameter requires server.debug=true in the service configuration. If debug mode is not enabled server-side, the query parameter is silently ignored (no debug data in response).
This is a security feature to prevent unauthorized debug data exposure. Contact your administrator if you need debug mode enabled.
When to Use Debug Mode
- Development: Verify JWT payload structure and field transformations
- Integration Testing: Compare input data vs output credentials
- Troubleshooting: Investigate credential format issues or unexpected transformations
- Learning: Understand how EA Consent Input maps to W3C VC structures
Security Warning: Debug output contains full decoded credentials with all consent data. Only use debug mode in development/staging environments or for authorized troubleshooting.
8. Related Components
The EA Consent Issuer integrates with other WebShield components as part of the Privacy Network flow.
Component Relationships
| Upstream Component | Downstream Component |
|---|---|
| Partner applications (mobile apps, web apps) | EA Consent Delta Writer |
| Data migration tools | Delta Sharing Server |
Data Flow
Upstream (Input to EA Consent Issuer):
Partner applications capture consent from users and POST EA Consent Input JSON to this service. The applications provide:
- Subject identity information (user IDs, email, phone, etc.)
- Consent decisions and policies
- Optional evidence (OpenID tokens, document scans)
- Optional provenance metadata (
captured_by)
Downstream (Output from EA Consent Issuer):
This service issues Trust Block JWTs that are consumed by:
-
EA Consent Delta Writer: Receives Trust Blocks, verifies signatures, extracts EA Consent VCs, and writes normalized data to Delta tables for Privacy Network queries.
-
Partner applications: May store Trust Blocks in their own databases for audit trails or compliance reporting.
-
Verification services: Any service that needs to verify consent credentials can fetch verification keys from this issuer’s
/api/v2/keysendpoint.
Shared Identifiers
| Identifier | Description | Where It Appears |
|---|---|---|
trust_block_id |
Unique ID for the Trust Block credential | Response field, Trust Block JWT jti claim |
consent_vc_id |
Unique ID for the EA Consent VC | Response field, EA Consent VC JWT jti claim |
person_vc_id |
Unique ID for the EA Person VC | Response field, EA Person VC JWT jti claim |
subject_id |
Subject identifier for the credential | Response field, Trust Block JWT credentialSubject.id |
issuer |
Issuer URL | All JWT iss claims, metadata endpoint |
kid (key ID) |
Signing key identifier | JWT headers, JWKS endpoint |
9. Versioning & Compatibility
Current Versions
| Type | Current Version | Notes |
|---|---|---|
| API Version | v2 |
Current and only supported version |
| EA Consent Schema Version | v2 |
Aligns with EA Consent Verifiable Credential v2 specification |
| W3C VC Version | 2.0 |
Implements W3C Verifiable Credentials Data Model 2.0 |
| JWT Format | RFC 7519 | Compact JWT serialization |
Versioning Guidelines
- API Version (
/api/v2/): Incremented for breaking changes to endpoint paths, request/response structures, or behavior - Schema Version: Follows EA Consent schema versioning (maintained in separate repository)
- Backward Compatibility: Current version is initial release; future versions will maintain backward compatibility where possible
API Response Version Information
The /api/v2/metadata endpoint returns version information including service_version. See Section 3.3: Get Metadata for the full response format.
Additional Resources
Questions or Issues?
Contact your administrator or WebShield support with any questions about API access, configuration, or troubleshooting.