Observe agent tool calls and build tamper-evident receipts
Project description
drashta
1. Why are we doing this?
So when an agent runs in a sensitive context, you can prove what it did—for compliance, legal questions, and customer trust—not a black box.
2. How are we doing this?
Drashta.observe plus intercept(tool, run), or async with Drashta(...).instrument(agent) as run: to wrap an object’s public callables and restore them after seal(). Each tool call becomes a hashed step on a Run. seal() builds a receipt (hash chain + Merkle root), returns it, and schedules Emitter.flush in the background so the agent does not wait on the network.
Ingest stores the run in S3 (Object Lock) and indexes it in DynamoDB. The receipt API serves JSON verification and a PDF auditors can read.
3. What is this?
| Path | Role |
|---|---|
drashta/ |
Python SDK |
drashta/receipt_engine/ |
Timeline, verify, PDF (also used by AWS Lambdas) |
tests/ |
pytest suite |
infra/modules/aws/ |
Terraform module (ingest, storage, receipt API) |
infra/example/ |
Example terraform apply + outputs |
dashboard/ |
Developer portal (Firebase + portal API) |
scripts/ |
Smoke ingest, download receipt PDF |
docs/MVP.MD |
Full scope, status, Component 4 plan |
docs/PUBLISHING.md |
PyPI release checklist |
Status
| Component | Status |
|---|---|
| SDK + tests | In repo (pip install -e .; PyPI — see docs/PUBLISHING.md) |
| Ingest + storage + receipt API | Deployed via Terraform |
| Developer portal | Shipped — API keys, runs list/detail, Merkle tree, PDF (local: dashboard/) |
Quickstart (SDK)
pip install -e . # from repo root; PyPI publish TBD
from drashta import Drashta
async def main():
async with Drashta(api_key="your-key").observe("my-agent") as run:
run.log_decision("approve claim", confidence=0.92, outcome="approved")
print(run.last_receipt["merkle_root"])
Point ingest at your deploy:
from drashta import Drashta
from drashta.emitter import Emitter
endpoint = "https://....execute-api.us-east-1.amazonaws.com/v1/v1/events" # terraform output
emitter = Emitter(api_key="your-key", endpoint=endpoint)
async with Drashta(api_key="your-key", emitter=emitter).observe("my-agent") as run:
...
Deploy (AWS)
# Repo root — set admin key for Terraform
echo 'export TF_VAR_drashta_api_key="your-secret"' >> .env
source .env
cd infra/example
terraform init
terraform apply
terraform output -raw ingest_endpoint # SDK ingest URL
terraform output -raw receipt_endpoint # base for /{run_id}/receipt[.pdf]
Use the same key as X-Drashta-Key on all HTTP calls, or create a dra_live_… key in the dashboard for per-developer ingest.
URL note: API Gateway stage v1 plus resource /v1 produces paths like .../v1/v1/events. Use terraform output values exactly—do not drop a /v1.
Developer portal
cd dashboard
cp .env.local.example .env.local # Firebase + VITE_PORTAL_API_BASE from terraform output
npm install && npm run dev # http://localhost:3000
Sign in → API keys → create dra_live_… → use in SDK. Runs tab lists ingested runs; open a run for timeline, hash chain, Merkle tree, and PDF download.
Deploy to Firebase Hosting: see dashboard/README.md.
Verify the loop
Ingest a run:
source .env
export DRASHTA_API_KEY="$TF_VAR_drashta_api_key"
export DRASHTA_INGEST_URL="$(cd infra/example && terraform output -raw ingest_endpoint)"
python scripts/smoke_ingest.py
Download receipt PDF (replace RUN_ID with output from smoke test or a known run):
chmod +x scripts/download_receipt.sh
./scripts/download_receipt.sh RUN_ID
# writes infra/example/receipt.pdf
Or with curl (do not pipe through base64; API Gateway returns raw PDF bytes):
cd infra/example && source ../../.env
BASE=$(terraform output -raw receipt_endpoint)
curl -s -H "X-Drashta-Key: $TF_VAR_drashta_api_key" \
"$BASE/RUN_ID/receipt.pdf" -o receipt.pdf
file receipt.pdf # should say: PDF document
Receipt JSON + verification (chain_ok, merkle_ok, signature_ok):
curl -s -H "X-Drashta-Key: $TF_VAR_drashta_api_key" \
"$BASE/RUN_ID/receipt" | python -m json.tool
Integrity (short)
- Hash chain — each step’s
hashlinks viaprev_hash; tampering breaks the chain. - Merkle root — single digest over all step hashes; KMS signs the root on ingest.
- Details:
drashta/hasher.py,drashta/receipt_engine/verify.py, and docs/MVP.MD.
Roadmap
Component 4d (polish): Merkle tree visualization and per-step chain badges in the dashboard; PyPI publish prep — see docs/PUBLISHING.md.
Optional next: Firebase Hosting production deploy, Merkle inclusion proofs, JS SDK.
Full architecture: docs/MVP.MD.
Tests
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file drashta-0.1.0.tar.gz.
File metadata
- Download URL: drashta-0.1.0.tar.gz
- Upload date:
- Size: 20.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c5a8f7040003767afa27e7ee7186f3c83e92228b4f29c71506ffe9c3ef988da
|
|
| MD5 |
7cf0e158c66233aa203fe1b7584e3e23
|
|
| BLAKE2b-256 |
033bdd8015a41f2c50a1f2f7d454440309108881e20532b17c722bbdea206480
|
File details
Details for the file drashta-0.1.0-py3-none-any.whl.
File metadata
- Download URL: drashta-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5006a7afcabd3618e757f1e0841cea8a27551571c1e10db1e593dd5af160fa10
|
|
| MD5 |
a5a690c76b4f0c9e1dbe11797c984cd7
|
|
| BLAKE2b-256 |
b846750d5b9b9e9437ecd9619c2cb94180dd78452cbeb9bf43137a870bcf1d75
|