Skip to main contentCertyo Developer Portal

Amazon Web Services Integration

Reference architecture for integrating Certyo with AWS using EventBridge, Lambda, Step Functions, and API Gateway.

EventBridge API Destinations
EventBridge API Destinations support automatic retry with exponential backoff — configure max retries to 185 for 24h coverage.

Prerequisites

  • AWS account with IAM permissions for EventBridge, Lambda, Step Functions, and Secrets Manager
  • AWS CLI v2 configured with credentials
  • Certyo API key (stored in AWS Secrets Manager — see Authentication section below)
  • Node.js 20+ or Python 3.12+ (for Lambda development)

Reference Architecture

This architecture leverages AWS-native event routing and serverless compute to integrate with Certyo:

AWS Reference Architecture
Source System ──► EventBridge ──► API Destination (Certyo) ──► POST /api/v1/records
                          │                                           │
                     DLQ (SQS)                                  Step Functions
                   for failed                               (verification workflow)
                    deliveries                                        │
                                                              ┌──────┴──────┐
                                                              │  Wait 90s   │
                                                              │  Verify     │
                                                              │  Branch     │
                                                              └──────┬──────┘
                                                                     │
                                                              SNS notification
                                                           (anchored / failed)

EventBridge receives domain events from your source systems (S3, DynamoDB Streams, custom applications). For simple forwarding, API Destinations call Certyo directly without a Lambda intermediary. For complex transformations, Lambda processes events before ingestion. Step Functions orchestrate multi-step verification workflows.


EventBridge API Destinations

The simplest integration pattern: EventBridge calls Certyo's API directly via an API Destination. No Lambda code required for straightforward event forwarding.

How it works

  • ConnectionStores the Certyo API key with API_KEY auth type. EventBridge manages credential rotation if you update the secret.
  • API DestinationDefines the Certyo endpoint URL, HTTP method, and invocation rate limit.
  • RuleMatches incoming events by source, detail-type, or custom patterns and routes them to the API Destination.
  • Input TransformerMaps your event schema to the Certyo record payload without any Lambda code.
  • Retry + DLQBuilt-in retry with exponential backoff (up to 24 hours with 185 retries). Failed events land in an SQS dead-letter queue.

Lambda Functions

For events that require transformation, enrichment, or conditional logic before ingestion, use Lambda as the processing layer:

  • S3 triggerNew objects in a bucket trigger a Lambda that reads the file, extracts records, and sends each to Certyo
  • DynamoDB StreamsCapture change data from DynamoDB tables and forward modified items as Certyo records
  • Webhook handlerReceive webhooks from third-party systems via API Gateway, transform, and ingest

Step Functions

Orchestrate multi-step workflows that ingest a record, wait for anchoring, verify the result, and branch on success or failure:

  • Standard WorkflowFor long-running verification flows (up to 1 year execution). Uses Wait states to pause for Certyo's ~60-90 second anchoring window.
  • Express WorkflowFor high-volume, short-duration executions (up to 5 minutes). Ideal for bulk ingestion where verification is handled separately.

API Gateway

Front Certyo for internal consumers with API Gateway for usage plans, throttling, and API key management:

  • Create a REST API proxy that forwards requests to https://www.certyos.com/api/v1/
  • Add a usage plan with throttling (e.g., 100 requests/second per consumer) and monthly quotas
  • Inject the Certyo X-API-Key via a Lambda authorizer or VTL mapping template
  • Internal consumers authenticate with their own API Gateway keys — they never see the Certyo key

Code Samples

certyo_s3_ingest.pypython
import json
import os
import urllib.parse
import boto3
import urllib3

secrets_client = boto3.client("secretsmanager")
s3_client = boto3.client("s3")
http = urllib3.PoolManager()

CERTYO_API_URL = os.environ.get("CERTYO_API_URL", "https://www.certyos.com")
CERTYO_TENANT_ID = os.environ["CERTYO_TENANT_ID"]
SECRET_ARN = os.environ["CERTYO_SECRET_ARN"]

_api_key_cache = None


def get_api_key():
    global _api_key_cache
    if _api_key_cache is None:
        secret = secrets_client.get_secret_value(SecretId=SECRET_ARN)
        _api_key_cache = json.loads(secret["SecretString"])["apiKey"]
    return _api_key_cache


def handler(event, context):
    """
    Triggered by S3 PutObject events. Reads the uploaded JSON file,
    extracts records, and sends each to Certyo for blockchain anchoring.
    """
    api_key = get_api_key()
    results = []

    for record in event["Records"]:
        bucket = record["s3"]["bucket"]["name"]
        key = urllib.parse.unquote_plus(record["s3"]["object"]["key"])

        print(f"Processing s3://{bucket}/{key}")

        # Read the S3 object
        obj = s3_client.get_object(Bucket=bucket, Key=key)
        body = json.loads(obj["Body"].read().decode("utf-8"))

        # Support single record or array of records
        items = body if isinstance(body, list) else [body]

        for item in items:
            record_id = item.get("id", key.split("/")[-1].replace(".json", ""))

            payload = {
                "tenantId": CERTYO_TENANT_ID,
                "database": f"s3-{bucket}",
                "collection": key.rsplit("/", 1)[0] if "/" in key else "root",
                "recordId": record_id,
                "recordVersion": str(item.get("version", "1")),
                "operationType": "upsert",
                "recordPayload": item,
                "sourceTimestamp": record["eventTime"],
                "idempotencyKey": f"{record_id}-{record['eventTime'][:10]}",
            }

            response = http.request(
                "POST",
                f"{CERTYO_API_URL}/api/v1/records",
                body=json.dumps(payload),
                headers={
                    "X-API-Key": api_key,
                    "Content-Type": "application/json",
                },
            )

            result = json.loads(response.data.decode("utf-8"))

            if response.status != 202:
                print(f"ERROR: Certyo returned {response.status} for {record_id}: {result}")
                raise Exception(f"Ingestion failed for {record_id}: {response.status}")

            print(f"Record {record_id} accepted. Hash: {result['recordHash']}")
            results.append(result)

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": f"Ingested {len(results)} records",
            "records": results,
        }),
    }

Authentication

The recommended authentication pattern uses AWS-native secrets management with IAM for service-to-service authorization:

  • Secrets ManagerStore the Certyo X-API-Key as a secret. Enable automatic rotation if your organization requires it.
  • EventBridge ConnectionThe connection object securely stores the API key and injects it into every API Destination request. You do not handle the key in application code.
  • Lambda execution roleGrant Lambda functions secretsmanager:GetSecretValue on the specific secret ARN. Use the least-privilege principle.
  • API Gateway API keysFor internal consumers, issue API Gateway keys tied to usage plans. The gateway injects the Certyo key via a Lambda authorizer or mapping template.
IAM policy for Lambda to read Certyo secretjson
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadCertyoApiKey",
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:certyo/api-key-*"
    }
  ]
}

Cost Optimization

Choose the right integration pattern based on your workload to minimize AWS costs:

  • EventBridge API Destinations (cheapest)No Lambda invocation costs. You pay only for EventBridge events ($1.00 per million events) and API Destination invocations. Use this for simple event forwarding where no transformation is needed.
  • EventBridge + Input TransformerIf you only need to reshape the event payload (rename fields, extract nested values), use the EventBridge Input Transformer instead of Lambda. Zero compute cost.
  • Lambda (for transformations)Reserve Lambda for cases where you need to read from S3, call external APIs, or apply complex business logic before ingesting. Use ARM64 (Graviton) for 20% cost savings.
  • Step Functions ExpressFor high-volume verification workflows (>100K executions/month), Express Workflows cost up to 80% less than Standard Workflows.
Tip
For most integrations, EventBridge API Destinations with Input Transformers handle everything without a single line of Lambda code. Start there and add Lambda only when you need it.

Next steps

  • Deploy the CDK stack above to provision the full EventBridge pipeline in minutes
  • Publish a test event to the domain-events bus and verify it arrives in Certyo
  • Deploy the Step Functions verification workflow for end-to-end anchoring confirmation
  • Review the Ingestion Guide for details on record schema and idempotency
  • See the Verification Guide for cryptographic proof details

AI Integration · v1.0.0

AI Integration Skill

Download a skill file that enables AI agents to generate working AWS + Certyo integration code for any language or framework.

v1.0.0
What is this?
A markdown file containing AWS-specific field mappings, authentication setup, code examples, and integration patterns for Certyo. Drop it into your AI agent's context and ask it to generate integration code.

What's inside

  • AuthenticationEventBridge Connection with API Key, Lambda with Secrets Manager
  • ArchitectureEventBridge → API Destination or Lambda → Certyo → Step Functions verify
  • Code examplesPython Lambda, CDK TypeScript stack, Step Functions ASL workflow
  • API DestinationsZero-Lambda direct forwarding to Certyo with retry policies
  • Step FunctionsVerification workflow with Wait states, retry loops, and branching
  • Cost optimizationAPI Destinations vs Lambda vs Express Workflows comparison

How to use

Claude Code

Place the file in your project's .claude/commands/ directory, then use it as a slash command:

# Download the skill file
mkdir -p .claude/commands
curl -o .claude/commands/certyo-aws.md \
  https://www.certyos.com/developers/skills/certyo-aws-skill.md

# Use it in Claude Code
/certyo-aws "Generate an EventBridge API Destination that forwards events to Certyo"

Cursor / Copilot / Any AI Agent

Add the file to your project root or attach it to a conversation. The AI agent will use the AWS-specific patterns, field mappings, and code examples to generate correct integration code.

# Add to your project
curl -o CERTYO_AWS.md \
  https://www.certyos.com/developers/skills/certyo-aws-skill.md

# Then in your AI agent:
"Using the Certyo AWS spec in CERTYO_AWS.md,
 generate an eventbridge api destination that forwards events to certyo"

CLAUDE.md Context File

Append the skill file to your project's CLAUDE.md so every Claude conversation has AWS + Certyo context automatically.

# Append to your project's CLAUDE.md
echo "" >> CLAUDE.md
echo "## Certyo AWS Integration" >> CLAUDE.md
cat CERTYO_AWS.md >> CLAUDE.md