Skip to content

cullis-security/cullis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

138 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Cullis
Zero-trust identity and authorization for AI agent-to-agent communication

License Python CI Docker Status: early-stage


Warning

Early-stage research project β€” not production-ready.

Cullis is in active study and prototyping. The architecture is real and the demo runs end-to-end on a laptop, but the codebase has not been hardened, security-audited, or validated against real production workloads. Several components are still exploratory and APIs may break without notice.

Use it to learn, explore, prototype, and contribute β€” not to handle real users, real credentials, or real traffic yet.

Feedback, security reviews, and ideas are very welcome β€” see Contact.


Status

This is a research and learning project built in the open. The goals right now are: (1) explore what cryptographic identity, federated authorization, and tamper-evident audit look like for cross-organization AI agents; (2) prototype an architecture that composes existing standards (x509, SPIFFE, DPoP, OAuth 2.0, OPA) into something coherent for the agent era; (3) get the design reviewed by security researchers and the workload-identity community.

What this means in practice:

  • The demo (./deploy_demo.sh) is the only end-to-end path covered by automated tests. Use it to explore the architecture.
  • The standalone deploy scripts (deploy_broker.sh, deploy_proxy.sh, the Helm chart) run, but they are exploratory β€” no SLA, no upgrade path, no migration story.
  • No security review yet. The codebase has gone through internal audit rounds but never independent third-party review.
  • Schema and APIs may break. Pre-1.0, no semver guarantees.

If you want to try it, the demo is the right entry point. If you want to review or break it, see SECURITY.md. If you want to deploy it for real workloads β€” please don't, not yet.


When your AI agents negotiate with another company's AI agents β€” who verifies identity? Who enforces policy? Who audits what happened?

Cullis is a federated trust broker for AI agents: x509 PKI for identity, DPoP-bound tokens, end-to-end encrypted messaging, default-deny policy, and a cryptographic audit ledger. Purpose-built infrastructure for the agent-to-agent era.

πŸ“– Why Cullis exists, architectural deep-dives, use cases, and comparisons β†’ cullis.io

This README is the engineer's entry point: how to clone it, how to run it, how the code is laid out. Everything else lives on the site.


Quickstart

Boot the full architecture (broker + 2 MCP proxies + 2 agents in 2 organizations), route one cross-org E2E-encrypted message, tear it all down. About a minute end to end.

What you need

Requirement Why
Docker Engine with the Compose v2 plugin The demo runs five containers (broker, 2 MCP proxies, postgres, redis)
Python 3.10+ on the host The orchestrator + sender + checker scripts run on the host, not in containers
httpx Python package The only host-side Python dependency the demo touches
Free TCP ports 8800, 9800, 9801 The script fails fast with a clear message if any of them is taken
~2 GB free disk + outbound network First-time build pulls the broker + proxy images

Supported hosts: Linux native, macOS with Docker Desktop / OrbStack / Colima, Windows via WSL2 + Docker Desktop. No Nix required (Nix is only used by the maintainer's dev loop).

Installing httpx if you do not already have it:

# Recommended: a project venv (works on every OS, never collides with system Python)
python3 -m venv .venv && .venv/bin/pip install httpx
# the wrapper auto-detects .venv/bin/python, no need to activate it

# Or user-wide
python3 -m pip install --user httpx

# Debian/Ubuntu/macOS Homebrew with PEP 668 ("externally-managed-environment"):
python3 -m pip install --user --break-system-packages httpx

Run it

git clone https://github.com/cullis-security/cullis
cd cullis
./deploy_demo.sh up
python scripts/demo/sender.py

Three commands after the clone, including a full Docker build on first run. The demo uses KMS_BACKEND=local, no TLS, no Vault β€” it is meant for laptops. See scripts/demo/README.md for the full guided tour (dashboards, customization, troubleshooting).

If you want to explore the broker or a proxy on its own (not as part of the bundled demo), see Run the components individually below β€” note that those standalone paths are not yet production-tested.


Two components

Cullis ships as two independent, deployable components:

Cullis Broker Cullis MCP Proxy
Role Network control plane Organization data plane
Deployed at Network operator's infrastructure Each participating org's network
Manages Identity, routing, policy federation, audit ledger Agent certs, broker uplink, tool execution
Dashboard Network admin (onboard orgs, approve, audit) Org admin (register, create agents, manage tools)
Default port 8000 (HTTP) / 8443 (HTTPS) 9100

Fully self-hosted. No SaaS dependency. A single company can run both, or a consortium of organizations can agree on who hosts the broker while each runs their own proxy.


Architecture

flowchart TB
    subgraph org_a["🏒 Organization A"]
        direction TB
        A1["πŸ€– Buyer Agent"]
        A2["πŸ€– Inventory Agent"]
        VA["πŸ” Vault A"]
        PA["⚑ MCP Proxy A<br><sub>auto PKI · cert issuance · API key auth</sub>"]
        A1 -->|"β‘  API Key"| PA
        A2 -->|"β‘  API Key"| PA
        VA -.->|"agent keys"| PA
    end

    subgraph broker["🌐 Cullis Broker β€” self-hosted"]
        direction TB
        AUTH["β‘‘ Verify x509 chain"]
        DPOP["β‘’ Validate DPoP"]
        POL["β‘£ Query policies"]
        FWD["β‘₯ Forward E2E"]
        AUTH --> DPOP --> POL --> FWD
    end

    subgraph org_b["🏒 Organization B"]
        direction TB
        B1["πŸ€– Supplier Agent"]
        T1["πŸ”§ Tool: ERP"]
        VB["πŸ” Vault B"]
        PB["⚑ MCP Proxy B<br><sub>auto PKI · cert issuance · API key auth</sub>"]
        PB -->|"⑦ API Key"| B1
        PB -->|"⑦ tool call"| T1
        VB -.->|"agent keys"| PB
    end

    PA ==>|"β‘‘ x509 + DPoP + E2E"| broker
    broker ==>|"β‘₯ E2E encrypted"| PB

    broker ---|"β‘£ policy query"| PDPA["πŸ“‹ Org A PDP<br><sub>webhook / OPA</sub>"]
    broker ---|"β‘£ policy query"| PDPB["πŸ“‹ Org B PDP<br><sub>webhook / OPA</sub>"]

    PDPA -->|"β‘€ allow βœ“"| DUAL{"Both must<br>allow"}
    PDPB -->|"β‘€ allow βœ“"| DUAL

    classDef broker fill:#4f46e5,stroke:#6366f1,color:#fff,font-weight:bold
    classDef proxy fill:#0d9488,stroke:#14b8a6,color:#fff,font-weight:bold
    classDef agent fill:#1e293b,stroke:#334155,color:#e2e8f0
    classDef pdp fill:#92400e,stroke:#d97706,color:#fef3c7
    classDef vault fill:#1e1b4b,stroke:#4338ca,color:#c7d2fe
    classDef decision fill:#b45309,stroke:#f59e0b,color:#fff

    class AUTH,DPOP,POL,FWD broker
    class PA,PB proxy
    class A1,A2,B1,T1 agent
    class PDPA,PDPB pdp
    class VA,VB vault
    class DUAL decision
Loading
  1. Agent β†’ Proxy β€” agents authenticate with a local API key (X-API-Key)
  2. Proxy β†’ Broker β€” the proxy signs with x509 + DPoP and encrypts E2E; agents never touch crypto keys
  3. Broker verifies β€” x509 chain, DPoP proof-of-possession, certificate thumbprint pinning
  4. Policy query β€” broker asks both organizations' PDP (webhook or OPA)
  5. Dual authorization β€” session proceeds only if both orgs return allow (default-deny)
  6. E2E forward β€” broker forwards the encrypted message it cannot read (zero-knowledge)
  7. Proxy β†’ Agent / Tool β€” the receiving proxy decrypts and delivers

Key features

  • 3-tier x509 PKI + SPIFFE workload identity β€” Broker CA β†’ Org CA β†’ Agent cert with spiffe://trust-domain/org/agent SAN
  • DPoP token binding (RFC 9449) β€” every token bound to an ephemeral EC P-256 key, server nonce rotation
  • End-to-end encryption β€” AES-256-GCM payloads, RSA-OAEP-SHA256 key wrapping, two-layer RSA-PSS signing
  • Federated dual-org policy β€” PDP webhook or OPA, default-deny, both orgs must allow
  • Cryptographic audit ledger β€” append-only, SHA-256 hash chain, tamper detection, NDJSON / CSV export
  • Self-service org onboarding β€” invite tokens, automatic Org CA generation, no manual openssl
  • OIDC federation for admin login β€” Okta, Azure AD, Google, per-org IdP config
  • KMS backends β€” local filesystem (dev), HashiCorp Vault KV v2 (prod), extensible
  • Self-hosted, no SaaS dependency

Python SDK

from cullis_sdk.client import CullisClient

client = CullisClient("https://broker.example.com")
client.login("buyer", "acme", "agent.pem", "agent-key.pem")

agents = client.discover(capabilities=["supply"])
session_id = client.open_session("widgets::supplier", "widgets", ["supply"])
client.send(session_id, "acme::buyer", {"order": "100 units"}, "widgets::supplier")

A TypeScript SDK lives in sdk-ts/. An MCP server exposing 10 Cullis tools (so any MCP-compatible LLM can become a Cullis agent) is in cullis_sdk/mcp_server.py.


Run the components individually

⚠️ Status: exploratory, not production-tested. The bundled demo (./deploy_demo.sh) is the only end-to-end path covered by automated tests. The standalone deploy scripts below let you spin up the broker or a single proxy on its own to evaluate each piece in isolation, but they have not been hardened or validated against a real production workload yet. Use them to explore, not yet to operate.

If you only want to see Cullis in action, stop at the Quickstart above and use the demo.

Just the broker

# Self-signed cert on https://localhost:8443 β€” no public DNS required
./deploy_broker.sh --dev

# With Let's Encrypt (requires a public domain pointing at the host)
./deploy_broker.sh --prod-acme \
  --domain broker.example.com \
  --email ops@example.com

# With your enterprise CA (Bring Your Own CA)
./deploy_broker.sh --prod-byoca \
  --domain broker.example.com \
  --cert /etc/ssl/cullis/fullchain.pem \
  --key  /etc/ssl/cullis/privkey.pem

Three TLS profiles, same script. The --dev profile is the one most likely to "just work" right now; the --prod-* profiles are still being shaken out.

Just a proxy (for one organization)

./deploy_proxy.sh

Pairs with a running broker. Walks you through entering the broker URL, the invite token, and registering the org.

Kubernetes (Helm)

A Helm chart lives in deploy/helm/cullis/. Same caveat: it captures the deployment topology and is helm lint-clean, but has not been validated against a managed Kubernetes cluster end to end yet. Treat it as a starting point for your own packaging, not a turnkey install.

Where to look next

  • enterprise-kit/ β€” BYOCA guide, OPA policy bundle, Prometheus alert rules, PDP webhook template
  • docs/ops-runbook.md β€” operational pitfalls (DPoP htu, KMS bootstrap, common health-check failures)
  • scripts/demo/README.md β€” the recommended path: full demo guide with dashboard tour and customization hooks

Project layout

app/             Broker FastAPI application (auth, registry, broker, dashboard, kms)
mcp_proxy/       Org MCP gateway (egress, ingress, dashboard, agent manager)
cullis_sdk/      Python SDK + MCP server
sdk-ts/          TypeScript SDK
alembic/         Broker database migrations
tests/           Unit + integration tests; tests/e2e/ holds the full-stack suite
scripts/         Ops scripts (generate-env, pg-backup) + scripts/demo/ live demo
deploy/          Helm chart for Kubernetes
enterprise-kit/  BYOCA guide, OPA policy bundles, monitoring, PDP template
docs/            cullis.io site source + ops runbook
.github/         CI workflows + issue / PR templates

Runtime: Python 3.11 Β· FastAPI Β· PostgreSQL 16 Β· Redis Β· HashiCorp Vault Β· cryptography Β· PyJWT Β· OpenTelemetry + Jaeger Β· OPA Β· Docker Β· Helm.


Contributing

See CONTRIBUTING.md for development setup, PR workflow, and code conventions.

Security vulnerabilities: see SECURITY.md for private reporting guidelines.

Contact

General questions, partnerships, demos hello@cullis.io
Security vulnerabilities (private) security@cullis.io Β· see SECURITY.md
Bug reports, feature requests GitHub Issues
Discussion, questions, ideas GitHub Discussions

License

Apache License 2.0


Architecture deep-dives, use cases, comparisons, and the project's reason for existing all live at cullis.io.

Releases

No releases published

Packages

 
 
 

Contributors