Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# project keys
*.pem

# IDE specific files:
.idea
*.iml
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ This repository contains a complete sample implementation demonstrating the Trus

2. **Start All Services**:
```bash
# Terminal 1: Agent Registry (port 8001)
cd agent-registry && python main.py
# Generate keys
./generate_keys.sh

# Terminal 1: Agent Registry (port 9002)
cd agent-registry && (sleep 10 && python populate_sample_data.py) & python main.py

# Terminal 2: Merchant Backend (port 8000)
cd merchant-backend && python -m uvicorn app.main:app --reload
Expand Down
48 changes: 41 additions & 7 deletions agent-registry/populate_sample_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import requests
import json
import base64
from cryptography.hazmat.primitives import serialization

# Agent Registry Service URL
BASE_URL = "http://localhost:9002"
Expand All @@ -29,13 +31,13 @@
{
"key_id": "primary",
"public_key": """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoG2JyN6sWH0BSze3C8iK
6u6q7+0wo5ybcFX1kKquBDCLIKqY1hqvtVmj9wTGpCXQ2Jt8PtXXnSOhj69ng3mc
ypJjf72GyKrgHX+nYxcQrnrPXNDaDrhLVtxDsoGIwyVTiUGH5bX2qlIerwlfG9Jz
24HabfGSs6wpxXlfSt29giljSbX78g+Rb9TEV3joZjSQIn68iaKU147uVpv2JhCA
88X9l7fKMUSKDbiyhLRpDjutHrns8NYALPSyRLN645+Hcl7so+AWb9CR8+bdgBUq
GHYlyRsMdsQENFDDFS35M4oz/5MeXj+sIAWrq2ceI0LBttCH6cOcX/r1VpSqoUc1
dQIDAQAB
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4rNYC4ChLr3xvR9K5a9
JGFksUYbVqB2XfVF6QHlU9W0vONUjunKo1V56WkJWxY/diolG0847NTj2y0ksnZv
18e/AuPex4blylGuRXSBOoxsTkN6szMeFB1vsrKqrDqCGxOP0cHeW6biCZbOhQpE
tjWVwEXsJMzbKIYwhx35UrD1RjfRCdsFP6ery/tBu0jnTN47pWQWBq200JXZRpSR
0MfPDeIdQzvTUrHnxIbfGdsBixHvZXnw8Fa3lG9ol5l9QYpi8MN3qoVM4rT4ANcW
FkVaOOsJYd863Bqy3X9vaIUpDqJS0HoOq8l8X26HGtX2LinFi7hcPGZWiznj03v2
ywIDAQAB
-----END PUBLIC KEY-----""",
"algorithm": "RSA-SHA256",
"description": "Primary signing key for Test Agent 1",
Expand Down Expand Up @@ -91,6 +93,35 @@
}
]

def make_agent_from_PEM_files():
with open("ed25519_public.pem", "rb") as f:
ed25519_public_key= serialization.load_pem_public_key(f.read())
ed25519_public_key_b64 = base64.b64encode(ed25519_public_key.public_bytes_raw()).decode("utf-8")
rsa_public_key = open("rsa_public.pem", "r").read()
return {
"name": "My TAP Agent",
"domain": "https://tapagent.com",
"description": "Official Tap Agent 1 service for merchant verification",
"contact_email": "support@tapagent.com",
"is_active": "true",
"keys": [
{
"key_id": "primary",
"public_key": rsa_public_key,
"algorithm": "RSA-SHA256",
"description": "Primary signing key for Test Agent 1",
"is_active": "true"
},
{
"key_id": "primary-ed25519",
"public_key": ed25519_public_key_b64,
"algorithm": "ed25519",
"description": "Primary Ed25519 signing key for modern crypto",
"is_active": "true"
}
]
}

def register_agent(agent_data):
"""Register a single agent"""
try:
Expand Down Expand Up @@ -130,6 +161,9 @@ def main():
# Register each agent
for agent in sample_agents:
register_agent(agent)
# Register the agent from the PEM files
register_agent(make_agent_from_PEM_files())


print("🏁 Sample data population completed!")

Expand Down
21 changes: 21 additions & 0 deletions generate_keys.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

# Generate RSA keys (optional - for RSA-PSS-SHA256)
openssl genrsa -out rsa_private.pem 2048
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

# Generate Ed25519 keys (optional - for Ed25519)
openssl genpkey -algorithm Ed25519 -out ed25519_private.pem
openssl pkey -in ed25519_private.pem -pubout -out ed25519_public.pem

# Copy public keys to merchant-backend/
cp ed25519_public.pem rsa_public.pem merchant-backend/

# Copy public keys to agent-registry/
cp ed25519_public.pem rsa_public.pem agent-registry/

# Copy public and private keys to tap-agent/
cp ed25519_public.pem ed25519_private.pem rsa_public.pem rsa_private.pem tap-agent/

# Remove private keys from top-level directory
rm rsa_private.pem rsa_public.pem ed25519_private.pem ed25519_public.pem
18 changes: 7 additions & 11 deletions merchant-backend/app/security/signature_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@
import base64
import hashlib

publicKey = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAysHJFJ9uoVvU1sH2x3TV
bwW3nfyp34eOb8w177Ei/Bx8pk+8Ibu1yulV0nCBl/c9insg1k2x7dw1jRDZHJBG
wIpCdRL0GKm6qIdtsjeOcMnkI5ET0zGpxkhuRUwRblYW3LAdAq1Gja1WSPQKRT8r
EhUsmSlDWgAf0rFna15Ok6zOO3q21LtrEjnJSrgO+cr33YH0IAdALD7hqtPYK7+/
7dD/XIgGW9cX0USMxdDBUt8TnN2TYar5YXetpMnFOPpQHiGpKTkDwrRggcthUyuC
e1CoL/9a/DWilJwd481QkurvZqGaKegX5DlI+jLNvfi8TWMS3jCjknyOLg54KU86
LQIDAQAB
-----END PUBLIC KEY-----"""
with open("rsa_public.pem", "r") as f:
publicKey_rsa = f.read()

with open("ed25519_public.pem", "r") as f:
publicKey_ed25519 = f.read()

class SignatureVerifier:
def __init__(self):
Expand All @@ -44,10 +40,10 @@ def _load_public_key(self, agent_name: str):
"""Load public key for the agent. In production, load from secure storage."""

if agent_name == "example":
return serialization.load_pem_public_key(publicKey.encode("utf-8"))
return serialization.load_pem_public_key(publicKey_rsa.encode("utf-8"))
elif agent_name == "sample":
# Replace with actual sample public key in production
return serialization.load_pem_public_key(publicKey.encode("utf-8"))
return serialization.load_pem_public_key(publicKey_rsa.encode("utf-8"))
else:
raise ValueError(f"Unknown agent name: {agent_name}")

Expand Down
10 changes: 0 additions & 10 deletions tap-agent/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,3 @@ AGENT_PORT=8501

# Debug Configuration
DEBUG=true

# RSA Key Pair for HTTP Message Signatures (RFC 9421)
# Generate your own RSA key pair and replace these values
RSA_PRIVATE_KEY=<replacethis>
RSA_PUBLIC_KEY = "<replacethis>"

# Ed25519 Key Pair for HTTP Message Signatures (RFC 9421)
# Static keys for Ed25519 algorithm
ED25519_PRIVATE_KEY = "<replacethis>"
ED25519_PUBLIC_KEY = "<replacethis>"
16 changes: 3 additions & 13 deletions tap-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@ A sophisticated Streamlit web application for testing RFC 9421 HTTP Message Sign

## Environment Configuration

Create a `.env` file in the root directory with the following variables:

```bash
# RSA Keys (for RSA-PSS-SHA256 signatures)
RSA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
RSA_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"

# Ed25519 Keys (for Ed25519 signatures)
ED25519_PRIVATE_KEY="base64_encoded_private_key"
ED25519_PUBLIC_KEY="base64_encoded_public_key"
```
The `generate_keys.sh` script will generate a set of keys for the agent.

## Features

Expand Down Expand Up @@ -155,8 +145,8 @@ streamlit run agent_app.py --server.runOnSave true
### Environment Setup
```bash
# Generate RSA keys (optional - for RSA-PSS-SHA256)
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
openssl genrsa -out rsa_private_key.pem 2048
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

# Generate Ed25519 keys (optional - for Ed25519)
openssl genpkey -algorithm Ed25519 -out ed25519_private.pem
Expand Down
Loading