Skip to content
bogwarePublic

About

A self-hostable, enterprise-grade LLM gateway: routing, cost control, caching, guardrails, access control, and a tamper-evident audit trail.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

277 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Gulley

One gate every model request rides through.

A self-hostable, enterprise-grade LLM gateway: a single container in front of every provider your outfit uses — adding routing, cost control, caching, guardrails, access control, and a tamper-evident audit trail, without changing a line of application code.

License: Apache-2.0 Self-hostable Node ≥ 22.9 DCO

Out on the model frontier, traffic rides in from every vendor at once. Gulley is the gate at the pass — it checks the papers, tallies the toll, keeps the ledger, and remembers exactly who rode through.

Gulley admin console — overview dashboard


One control plane over both Claude Code and Codex. Anthropic's and OpenAI's own gateways each govern only their own agent, with after-the-fact, 30-day logs. Gulley is the single in-line, tamper-evident plane over both — plus Bedrock, Vertex, and Azure — with cross-vendor DLP, tool-call policy, hard budgets, and a WORM audit no single-vendor tool can match. It is Claude-first (the Anthropic Messages schema is its canonical internal model) and drop-in: point Claude Code, Codex, or any custom harness at Gulley by changing a base URL, and everything just works — while you gain governance, cost control, and audit over every request.

Why Gulley

  • Multi-provider, one surface — Anthropic (API + Enterprise), OpenAI, AWS Bedrock, Azure AI Foundry, any OpenAI-compatible backend (Groq, Mistral, Together, …), and local runtimes (Ollama, vLLM, LM Studio); a Google Gemini/Vertex native adapter ships but is not yet configurable. Native full-fidelity passthrough and a cross-provider layer for routing, load-balancing, failover, and same-model arbitrage.
  • Governance, all open — RBAC, virtual keys, budgets with hard caps, PII/secret masking, guardrails, and a tamper-evident (hash-chained + S3 Object Lock WORM, KMS-signed, externally anchored) audit trail. Every governance feature is in the Apache-2.0 core — not paywalled behind an "enterprise" edition.
  • Coding-agent aware — governs and attributes the traffic Claude Code and Codex actually generate; in-stream (not buffered) source-code / secret DLP; the prompt cache the big cacheable prefixes depend on is metered, so you can see the dollars it saves.
  • Enterprise identity — console SSO over OIDC (Microsoft Entra) or SAML 2.0, JWT auth for the data plane, App-Role / group → RBAC with custom roles, SCIM provisioning, Graph-backed revoke-on-deprovision, and workload identity (a Kubernetes service account or GitHub Actions job exchanges its platform token for a scoped, short-lived gateway token — RFC 7523). See docs/ENTRA_SETUP.md, docs/SAML_SETUP.md and docs/WORKLOAD_IDENTITY.md.
  • Observability without lock-in — emits OpenTelemetry (GenAI semantic conventions) to your backend; enforces cost/rate limits locally; a Prometheus endpoint and a batteries-included admin console. Operational alerts (budgets, key expiry, breakers, guardrail blocks, config applies, break-glass) go to Slack, Teams, PagerDuty, email or a signed webhook — see docs/ALERTING.md.
  • Runs where you run — one distroless container for AWS ECS Fargate (a single adaptable Terraform module), Kubernetes (Helm, with an EKS Terraform module), or a docker-compose self-host.

The console

A batteries-included Next.js admin plane — observe spend and traffic, browse the request log, walk the tamper-evident audit chain, manage identity and routing, and edit config as GitOps.

Request log browser
Request logs — every call, keyset-paginated, with latency and cost.
Compliance and WORM
Compliance & WORM — hash-chained audit, signed attestation, evidence bundle.
Analytics
Analytics — cost / tokens / requests by provider, model, or workspace.

Also in the console: FinOps chargeback, per-agent cost tree, FOCUS 1.2 export & runaway-session kill switch, shadow-spend, guardrails, budgets & rate limits, virtual keys & onboarding, OAuth/Entra identity, providers, prompts, eval rollouts, and a live config editor.

Architecture

The full design — request pipeline, provider abstraction, auth model, data model, AWS topology, and a concrete integration-spec appendix — lives in docs/ARCHITECTURE.md; delivered capabilities are tracked in the CHANGELOG.

apps/gateway       data plane: the streaming proxy + request pipeline
apps/control-api   control plane: orgs, keys, routes, policies, OAuth/OIDC, SCIM
apps/web           admin console (Next.js)
packages/*         core, providers, routing, auth, rbac, budget, ratelimit, cost, catalog,
                   cache, guardrails, pipeline, config, storage, telemetry, metrics, oauth,
                   oidc, cel, crypto, worm, redact, egress, http-edge, prompts,
                   control-client, cli
infra/terraform    one adaptable AWS ECS module (test/prod tiers) — see INSTALL.md
infra/eks          the EKS sibling module (AWS substrate for the Helm chart)
deploy/            Helm chart + docker-compose self-host
scripts/bundle.mjs esbuild bundling of both apps for the distroless runtime image

Quick start (development)

Prerequisites: Node ≥ 22.9 (via corepack), Docker.

corepack enable                            # activates pnpm from package.json's packageManager
pnpm install
cp .env.example .env                       # dev defaults, no real secrets — then add your
                                           # ANTHROPIC_UPSTREAM_API_KEY (no provider key = no routes)
docker compose up -d                       # postgres (pgvector) + the three role-split redis
pnpm --filter @gulley/control-api migrate  # apply the SQL migrations
pnpm dev                                   # gateway (:8080), control-api (:8081), web (:3000)

Every workspace script (dev, migrate, seed, the *:check smoke tests) loads the repo-root .env itself (--env-file-if-exists), so nothing has to be exported into the shell; Turborepo's strict env mode is not in the way. The gateway answers /ready with 503 until at least one provider route is configured and the database schema is current, so check curl -s localhost:8080/ready before the first request.

Mint a virtual key and point any Anthropic-Messages client at the gateway:

# mint a key (prints a gk_ token once; DATABASE_URL + GULLEY_KEY_PEPPER come from .env)
pnpm --filter @gulley/control-api seed --name dev

export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=gk_...            # the printed token
curl -s "$ANTHROPIC_BASE_URL/v1/messages" \
  -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-haiku-4-5","max_tokens":32,"messages":[{"role":"user","content":"hello"}]}'
# now Claude Code, Codex, or curl all flow through Gulley

Prefer short-lived, identity-bound tokens over static keys? Turn on the OAuth broker (OAUTH_BROKER_ENABLED=true on both apps), register a client in the console, and have developers run pnpm gulley login — Claude Code and Codex then fetch tokens through gulley token. See docs/HARNESS_OAUTH.md.

Deploy

Two release images are published multi-arch (amd64 + arm64), distroless, cosign-signed with SBOM + SLSA provenance: ghcr.io/bogware/gulley (one image runs either the gateway or the control-api) and ghcr.io/bogware/gulley-web (the console) — how to verify. The SQL migrations ship in the API image (node dist/control-api/migrate.mjs).

Common tasks

Command What it does
pnpm dev Run all apps in watch mode (each loads the repo-root .env)
bash ci/verify.sh The full local gate (format/lint/types/test/build/bundle)
pnpm test Unit/integration tests (Vitest)
pnpm --filter @gulley/<pkg> test Test one package
pnpm --filter @gulley/control-api migrate Apply the SQL migrations (same entry the image runs)
pnpm db:generate Generate a SQL migration from the Drizzle schema
pnpm bundle esbuild-bundle both apps into dist/ (what the image runs)
pnpm --filter @gulley/gateway doctor Static preflight over the gateway config

Contributing

See CONTRIBUTING.md and our Code of Conduct. Contributions are accepted under the Developer Certificate of Origin — sign your commits with git commit -s. Report vulnerabilities privately via Security Advisories; see SECURITY.md.

License

Apache License 2.0. Copyright 2026 The Gulley Authors.

About

A self-hostable, enterprise-grade LLM gateway: routing, cost control, caching, guardrails, access control, and a tamper-evident audit trail.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages