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

  1. EA Consent Delta Writer – Developer Guide
    1. Quick Navigation
    2. Audience and Assumptions
    3. 1. Overview
    4. 2. Integration Flow
    5. 3. API Operations
      1. 3.1 Post Trust Blocks
      2. 3.2 Post Verification Keys
      3. 3.3 Revoke Verification Key
      4. 3.4 Get Metadata
    6. 4. Monitoring Endpoints
      1. Health Check
      2. System Status
    7. 5. Delta Table Output
    8. 6. Security & Authorization
      1. Client Authentication
    9. 7. Error Handling
      1. Request-Level Errors
      2. Block-Level Errors (Partial Success)
      3. Best-Effort Processing
    10. 8. Debug & Testing
      1. Debug Mode
    11. 9. Related Components
      1. Upstream: EA Consent Issuer
      2. Downstream: Delta Sharing Server
    12. 10. Versioning & Compatibility
      1. Versioning Guidelines
      2. Breaking Changes Policy
      3. Checking Versions

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:

  1. Accepts Trust Block JWTs containing EA Consent Verifiable Credentials (typically from the EA Consent Issuer)
  2. Decodes and validates the JWT structure (note: signature verification not yet implemented in Phase 1)
  3. Transforms consent data into Delta Share format across two tables:
    • ea-consent-tb - Complete EA Consent Verifiable Credentials
    • ea-consent-verification-keys - Cryptographic public keys for verifying consent VCs
  4. 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):

  1. Obtain Trust Blocks from the EA Consent Issuer (which processes your stored consent data)
  2. POST Trust Blocks to /ea-consent-delta-writer/api/v1/trust-block-batches
  3. Handle responses - check for success/partial success and process any errors
  4. Retry failed blocks if needed (based on error codes)
  5. 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 items
    • client_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 metrics
    • total (integer): Total Trust Blocks submitted
    • successful (integer): Successfully processed blocks
    • failed (integer): Failed blocks
  • results (array): Per-block results
  • timestamp (string): ISO 8601 timestamp (UTC)

Success result item:

  • client_reference_id (string): Your correlation ID from the request
  • status (string): "success"
  • trust_block_id (string): Trust Block identifier from JWT
  • ea_consent_id (string): Consent identifier from ConsentVC
  • debug (object, optional): Debug info if ?debug=true is used

Error result item:

  • client_reference_id (string): Your correlation ID from the request
  • status (string): "error"
  • error (string): Error code (see table below)
  • message (string): Human-readable error message
  • details (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 issuer
  • kty (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 revoke
  • revocation_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_ts set
  • Idempotent: Returns already_revoked if 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 Blocks
  • POST /ea-consent-delta-writer/api/v1/verification-key-batches - Ingest verification keys
  • POST /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 check
  • GET /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: Bearer header per RFC 6750

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:

  1. All blocks are processed independently
  2. Failures in one block don’t stop processing of remaining blocks
  3. Successfully processed blocks are written to S3 atomically (all-or-nothing)
  4. Response includes results for all submitted blocks

Retry Strategy for Partial Success:

  1. Extract failed blocks from response
  2. Fix data based on error messages
  3. Resubmit only failed blocks in new request
  4. 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.


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)

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 VCs
  • ea-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.