{"id":47588285,"url":"https://github.com/jefftrojan/robopotato","last_synced_at":"2026-04-01T16:53:07.449Z","repository":{"id":345212188,"uuid":"1184935320","full_name":"jefftrojan/robopotato","owner":"jefftrojan","description":"Lightweight inter-agent trust, coordinatination and shared state server for AI agent swarms","archived":false,"fork":false,"pushed_at":"2026-03-18T07:45:54.000Z","size":4165,"stargazers_count":3,"open_issues_count":5,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-18T20:45:41.311Z","etag":null,"topics":["agent-framework","agentic-ai","agents","ai-agents","axum","collaborate","github","hmac","key-value-store","llm","multi-agent","rust","security","tokio","websocket"],"latest_commit_sha":null,"homepage":"","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/jefftrojan.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":"audit.toml","citation":null,"codeowners":null,"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":{"github":["jefftrojan"]}},"created_at":"2026-03-18T04:27:05.000Z","updated_at":"2026-03-18T07:45:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jefftrojan/robopotato","commit_stats":null,"previous_names":["jefftrojan/robopotato"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jefftrojan/robopotato","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jefftrojan%2Frobopotato","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jefftrojan%2Frobopotato/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jefftrojan%2Frobopotato/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jefftrojan%2Frobopotato/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jefftrojan","download_url":"https://codeload.github.com/jefftrojan/robopotato/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jefftrojan%2Frobopotato/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: 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-framework","agentic-ai","agents","ai-agents","axum","collaborate","github","hmac","key-value-store","llm","multi-agent","rust","security","tokio","websocket"],"created_at":"2026-04-01T16:53:06.783Z","updated_at":"2026-04-01T16:53:07.437Z","avatar_url":"https://github.com/jefftrojan.png","language":"Python","readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/robopotato_logo.png\" alt=\"robopotato\" width=\"160\" /\u003e\n\n# robopotato\n\n**The missing trust layer for AI agent swarms.**\n\n[![CI](https://github.com/jefftrojan/robopotato/actions/workflows/ci.yml/badge.svg)](https://github.com/jefftrojan/robopotato/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Rust](https://img.shields.io/badge/rust-1.75%2B-orange.svg)](https://www.rust-lang.org)\n[![crates.io](https://img.shields.io/crates/v/robopotato.svg)](https://crates.io/crates/robopotato)\n\n*Cryptographic identity · namespaced shared state · optimistic concurrency control*\n\n[Quick start](#quick-start) · [API reference](#api-reference) · [Demo](#live-demo) · [Whitepaper](WHITEPAPER.md) · [Contributing](CONTRIBUTING.md)\n\n\u003c/div\u003e\n\n---\n\n## The problem\n\nThe moment you run more than one AI agent in the same environment, three things go wrong:\n\n| Failure mode | What happens without robopotato |\n|---|---|\n| **Identity spoofing** | Agent B claims to be Agent A. There is no cryptographic check. Trust is a prompt. |\n| **Unauthorized mutation** | Any agent can overwrite any shared state. A confused worker corrupts the orchestrator's config silently. |\n| **Silent concurrency conflicts** | Two agents read version 3, both write version 4. Last writer wins. The first write disappears. Nobody notices. |\n\nrobopotato fixes all three at the infrastructure layer — not the prompt layer.\n\n---\n\n## Live demo\n\nStart the server, then run:\n\n```bash\nROBOPOTATO_SECRET=test-secret cargo run \u0026\n./demo.sh\n```\n\n```\n▶ Registering agents\n  ✓ Orchestrator registered  (id: a1b2c3d4...)\n  ✓ Worker registered         (id: e5f6a7b8...)\n  ✓ Observer registered       (id: c9d0e1f2...)\n  ✓ Rogue worker registered   (id: 33445566...)\n\n▶ Namespace isolation — workers cannot write global.*\n  ✓ Orchestrator writes global.config → HTTP 200\n  ✗ BLOCKED — Worker PUT global.config → HTTP 403 (missing capability: state_write_global)\n\n▶ Observer is read-only — cannot write shared.*\n  ✗ BLOCKED — Observer PUT shared.results → HTTP 403 (missing capability: state_write_shared)\n\n▶ Agent namespace isolation — workers cannot write each other's state\n  ✗ BLOCKED — Worker PUT agent.\u003corchestrator\u003e.private → HTTP 403 (not the owner)\n  ✓ Worker PUT agent.\u003cself\u003e.private → HTTP 200 (owner allowed)\n\n▶ Optimistic Concurrency Control — concurrent writers, one wins\n  ✓ Worker A writes shared.task (expected_version=1) → HTTP 200\n  ✗ BLOCKED — Worker B writes shared.task (expected_version=1) → HTTP 409 (version conflict: stale read detected)\n\n▶ Mid-task revocation — rogue agent blocked after orchestrator revokes\n  ✓ Rogue agent writes before revocation → HTTP 200\n  ✓ Orchestrator revokes rogue agent → HTTP 200\n  ✗ BLOCKED — Rogue agent write after revocation → HTTP 401 (agent has been revoked)\n\n▶ Token forgery — wrong HMAC secret is rejected\n  ✗ BLOCKED — Forged token PUT global.pwned → HTTP 401 (invalid token signature)\n\n  Summary\n\n  ✓  Namespace isolation    workers cannot touch global.* or other agents' namespaces\n  ✓  Role enforcement       observers are permanently read-only\n  ✓  OCC conflict detection concurrent stale writes produce 409, not silent overwrites\n  ✓  Mid-task revocation    revoked tokens rejected immediately, no restart needed\n  ✓  Token forgery rejected wrong HMAC secret → 401 every time\n\n  All of the above enforced at the infrastructure layer.\n  No prompt-engineering required.\n```\n\n---\n\n## Quick start\n\n```bash\ngit clone https://github.com/jefftrojan/robopotato\ncd robopotato\nROBOPOTATO_SECRET=change-me cargo run --release\n```\n\nServer starts on `http://127.0.0.1:7878`. Register an agent and start calling:\n\n```bash\n# Register\nTOKEN=$(curl -sf -X POST http://127.0.0.1:7878/agents/register \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"role\":\"worker\"}' | python3 -c \"import sys,json; print(json.load(sys.stdin)['token'])\")\n\n# Write shared state\ncurl -X PUT http://127.0.0.1:7878/state/shared.task \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"value\": {\"status\": \"pending\"}}'\n\n# Read it back\ncurl http://127.0.0.1:7878/state/shared.task \\\n  -H \"Authorization: Bearer $TOKEN\"\n```\n\nWith SQLite persistence across restarts:\n\n```bash\nROBOPOTATO_SECRET=change-me \\\nROBOPOTATO_PERSIST=true \\\nROBOPOTATO_DB_PATH=./robopotato.db \\\ncargo run --release --features persist\n```\n\n---\n\n## How it works\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                        robopotato                           │\n│                                                             │\n│  POST /agents/register  →  HMAC-SHA256 capability token     │\n│                                                             │\n│  PUT  /state/{key}      →  verify token                     │\n│                            check capability for namespace   │\n│                            check expected_version (OCC)     │\n│                            write + publish event            │\n│                                                             │\n│  GET  /events (WS)      →  live stream of all changes       │\n└─────────────────────────────────────────────────────────────┘\n       ↑                          ↑                    ↑\n  orchestrator               worker(s)            observer(s)\n```\n\nTokens are `base64url(claims_json).hex(hmac_sha256)` — no JWT library, no asymmetric key management, no external auth service. Drop robopotato next to your agents and point them at it.\n\n---\n\n## Features\n\n| | |\n|---|---|\n| **HMAC-SHA256 tokens** | Signed capability tokens. Constant-time verification. No JWT dependency. |\n| **Three roles** | `orchestrator` · `worker` · `observer` |\n| **Nine capabilities** | `state_read/write_{global,shared,own}` · `agent_list` · `agent_revoke` · `token_verify` |\n| **Namespaced KV store** | `global.*` · `shared.*` · `agent.\u003cid\u003e.*` with per-namespace write rules |\n| **OCC** | `expected_version` on writes → 409 Conflict on stale reads instead of silent overwrites |\n| **Agent revocation** | Orchestrators revoke agents mid-flight; takes effect on the next request |\n| **WebSocket event bus** | Live stream of `StateChanged`, `StateDeleted`, `AgentRegistered`, `AgentRevoked` |\n| **SQLite persistence** | `--features persist` — WAL mode, write-through, startup recovery |\n| **Framework-agnostic** | Plain JSON over HTTP — Python, Node, Go, curl, anything |\n| **Self-contained** | Single Rust binary, no external infrastructure |\n\n---\n\n## Capability matrix\n\n| Capability | Orchestrator | Worker | Observer |\n|---|:---:|:---:|:---:|\n| `state_read_global` | ✓ | ✓ | ✓ |\n| `state_read_shared` | ✓ | ✓ | ✓ |\n| `state_read_own` | ✓ | ✓ | ✓ |\n| `state_write_global` | ✓ | — | — |\n| `state_write_shared` | ✓ | ✓ | — |\n| `state_write_own` | ✓ | ✓ | — |\n| `agent_list` | ✓ | ✓ | ✓ |\n| `agent_revoke` | ✓ | — | — |\n| `token_verify` | ✓ | ✓ | ✓ |\n\n---\n\n## API reference\n\n### Public endpoints\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `/health` | Liveness probe |\n| `POST` | `/agents/register` | Register agent, receive signed token |\n| `POST` | `/tokens/verify` | Verify token validity + revocation status |\n| `GET` | `/events` | WebSocket — live event stream |\n\n### Protected endpoints (Bearer token required)\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `/state/{key}` | Read a state entry |\n| `PUT` | `/state/{key}` | Write a state entry (optional OCC via `expected_version`) |\n| `DELETE` | `/state/{key}` | Delete a state entry |\n| `GET` | `/state/namespace/{ns}` | List all keys under a namespace prefix |\n| `DELETE` | `/agents/{id}` | Revoke an agent (orchestrator only) |\n\n**OCC write example:**\n```jsonc\n// PUT /state/shared.task\n{\n  \"value\": { \"status\": \"done\" },\n  \"expected_version\": 3   // omit for last-writer-wins; 409 if current version ≠ 3\n}\n```\n\n---\n\n## Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `ROBOPOTATO_SECRET` | **required** | HMAC signing secret |\n| `ROBOPOTATO_HOST` | `127.0.0.1` | Bind address |\n| `ROBOPOTATO_PORT` | `7878` | Bind port |\n| `ROBOPOTATO_TOKEN_TTL` | `3600` | Token lifetime (seconds) |\n| `ROBOPOTATO_PERSIST` | `false` | Enable SQLite persistence |\n| `ROBOPOTATO_DB_PATH` | `robopotato.db` | SQLite file path |\n\n---\n\n## Testing\n\n```bash\n# Unit tests (no server)\ncargo test\ncargo test --features persist\n\n# Adversarial integration tests (20 scenarios)\nROBOPOTATO_SECRET=test-secret cargo run \u0026\ncd tests \u0026\u0026 python3 test_adversarial.py -v\n\n# With/without comparison using Claude Code agents\ncd tests \u0026\u0026 python3 compare.py\n```\n\nAdversarial scenarios include: expired token replay, wrong-secret forgery, payload tampering, cross-namespace pollution, observer write attempts, mid-task revocation, OCC storm (5 concurrent writers), and malformed token formats.\n\n---\n\n## Project structure\n\n```\nsrc/\n├── main.rs                  # Router, WebSocket handler\n├── auth/\n│   ├── token.rs             # TokenEngine: sign, verify, claims\n│   └── middleware.rs        # Bearer token enforcement\n├── state/\n│   ├── store.rs             # RwLock KV store with OCC\n│   ├── namespace.rs         # Namespace parsing + capability mapping\n│   └── persistence.rs       # SQLite write-through (--features persist)\n├── events/bus.rs            # Tokio broadcast event bus\n└── routes/                  # agents, state, tokens handlers\ntests/\n├── test_adversarial.py      # 20 programmatic adversarial tests\n├── robopotato_client.py     # Python HTTP client\n└── compare.py               # With/without Claude Code comparison\n```\n\n---\n\n## Why not X?\n\n| | robopotato | Redis | a shared database | prompt instructions |\n|---|---|---|---|---|\n| Cryptographic agent identity | ✓ | — | — | — |\n| Per-namespace capability enforcement | ✓ | — | — | — |\n| OCC with version conflicts | ✓ | partial | partial | — |\n| Agent revocation | ✓ | — | — | — |\n| Live event bus | ✓ | ✓ | — | — |\n| Self-contained single binary | ✓ | — | — | ✓ |\n| Works with any AI framework | ✓ | ✓ | ✓ | ✓ |\n\nrobopotato is not a general-purpose database. It is a trust and coordination primitive specifically shaped for AI agent workloads.\n\n---\n\n## Whitepaper\n\n[WHITEPAPER.md](WHITEPAPER.md) covers the threat model, research context, cryptographic design, and evaluation methodology with 40+ citations.\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues are labelled [`good first issue`](https://github.com/jefftrojan/robopotato/issues?q=is%3Aopen+label%3A%22good+first+issue%22).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","funding_links":["https://github.com/sponsors/jefftrojan"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjefftrojan%2Frobopotato","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjefftrojan%2Frobopotato","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjefftrojan%2Frobopotato/lists"}