{"id":49109660,"url":"https://github.com/ExposureGuard/haldir","last_synced_at":"2026-05-07T10:00:57.187Z","repository":{"id":349049788,"uuid":"1200099600","full_name":"ExposureGuard/haldir","owner":"ExposureGuard","description":"The guardian layer for AI agents — identity, secrets, audit via MCP. Gate + Vault + Watch.","archived":false,"fork":false,"pushed_at":"2026-04-19T00:25:19.000Z","size":623,"stargazers_count":2,"open_issues_count":3,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-19T00:40:15.094Z","etag":null,"topics":["agent-auth","agent-governance","ai-agents","ai-security","audit","audit-log","compliance","crewai","governance","human-in-the-loop","identity","langchain","mcp","mcp-server","model-context-protocol","proxy","secrets","security","spend-control","vercel-ai-sdk"],"latest_commit_sha":null,"homepage":"https://haldir.xyz","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ExposureGuard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://haldir.xyz","https://haldir.xyz/pricing"]}},"created_at":"2026-04-03T03:17:55.000Z","updated_at":"2026-04-19T00:25:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ExposureGuard/haldir","commit_stats":null,"previous_names":["exposureguard/haldir"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/ExposureGuard/haldir","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExposureGuard%2Fhaldir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExposureGuard%2Fhaldir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExposureGuard%2Fhaldir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExposureGuard%2Fhaldir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ExposureGuard","download_url":"https://codeload.github.com/ExposureGuard/haldir/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExposureGuard%2Fhaldir/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32732349,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-07T02:14:30.463Z","status":"ssl_error","status_checked_at":"2026-05-07T02:14:29.405Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-auth","agent-governance","ai-agents","ai-security","audit","audit-log","compliance","crewai","governance","human-in-the-loop","identity","langchain","mcp","mcp-server","model-context-protocol","proxy","secrets","security","spend-control","vercel-ai-sdk"],"created_at":"2026-04-21T04:00:25.541Z","updated_at":"2026-05-07T10:00:57.165Z","avatar_url":"https://github.com/ExposureGuard.png","language":"Python","funding_links":["https://haldir.xyz","https://haldir.xyz/pricing"],"categories":["Cloud Infrastructure","MCP Servers","📦 Other"],"sub_categories":["🔒 Security"],"readme":"\u003c!-- mcp-name: io.github.ExposureGuard/haldir --\u003e\n# Haldir — The Guardian Layer for AI Agents\n\n[![tests](https://github.com/ExposureGuard/haldir/actions/workflows/test.yml/badge.svg)](https://github.com/ExposureGuard/haldir/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/ExposureGuard/haldir/branch/main/graph/badge.svg)](https://codecov.io/gh/ExposureGuard/haldir)\n[![type-checked: mypy](https://img.shields.io/badge/type--checked-mypy-1f5082)](https://github.com/ExposureGuard/haldir/blob/main/mypy.ini)\n[![Smithery](https://smithery.ai/badge/haldir)](https://smithery.ai/server/haldir/haldir)\n[![PyPI](https://img.shields.io/pypi/v/haldir)](https://pypi.org/project/haldir/)\n[![PyPI Downloads](https://img.shields.io/pypi/dm/haldir)](https://pypi.org/project/haldir/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Security: SECURITY.md](https://img.shields.io/badge/security-policy-brightgreen)](SECURITY.md)\n[![GitHub Stars](https://img.shields.io/github/stars/ExposureGuard/haldir?style=social)](https://github.com/ExposureGuard/haldir)\n[![SafeSkill 89/100](https://img.shields.io/badge/SafeSkill-89%2F100_Passes%20with%20Notes-yellow)](https://safeskill.dev/scan/exposureguard-haldir)\n\n**The open-source governance layer for AI agents.** Identity, secrets, audit, and policy enforcement — MIT licensed, self-host or use our cloud.\n\nHaldir enforces governance on every AI agent tool call: scoped sessions with spend caps, encrypted secrets the model never sees, hash-chained tamper-evident audit trail, human-in-the-loop approvals, and a proxy that intercepts every MCP call before it reaches your tools. Native SDKs for LangChain, CrewAI, AutoGen, and Vercel AI SDK.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"demo/quickstart.svg\" alt=\"Haldir quickstart: install, create a scoped session, check permission, log the action to the hash-chained audit trail\" width=\"780\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/architecture.svg\" alt=\"Haldir architecture: Agent → Proxy → (Gate/Vault/Watch/Policy) → Upstream APIs\" width=\"820\"\u003e\n\u003c/p\u003e\n\n## CLI\n\n```text\n$ haldir overview\n\n  Haldir tenant overview\n  acct_xyz123  ·  tier pro  ·  2026-04-19T18:42:11+00:00\n\n  Status     ● ok\n  Actions      4,217 / 50,000   ████░░░░░░░░░░░░░░░░    8.4%\n  Spend      $ 47.30 this month\n  Sessions        12 active  ·  3/10 agents\n  Vault            8 secrets  ·  62 accesses this month\n  Audit        1,847 entries  ·  0 flagged (7d)  ·  chain ✓\n  Webhooks         2 registered  ·  541 deliveries (24h)  ·  99.82% success\n  Approvals        1 pending\n```\n\nInstall once, drive the whole platform from the terminal:\n\n```bash\npip install haldir\nhaldir login                           # one-time; stashes API key\nhaldir overview --watch                # top-style live dashboard\nhaldir status                          # green/yellow/red component pills\nhaldir ready                           # exits 0/1, perfect for CI\nhaldir audit tail --agent my-bot       # the last N entries\nhaldir audit export --format=jsonl --out audit-2026-04.jsonl\nhaldir audit verify                    # hash chain integrity check\nhaldir webhooks deliveries             # last 20 retry attempts\nhaldir migrate up                      # apply pending schema migrations\n```\n\nEvery command takes `--json` for scripts. `haldir --help` for the full surface.\n\n## Two ways to run Haldir\n\n| | Self-host | Cloud ([haldir.xyz](https://haldir.xyz)) |\n|---|---|---|\n| Price | Free forever | Free tier + paid plans |\n| Features | Everything | Everything — same API, same SDKs |\n| You run | API + Postgres | Nothing |\n| Best for | Regulated industries, air-gapped, \"must own data\" | \"Just make it work\" |\n\n### Self-host in 5 minutes\n\n```bash\ngit clone https://github.com/ExposureGuard/haldir.git\ncd haldir\ncp .env.example .env\npython3 -c 'import base64, os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'\n# paste the output into .env as HALDIR_ENCRYPTION_KEY, then:\ndocker compose up -d\ncurl http://localhost:8000/health\n```\n\nFull self-hosting guide: [SELF_HOSTING.md](SELF_HOSTING.md)\n\n### Or use our cloud\n\n```bash\npip install haldir\n```\n\nThat's it — point at `https://haldir.xyz`, no signup, live API.\n\n---\n\n\u003e **Live now:** [haldir.xyz](https://haldir.xyz) · [API Docs](https://haldir.xyz/docs) · [OpenAPI Spec](https://haldir.xyz/openapi.json) · [Smithery](https://smithery.ai/server/haldir/haldir)\n\u003e\n\u003e 🧪 **Now accepting 5 design partners.** 30 days free, full access, direct line to the founder. If you're shipping AI agents to production, email [sterling@haldir.xyz](mailto:sterling@haldir.xyz?subject=Haldir%20Design%20Partner).\n\n## Performance\n\nHaldir is fast enough to sit in the hot path of every agent tool call without becoming the bottleneck.\n\n**Single-box HTTP throughput** (gunicorn 4 workers, 32 concurrent clients, tuned SQLite backend, every request goes through the full middleware stack — auth, validation, idempotency, metrics, structured logging):\n\n| Endpoint | RPS | p50 | p95 | p99 |\n| --- | --- | --- | --- | --- |\n| `GET /healthz` | 1,638 | 19.1 ms | 32.5 ms | 41.6 ms |\n| `GET /v1/status` | 1,382 | 22.2 ms | 30.8 ms | 45.4 ms |\n| `GET /v1/sessions/:id` | 903 | 29.2 ms | 95.5 ms | 172.1 ms |\n| `POST /v1/sessions` (create) | 1,142 | 27.7 ms | 35.2 ms | 39.9 ms |\n| `POST /v1/audit` (hash-chain write) | 1,092 | 28.7 ms | 37.6 ms | 52.6 ms |\n\nHardware: 12th-gen Intel Core i3-1215U (8 cores, 8 GB RAM). SQLite is configured with WAL + synchronous=NORMAL + 256 MiB mmap + in-memory temp store — the session-lookup p99 dropped by 52 % versus the untuned path. Postgres deployments (configurable pool via `HALDIR_PG_POOL_MIN/MAX`) flatten the p99 further still; enable via `DATABASE_URL=postgresql://...`.\n\n**Primitive cost** (pure-Python, no I/O):\n\n| Primitive | p50 | Notes |\n|---|---|---|\n| `Vault.store_secret` (AES-256-GCM encrypt + AAD binding) | **\u003c 10 µs** | in-memory, no DB write |\n| `Vault.get_secret` (AES-256-GCM decrypt + AAD verify) | **\u003c 10 µs** | in-memory |\n| `AuditEntry.compute_hash` (SHA-256 over canonical payload) | **\u003c 10 µs** | |\n| `Gate.check_permission` over REST | ~50-120 ms | network + DB round-trip, Cloudflare-fronted |\n| `Watch.log_action` over REST | ~50-150 ms | includes chain lookup + DB write |\n| Full governed-tool envelope (check + log) | ~100-250 ms | |\n\nAgents typically wait 500-3000 ms for an LLM completion and 100-1000 ms for an upstream API call, so Haldir's overhead sits inside the noise. Reproduce locally:\n\n```bash\n# Concurrent HTTP throughput (launches a local gunicorn, ~60s total)\npython bench/bench_http.py --duration 10 --concurrency 32 --workers 4\n\n# Primitive cost only (no API key needed)\npython bench/bench_primitives.py --local\n\n# End-to-end against the hosted service\nexport HALDIR_API_KEY=hld_...\npython bench/bench_primitives.py\n```\n\n## Compliance\n\nOne endpoint produces an auditor-ready proof-of-control pack covering eight sections, each anchored to a SOC2 trust services criterion:\n\n```bash\nhaldir compliance evidence --since 2026-01-01 --out evidence-q1-2026.md\n```\n\n| # | Section | SOC2 |\n| --- | --- | --- |\n| 1 | Identity (tenant, subscription, period) | — |\n| 2 | Access control (API keys + per-key scopes) | CC6.1 |\n| 3 | Encryption (AES-256-GCM, AAD binding) | CC6.7 |\n| 4 | Audit trail (entry count, hash chain integrity) | CC7.2 |\n| 5 | Spend governance (per-session caps, payment records) | CC5.2 |\n| 6 | Human approvals (request/decision lifecycle) | CC8.1 |\n| 7 | Outbound alerting (webhook delivery success rate) | CC7.3 |\n| 8 | Document signature (SHA-256 self-hash) | — |\n\nThe pack signs itself: a SHA-256 over the canonical JSON of sections 1-7. An auditor receiving an archived pack can re-call `/v1/compliance/evidence/manifest` and confirm the digest matches — proof the document was not modified after issuance.\n\nJSON for evidence-locker upload, Markdown for the \"show this to the auditor\" moment, both from the same `/v1/compliance/evidence` endpoint.\n\n## Why Haldir\n\nAI agents are calling APIs, spending money, and accessing credentials with zero oversight. Haldir is the missing layer:\n\n| Without Haldir | With Haldir |\n|---|---|\n| Agent has unlimited access | Scoped sessions with permissions |\n| Secrets in plaintext env vars | AES-encrypted vault with access control |\n| No spend limits | Per-session budget enforcement |\n| No record of what happened | Immutable audit trail |\n| No human oversight | Approval workflows with webhooks |\n| Agent talks to tools directly | Proxy intercepts and enforces policies |\n\n## Quick Start\n\n```bash\npip install haldir\n```\n\n```python\nfrom sdk.client import HaldirClient\n\nh = HaldirClient(api_key=\"hld_xxx\", base_url=\"https://haldir.xyz\")\n\n# Create a governed agent session\nsession = h.create_session(\"my-agent\", scopes=[\"read\", \"spend:50\"])\n\n# Store secrets agents never see directly\nh.store_secret(\"stripe_key\", \"sk_live_xxx\")\n\n# Retrieve with scope enforcement\nkey = h.get_secret(\"stripe_key\", session_id=session[\"session_id\"])\n\n# Authorize payments against budget\nh.authorize_payment(session[\"session_id\"], 29.99)\n\n# Every action is logged\nh.log_action(session[\"session_id\"], tool=\"stripe\", action=\"charge\", cost_usd=29.99)\n\n# Revoke when done\nh.revoke_session(session[\"session_id\"])\n```\n\n## Products\n\n### Gate — Agent Identity \u0026 Auth\nScoped sessions with permissions, spend limits, and TTL. No session = no access.\n\n```bash\ncurl -X POST https://haldir.xyz/v1/sessions \\\n  -H \"Authorization: Bearer hld_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"agent_id\": \"my-bot\", \"scopes\": [\"read\", \"browse\", \"spend:50\"], \"ttl\": 3600}'\n```\n\n### Vault — Encrypted Secrets \u0026 Payments\nAES-encrypted storage. Agents request access; Vault checks session scope. Payment authorization with per-session budgets.\n\n```bash\ncurl -X POST https://haldir.xyz/v1/secrets \\\n  -H \"Authorization: Bearer hld_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"api_key\", \"value\": \"sk_live_xxx\", \"scope_required\": \"read\"}'\n```\n\n### Watch — Audit Trail \u0026 Compliance\nImmutable log for every action. Anomaly detection. Cost tracking. Compliance exports.\n\n```bash\ncurl https://haldir.xyz/v1/audit?agent_id=my-bot \\\n  -H \"Authorization: Bearer hld_xxx\"\n```\n\n### Proxy — Enforcement Layer\nSits between agents and MCP servers. Every tool call is intercepted, authorized, and logged. Supports policy enforcement: allow lists, deny lists, spend limits, rate limits, time windows.\n\n```bash\n# Register an upstream MCP server\ncurl -X POST https://haldir.xyz/v1/proxy/upstreams \\\n  -H \"Authorization: Bearer hld_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"myserver\", \"url\": \"https://my-mcp-server.com/mcp\"}'\n\n# Call through the proxy — governance enforced\ncurl -X POST https://haldir.xyz/v1/proxy/call \\\n  -H \"Authorization: Bearer hld_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tool\": \"scan_domain\", \"arguments\": {\"domain\": \"example.com\"}, \"session_id\": \"ses_xxx\"}'\n```\n\n### Approvals — Human-in-the-Loop\nPause agent execution for human review. Webhook notifications. Approve or deny from dashboard or API.\n\n```bash\n# Require approval for spend over $100\ncurl -X POST https://haldir.xyz/v1/approvals/rules \\\n  -H \"Authorization: Bearer hld_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\": \"spend_over\", \"threshold\": 100}'\n```\n\n## MCP Server\n\nHaldir is available as an MCP server with 10 tools for Claude, Cursor, Windsurf, and any MCP-compatible AI:\n\n```json\n{\n  \"mcpServers\": {\n    \"haldir\": {\n      \"command\": \"haldir-mcp\",\n      \"env\": {\n        \"HALDIR_API_KEY\": \"hld_xxx\"\n      }\n    }\n  }\n}\n```\n\n**MCP Tools:** `createSession`, `getSession`, `revokeSession`, `checkPermission`, `storeSecret`, `getSecret`, `authorizePayment`, `logAction`, `getAuditTrail`, `getSpend`\n\n**MCP HTTP Endpoint:** `POST https://haldir.xyz/mcp`\n\n## Architecture\n\n```\nAgent (Claude, GPT, Cursor, etc.)\n    │\n    ▼\n┌─────────────────────────────┐\n│       Haldir Proxy          │  ← Intercepts every tool call\n│  Policy enforcement layer   │\n└──────┬──────────┬───────────┘\n       │          │\n  ┌────▼────┐ ┌───▼────┐\n  │  Gate   │ │ Watch  │\n  │identity │ │ audit  │\n  │sessions │ │ costs  │\n  └────┬────┘ └────────┘\n       │\n  ┌────▼────┐\n  │ Vault   │\n  │secrets  │\n  │payments │\n  └────┬────┘\n       │\n       ▼\n  Upstream MCP Servers\n  (your actual tools)\n```\n\n## API Reference\n\nFull docs at [haldir.xyz/docs](https://haldir.xyz/docs)\n\n| Endpoint | Method | Description |\n|---|---|---|\n| `/v1/keys` | POST | Create API key |\n| `/v1/sessions` | POST | Create agent session |\n| `/v1/sessions/:id` | GET | Get session info |\n| `/v1/sessions/:id` | DELETE | Revoke session |\n| `/v1/sessions/:id/check` | POST | Check permission |\n| `/v1/secrets` | POST | Store secret |\n| `/v1/secrets/:name` | GET | Retrieve secret |\n| `/v1/secrets` | GET | List secrets |\n| `/v1/secrets/:name` | DELETE | Delete secret |\n| `/v1/payments/authorize` | POST | Authorize payment |\n| `/v1/audit` | POST | Log action |\n| `/v1/audit` | GET | Query audit trail |\n| `/v1/audit/spend` | GET | Spend summary |\n| `/v1/approvals/rules` | POST | Add approval rule |\n| `/v1/approvals/request` | POST | Request approval |\n| `/v1/approvals/:id` | GET | Check approval status |\n| `/v1/approvals/:id/approve` | POST | Approve |\n| `/v1/approvals/:id/deny` | POST | Deny |\n| `/v1/approvals/pending` | GET | List pending |\n| `/v1/webhooks` | POST | Register webhook |\n| `/v1/webhooks` | GET | List webhooks |\n| `/v1/proxy/upstreams` | POST | Register upstream |\n| `/v1/proxy/tools` | GET | List proxy tools |\n| `/v1/proxy/call` | POST | Call through proxy |\n| `/v1/proxy/policies` | POST | Add policy |\n| `/v1/usage` | GET | Usage stats |\n| `/v1/metrics` | GET | Platform metrics |\n\n## Agent Discovery\n\nHaldir is discoverable through every major protocol:\n\n| URL | Protocol |\n|---|---|\n| `haldir.xyz/openapi.json` | OpenAPI 3.1 |\n| `haldir.xyz/llms.txt` | LLM-readable docs |\n| `haldir.xyz/.well-known/ai-plugin.json` | ChatGPT plugins |\n| `haldir.xyz/.well-known/mcp/server-card.json` | MCP discovery |\n| `haldir.xyz/mcp` | MCP JSON-RPC |\n| `smithery.ai/server/haldir/haldir` | Smithery registry |\n| `pypi.org/project/haldir` | PyPI |\n\n## License\n\nMIT\n\n## Links\n\n- **Website:** [haldir.xyz](https://haldir.xyz)\n- **API Docs:** [haldir.xyz/docs](https://haldir.xyz/docs)\n- **Smithery:** [View on Smithery](https://smithery.ai/server/haldir/haldir)\n- **PyPI:** [haldir](https://pypi.org/project/haldir/)\n- **OpenAPI:** [haldir.xyz/openapi.json](https://haldir.xyz/openapi.json)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FExposureGuard%2Fhaldir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FExposureGuard%2Fhaldir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FExposureGuard%2Fhaldir/lists"}