Skip to content

ryan-hansen/keritest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KERI Falcon API

A Falcon REST API implementation that handles KERI (Key Event Receipt Infrastructure) signed requests and responses for registering and retrieving user data.

Overview

This API provides two endpoints:

  • POST /register: Register user data with KERI signatures
  • GET /read: Retrieve user data by name, AID, or SAID with KERI signatures

All requests and responses are cryptographically signed using KERI signatures, ensuring authenticity and integrity without requiring trust in a third party.

Installation

  1. Clone the repository:
git clone <repository-url>
cd keripy
  1. Install dependencies using uv (or your preferred package manager):
uv sync
  1. Activate the virtual environment:
source .venv/bin/activate

Running the API

Option 1: Using Gunicorn (recommended)

Gunicorn is included in the dependencies and is the recommended way to run the API:

Basic usage:

gunicorn --bind 127.0.0.1:8000 main:app

For development with auto-reload:

gunicorn --reload --bind 127.0.0.1:8000 main:app

Customize the server:

# Use a different port
gunicorn --bind 127.0.0.1:8080 main:app

# Use a different host
gunicorn --bind 0.0.0.0:8000 main:app

# Combine options
gunicorn --reload --bind 0.0.0.0:8080 main:app

Option 2: Using the built-in script with Waitress (development)

The provided main script can be used with Waitress for development, but Waitress is not installed by default:

  1. Install Waitress:
uv add waitress
  1. Run the server:
python main.py

This will start the server on http://127.0.0.1:8000 using Waitress.

Customize the server:

# Use a different port
python main.py --port 8080

# Use a different host
python main.py --host 0.0.0.0

# Use gunicorn instead (note: gunicorn should be run directly, see Option 1)
python main.py --server gunicorn

Option 3: Using Waitress directly

  1. Install Waitress:
uv add waitress
  1. Run the server:
waitress-serve --port=8000 main:app

Verifying the API is running

Once the server is running, you can verify it's working by checking the endpoints:

# Health check (will return 404, but confirms server is running)
curl http://localhost:8000/read

The API will be available at:

  • POST http://localhost:8000/register
  • GET http://localhost:8000/read

Running Tests

Run the test suite using pytest:

pytest

To run with verbose output:

pytest -v

API Endpoints

POST /register

Register user data with a KERI signature.

Request:

  • Body: JSON SAD (Self-Addressing Data) structure:
    {
      "d": "SAID_VALUE",
      "i": "AID_VALUE",
      "n": "User Name"
    }
  • Headers:
    • Signature: RFC8941-compliant signature header signing the SAID value (d field)

Response:

  • Status: 200 OK
  • Body: JSON SAD with SAID
  • Headers:
    • Signature: Signature header signed by host AID on response body SAID

Example Request:

curl -X POST http://localhost:8000/register \
  -H "Content-Type: application/json" \
  -H "Signature: indexed=\"?1\";0=\"C0EF9012...\"" \
  -d '{"d":"Eabc123...","i":"EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-","n":"John Doe"}'

Example Response:

{
  "d": "Eabc123...",
  "i": "EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-",
  "n": "John Doe"
}

GET /read

Retrieve user data by name, AID, or SAID with a KERI signature.

Request:

  • Query Parameters: One of:
    • name=User Name
    • AID=AID_VALUE
    • SAID=SAID_VALUE
  • Headers:
    • Signature: RFC8941-compliant signature header signing a digest of the query parameter string

Response:

  • Status: 200 OK (if found) or 404 Not Found
  • Body: JSON SAD with SAID (if found)
  • Headers:
    • Signature: Signature header signed by host AID on response body SAID (only on success)

Example Request:

curl -X GET "http://localhost:8000/read?name=John%20Doe" \
  -H "Signature: indexed=\"?1\";0=\"C0EF9012...\""

Example Response:

{
  "d": "Eabc123...",
  "i": "EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-",
  "n": "John Doe"
}

Signature Header Format

The API uses RFC8941 Structured Field Values format for the Signature header. Signatures are indexed signatures using the Siger class from keripy.

Format:

Signature: indexed="?1";0="<signature_value>"

Where:

  • indexed="?1" indicates indexed signatures
  • 0="<signature_value>" is the signature value for key index 0

Error Responses

Error responses (4xx, 5xx) do not include Signature headers. Common error codes:

  • 400 Bad Request: Invalid JSON, missing required fields, or missing query parameters
  • 401 Unauthorized: Missing or invalid signature
  • 404 Not Found: Requested data not found (GET only)

Implementation Details

Signature Verification

  • POST requests: Signature is verified on the SAID value (d field) from the request body
  • GET requests: Signature is verified on a Blake3-256 digest of the query parameter string

SAID Generation

Self-Addressing Identifiers (SAIDs) are generated using the Saider.saidify() method from keripy, which:

  1. Serializes the SAD to JSON
  2. Creates a Blake3-256 hash
  3. Encodes the hash in CESR format
  4. Injects the SAID into the d field

Data Storage

For testing purposes, data is stored in module-level memory. In production, this would be replaced with persistent storage.

Testing

The test suite includes:

  • Successful registration and retrieval
  • Invalid signature handling
  • Missing signature handling
  • Malformed request handling
  • Response signature verification

Run tests with:

pytest

Dependencies

  • falcon: Web framework
  • keri: KERI library (from GitHub)
  • pytest: Testing framework

Resources

License

[Add your license here]

About

A small project to exercise keripy

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages