EA Consent Delta Writer – Developer Guide
Quick Navigation
This developer guide covers EA Consent Delta Writer API integration in 10 sections:
- Getting Started (1-2): Overview and integration flow
- API Operations (3): Post Trust Blocks, Post/Revoke Verification Keys, Get Metadata
- Infrastructure (4-5): Monitoring endpoints and Delta table output
- Security & Debugging (6-8): Authorization, error handling, and testing
- Integration Context (9-10): Related components and versioning
New to EA Consent Delta Writer? Start with sections 1-3 to understand the basics, then reference sections 6-8 as needed during implementation.
Table of Contents
- EA Consent Delta Writer – Developer Guide
Audience and Assumptions
This guide is for application developers who need to integrate with the EA Consent Delta Writer API.
Assumptions:
- You are developing an application that produces or processes EA Consent Trust Blocks
- You have access to a running EA Consent Delta Writer instance (URL and credentials provided by your administrator)
- You are not responsible for deploying or administering the EA Consent Delta Writer service
- For deployment, configuration, and operational guidance, see ops.md
What you’ll learn:
- How to call the EA Consent Delta Writer APIs
- Request and response formats for Trust Block ingestion
- Error handling and debugging techniques
- Integration flow with upstream and downstream components
1. Overview
The EA Consent Delta Writer is a transformation service that converts EA Consent Trust Blocks into queryable Delta tables conforming to the EA Consent schema.
What it does:
- Accepts Trust Block JWTs containing EA Consent Verifiable Credentials (typically from the EA Consent Issuer)
- Decodes and validates the JWT structure (note: signature verification not yet implemented in Phase 1)
- Transforms consent data into Delta Share format across two tables:
ea-consent-tb- Complete EA Consent Verifiable Credentialsea-consent-verification-keys- Cryptographic public keys for verifying consent VCs
- Writes Delta tables to S3 storage for consumption by Delta Sharing servers
Key capabilities:
- Batch processing (1-100 Trust Blocks per request)
- Best-effort processing with detailed per-block error reporting
- Debug mode for troubleshooting integration issues
- Verification key management for future JWT signature validation
2. Integration Flow
Prerequisite: This guide assumes you’ve completed Phase 1 - adding EasyAccess consent language to your application. Your app already captures and stores consent data. The EA Consent Delta Writer is part of Phase 2 when you’re ready to publish those consents to the Privacy Network.
The EA Consent Delta Writer fits into the Privacy Network flow as a transformation layer between consent issuance and data sharing:
--- Phase 1 (already done) ---
1. Your Application
└─> Captures user consent (your text + EasyAccess language)
└─> Stores consent data to your database
--- Phase 2 (this guide) ---
2. EA Consent Issuer
└─> Mints EA Consent VC and wraps it in a Trust Block (JWT)
3. EA Consent Delta Writer (This Service)
└─> 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
Typical workflow for developers (processing Trust Blocks from already-captured consents):
- Obtain Trust Blocks from the EA Consent Issuer (which processes your stored consent data)
- POST Trust Blocks to
/ea-consent-delta-writer/api/v1/trust-block-batches - Handle responses - check for success/partial success and process any errors
- Retry failed blocks if needed (based on error codes)
- Query Delta tables via Delta Sharing server (separate component)
3. API Operations
The service exposes data ingestion endpoints on Port 8080. All POST endpoints require Authorization: Bearer <token> header (see Section 6: Security & Authorization) and support an optional ?debug=true query parameter (see Section 8: Debug & Testing).
3.1 Post Trust Blocks
Ingest 1-100 Trust Block JWTs in a single batch request.
Endpoint: POST /ea-consent-delta-writer/api/v1/trust-block-batches 🔒
Request Body:
{
"trust_blocks": [
{
"client_reference_id": "order-123-consent-1",
"trust_block": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
},
{
"client_reference_id": "order-123-consent-2",
"trust_block": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
}
]
}
Request Schema:
trust_blocks(array, required): Array of 1-100 trust block itemsclient_reference_id(string, required): Your correlation ID for tracking (non-empty)trust_block(string, required): Trust Block JWT string (non-empty)
Trust Block JWT Format:
Trust Blocks are JWT strings obtained from the EA Consent Issuer. Treat them as opaque tokens - the service handles all internal decoding and validation.
Important: If you need to debug Trust Block structure (e.g., investigating “invalid_jwt_format” errors), see the internal documentation JWT-STRUCTURE.md.
Response - Complete Success (HTTP 200 OK):
{
"status": "success",
"summary": {
"total": 2,
"successful": 2,
"failed": 0
},
"results": [
{
"client_reference_id": "order-123-consent-1",
"status": "success",
"trust_block_id": "urn:uuid:test-trustblock-789",
"ea_consent_id": "urn:consent:id:1"
},
{
"client_reference_id": "order-123-consent-2",
"status": "success",
"trust_block_id": "urn:uuid:test-trustblock-790",
"ea_consent_id": "urn:consent:id:2"
}
],
"timestamp": "2025-11-22T15:30:00Z"
}
Response - Partial Success (HTTP 200 OK):
{
"status": "partial_success",
"summary": {
"total": 2,
"successful": 1,
"failed": 1
},
"results": [
{
"client_reference_id": "order-123-consent-1",
"status": "success",
"trust_block_id": "urn:uuid:tb-123",
"ea_consent_id": "urn:consent:id:456"
},
{
"client_reference_id": "order-123-consent-2",
"status": "error",
"error": "invalid_jwt_format",
"message": "Failed to decode JWT: Invalid token format",
"details": {
"jwt_preview": "eyJhbGci...",
"full_error": "Not enough segments"
}
}
],
"timestamp": "2025-11-22T15:30:01Z"
}
Response Schema:
Top-level fields:
status(string): Overall status -"success"or"partial_success"summary(object): Batch operation metricstotal(integer): Total Trust Blocks submittedsuccessful(integer): Successfully processed blocksfailed(integer): Failed blocks
results(array): Per-block resultstimestamp(string): ISO 8601 timestamp (UTC)
Success result item:
client_reference_id(string): Your correlation ID from the requeststatus(string):"success"trust_block_id(string): Trust Block identifier from JWTea_consent_id(string): Consent identifier from ConsentVCdebug(object, optional): Debug info if?debug=trueis used
Error result item:
client_reference_id(string): Your correlation ID from the requeststatus(string):"error"error(string): Error code (see table below)message(string): Human-readable error messagedetails(object): Additional context (jwt_preview, full_error, etc.)
Error Codes:
| Error Code | Meaning | Developer Action |
|---|---|---|
invalid_jwt_format |
JWT decoding failed | Verify JWT structure. Check that Trust Block is a valid JWT with three base64-encoded segments separated by dots. See JWT-STRUCTURE.md for debugging |
processing_failed |
Trust Block processing failed | Check error details.full_error for specific issue. May indicate malformed ConsentVC structure |
validation_error |
Pydantic model validation failed | Verify ConsentVC fields meet schema requirements. Check details for specific field errors |
transformation_error |
Delta Share transformation failed | Internal transformation error. Contact administrator with correlation ID |
Example:
curl -X POST "http://localhost:8080/ea-consent-delta-writer/api/v1/trust-block-batches" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-d '{
"trust_blocks": [
{
"client_reference_id": "test-consent-001",
"trust_block": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
}
]
}'
3.2 Post Verification Keys
Ingest 1-10 verification keys in JWK format for a given issuer.
Endpoint: POST /ea-consent-delta-writer/api/v1/verification-key-batches 🔒
Request Body:
{
"issuer": "https://consent-issuer.example.com",
"issuer_name": "Acme Consent Issuer",
"keys": [
{
"kty": "RSA",
"kid": "consent-key-2025-11",
"use": "sig",
"alg": "RS256",
"n": "xGOr_H3N...",
"e": "AQAB"
}
]
}
Request Schema:
issuer(string, required): Issuing authority URL (valid URI)issuer_name(string, optional): Human-readable issuer name (not stored)keys(array, required): Array of 1-10 JWK objects
JWK Object Required Fields:
kid(string, required): Key ID, unique within issuerkty(string, required): Key type (RSA,EC,OKP,oct)alg(string, required): JWT algorithm (RS256,RS384,RS512,ES256,ES384,ES512,PS256,PS384,PS512,HS256,HS384,HS512,EdDSA)
Response (HTTP 200 OK):
Response format follows the same batch response pattern as Trust Blocks with status, summary, results, and timestamp fields.
Error Codes:
| Error Code | Meaning | Developer Action |
|---|---|---|
invalid_alg |
Unsupported JWT algorithm | Use supported algorithms: RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512, HS256, HS384, HS512, EdDSA |
invalid_kty |
Unsupported key type | Use supported key types: RSA, EC, OKP, oct |
missing_required_field |
Required JWK field missing | Ensure kid, kty, and alg fields are present |
Example:
curl -X POST "http://localhost:8080/ea-consent-delta-writer/api/v1/verification-key-batches" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-d '{
"issuer": "https://consent-issuer.example.com",
"keys": [
{
"kty": "RSA",
"kid": "consent-key-2025-11",
"use": "sig",
"alg": "RS256",
"n": "xGOr_H3N_test_modulus_value",
"e": "AQAB"
}
]
}'
3.3 Revoke Verification Key
Revoke a previously registered verification key.
Endpoint: POST /ea-consent-delta-writer/api/v1/verification-keys/revoke 🔒
Request Body:
{
"issuer": "https://issuer.example.org",
"kid": "key-2025-01",
"revocation_ts": "2025-12-07T10:00:00Z"
}
Request Schema:
issuer(string, required): Issuing authority URL (valid URI)kid(string, required): Key ID to revokerevocation_ts(string, optional): ISO 8601 timestamp for revocation (defaults to server time)
Response - Newly Revoked (HTTP 200 OK):
{
"status": "revoked",
"issuer": "https://issuer.example.org",
"kid": "key-2025-01",
"revocation_ts": "2025-12-07T10:00:00Z",
"request_id": "ec7276d384f7841257428004168cc3fe",
"timestamp": "2025-12-07T10:00:00Z"
}
Response - Already Revoked (HTTP 200 OK, Idempotent):
{
"status": "already_revoked",
"issuer": "https://issuer.example.org",
"kid": "key-2025-01",
"revocation_ts": "2025-11-01T08:00:00Z",
"request_id": "ec7276d384f7841257428004168cc3fe",
"timestamp": "2025-12-07T10:00:00Z"
}
Response - Key Not Found (HTTP 404):
{
"detail": {
"error": {
"code": "NOT_FOUND",
"message": "No key found for issuer and kid",
"description": "issuer=https://issuer.example.org, kid=unknown-key"
},
"request_id": "ec7276d384f7841257428004168cc3fe",
"timestamp": "2025-12-07T10:00:00Z"
}
}
Behavior:
- Follows append-only pattern: Creates new row with
revocation_tsset - Idempotent: Returns
already_revokedif key is already revoked (no new row created) - Preserves audit history for time-travel queries
Example:
# Revoke a verification key
curl -X POST "http://localhost:8080/ea-consent-delta-writer/api/v1/verification-keys/revoke" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-d '{
"issuer": "https://issuer.example.org",
"kid": "key-2025-01"
}'
# Revoke with explicit timestamp
curl -X POST "http://localhost:8080/ea-consent-delta-writer/api/v1/verification-keys/revoke" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-d '{
"issuer": "https://issuer.example.org",
"kid": "key-2025-01",
"revocation_ts": "2025-12-07T10:00:00Z"
}'
3.4 Get Metadata
Retrieve service version, schema versions, and storage configuration.
Endpoint: GET /ea-consent-delta-writer/api/v1/metadata (no authentication required)
Response (HTTP 200 OK):
{
"service_version": "1.0.0",
"schema_versions": {
"ea_consent_schema": "2.0.8",
"ea_consent_delta": "0.1.0"
},
"storage": {
"provider": "s3",
"uri_base": "s3://my-bucket/delta-tables",
"tables": ["ea-consent-tb", "ea-consent-verification-keys"]
}
}
Example:
curl http://localhost:8080/ea-consent-delta-writer/api/v1/metadata
4. Monitoring Endpoints
The service exposes monitoring endpoints on Port 8081 (no authentication required).
| Method | Endpoint | Description |
|---|---|---|
GET |
/ea-consent-delta-writer/health |
Basic health check |
GET |
/ea-consent-delta-writer/status |
Comprehensive runtime statistics |
Health Check
curl http://localhost:8081/ea-consent-delta-writer/health
Response:
{
"status": "healthy"
}
System Status
curl http://localhost:8081/ea-consent-delta-writer/status
Response includes:
- Service version and health status
- System info (process ID, hostname, memory usage, uptime)
- Ingestion statistics (requests, Trust Blocks, verification keys)
Note: Statistics are in-memory and reset on service restart. For detailed schema, see ops.md.
5. Delta Table Output
Successfully processed Trust Blocks and verification keys are written to two Delta tables:
| Table Name | Purpose | Location |
|---|---|---|
ea-consent-tb |
Complete EA Consent Verifiable Credentials | S3 (configured by admin) |
ea-consent-verification-keys |
Verification keys for JWT validation | S3 (configured by admin) |
Important: Table names use hyphens (not underscores). Always reference tables as ea-consent-tb, ea-consent-verification-keys.
Delta tables are served by a separate Delta Sharing server. Consult your administrator for Delta Sharing endpoint details.
6. 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-delta-writer/api/v1/trust-block-batches- Ingest Trust BlocksPOST /ea-consent-delta-writer/api/v1/verification-key-batches- Ingest verification keysPOST /ea-consent-delta-writer/api/v1/verification-keys/revoke- Revoke verification keys
Public endpoints (no authentication required):
GET /ea-consent-delta-writer/api/v1/metadata- Service metadata and versions
Monitoring endpoints (Port 8081, no authentication required):
GET /ea-consent-delta-writer/health- Health checkGET /ea-consent-delta-writer/status- System status
Request format:
POST /ea-consent-delta-writer/api/v1/trust-block-batches
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 Delta Writer is designed to run within your company’s firewall or private network.
7. Error Handling
The service uses two error response patterns depending on the failure type:
Request-Level Errors
When the entire request is invalid, the service returns an error response with appropriate HTTP status code:
| Code | Meaning | Developer Action |
|---|---|---|
| 401 | Unauthorized – missing or invalid bearer token | Provide valid Authorization: Bearer <token> header |
| 404 | Not Found – resource doesn’t exist | For revoke: verify issuer and kid combination exists |
| 422 | Unprocessable Entity – request validation failed | Validate JSON structure, ensure arrays have valid item counts, verify required fields are present and non-empty |
| 500 | Internal Server Error – catastrophic system failure (e.g., S3 write failure) | Retry after delay. If persistent, contact administrator |
Example Request-Level Error:
{
"error": "validation_error",
"message": "trust_blocks array must contain 1-100 items",
"details": {
"field": "trust_blocks",
"provided_count": 150
}
}
Block-Level Errors (Partial Success)
When individual blocks fail but the request is valid, the service returns HTTP 200 OK with status: "partial_success". Check the results array for per-block error details. See operation-specific error codes in Section 3.
Best-Effort Processing
The service uses best-effort batch processing:
- All blocks are processed independently
- Failures in one block don’t stop processing of remaining blocks
- Successfully processed blocks are written to S3 atomically (all-or-nothing)
- Response includes results for all submitted blocks
Retry Strategy for Partial Success:
- Extract failed blocks from response
- Fix data based on error messages
- Resubmit only failed blocks in new request
- DO NOT resubmit successful blocks - creates duplicates
8. Debug & Testing
Debug Mode
Add ?debug=true to any POST request to receive additional debugging information in the response.
Example:
curl -X POST "http://localhost:8080/ea-consent-delta-writer/api/v1/trust-block-batches?debug=true" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-d @trust_blocks.json
Debug Response (Success):
{
"status": "success",
"summary": {
"total": 1,
"successful": 1,
"failed": 0
},
"results": [
{
"client_reference_id": "test-consent-001",
"status": "success",
"trust_block_id": "urn:uuid:test-trustblock-123",
"ea_consent_id": "urn:consent:id:456",
"debug": {
"decoded_trust_block": {
"iss": "https://webshield.io",
"jti": "https://webshield.io/trust-blocks/minimal-example",
"iat": 1729710000
},
"decoded_consent_vc": {
"iss": "https://issuer.example.org",
"jti": "https://issuer.example.org/credentials/consent-min-001",
"iat": 1729698000
},
"delta_share_models": {
"vc_table": "ea-consent-tb"
},
"processing_time_ms": 142
}
}
],
"timestamp": "2025-11-22T15:30:00Z"
}
Debug Response (Error):
{
"status": "partial_success",
"summary": {
"total": 1,
"successful": 0,
"failed": 1
},
"results": [
{
"client_reference_id": "test-consent-002",
"status": "error",
"error": "invalid_jwt_format",
"message": "Failed to decode JWT: Invalid token format",
"details": {
"jwt_preview": "eyJhbGci...",
"full_error": "Not enough segments"
},
"debug": {
"attempted_decode": true,
"jwt_structure_valid": false,
"segment_count": 2
}
}
],
"timestamp": "2025-11-22T15:30:01Z"
}
Use debug mode when:
- Verifying Trust Block structure during integration
- Investigating “invalid_jwt_format” errors
- Troubleshooting transformation issues
- Understanding Delta table mapping
Important: Debug mode exposes sensitive JWT contents. Only use in development/testing environments.
9. Related Components
The EA Consent Delta Writer integrates with other components in the Privacy Network data flow:
| Upstream Component | Downstream Component |
|---|---|
| EA Consent Issuer | Delta Sharing Server (external documentation) |
Upstream: EA Consent Issuer
What it provides: Trust Block JWTs containing EA Consent Verifiable Credentials
Integration point: Your application obtains Trust Blocks from the EA Consent Issuer Docker application, then submits them to this service via the /trust-block-batches endpoint.
Data flow: EA Consent Issuer → Trust Block JWT → EA Consent Delta Writer
TODO: Verify path to EA Consent Issuer dev.md (link above is placeholder)
Downstream: Delta Sharing Server
What consumes our output: External Delta Sharing servers serve the Delta tables produced by this service
Output format: Two Delta tables written to S3:
ea-consent-tb- Full consent VCsea-consent-verification-keys- Verification keys
Note: Delta Sharing server setup and configuration is documented separately. Consult your administrator for Delta Sharing endpoint URLs and access tokens.
10. Versioning & Compatibility
| Type | Current Version | Notes |
|---|---|---|
| API Version | v1 |
Initial partner release |
| Schema Version | ea-consent-schema 2.0.8 |
Aligns with EA Consent Verifiable Credential v2 schema |
| Delta Table Version | ea-consent-delta 0.1.0 |
Delta Share transformation layer |
| Service Version | Check /metadata endpoint |
Runtime service version |
Versioning Guidelines
- API Version (
/api/v1/) - Incremented only for breaking changes to request/response formats - Schema Version - Tracks EA Consent schema evolution (separate versioning)
- Compatibility - Phase 1 is backward compatible with all v1 Trust Block formats
Breaking Changes Policy
When breaking changes occur:
- New API version will be introduced (e.g.,
/api/v2/) - Previous version remains available with deprecation timeline
- Migration guide provided in changelog
- Advance notice given to integration partners
Checking Versions
Get current versions:
curl http://localhost:8080/ea-consent-delta-writer/api/v1/metadata
See Section 3.4: Get Metadata for response format.