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
Metadata
Release files for drashta 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drashta-0.1.0.tar.gz | 20.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drashta-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.7 kB
Release files / drashta-0.1.0.tar.gz
| Download URL | drashta-0.1.0.tar.gz |
|---|---|
| Size | 20.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c5a8f7040003767afa27e7ee7186f3c83e92228b4f29c71506ffe9c3ef988da
|
|
BLAKE2b-256 checksum How to use checksums |
033bdd8015a41f2c50a1f2f7d454440309108881e20532b17c722bbdea206480
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / drashta-0.1.0-py3-none-any.whl
| Download URL | drashta-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5006a7afcabd3618e757f1e0841cea8a27551571c1e10db1e593dd5af160fa10
|
|
BLAKE2b-256 checksum How to use checksums |
b846750d5b9b9e9437ecd9619c2cb94180dd78452cbeb9bf43137a870bcf1d75
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|