Skip to main content

Internal Claude gateway control layer and developer CLI

Project description

Claude Control Layer

FastAPI control plane for Claude/LiteLLM access with users, roles, teams, runtime policy settings, quota metadata, usage analytics, alerts, and admin APIs.

Claude Code no longer points directly at the FastAPI app for Anthropic-compatible transport. Claude Code points at LiteLLM, while this app manages the surrounding control-plane data and can create LiteLLM virtual keys for users.

Features

  • Role-based model enforcement for admin, engineer, and worker
  • Daily token quota checks per user
  • Full usage logging in Postgres
  • Admin analytics for overview, users, models, trends, and estimated cost
  • Token-based admin authentication with login
  • LiteLLM proxy service for Claude Code transport
  • LiteLLM virtual-key creation from admin-managed users, roles, and teams
  • Redis client wiring for future rate-limiting or caching work
  • Dockerized local development

Project layout

app/
  core/
  models/
  routes/
  schemas/
  services/
docker/
migrations/
admin-dashboard/

Run locally with Docker

docker-compose up --build

The API will be available at http://localhost:8000. LiteLLM will be available at http://localhost:4000.

API endpoints

  • POST /chat
  • POST /auth/login
  • POST /auth/claude-code-token
  • POST /v1/messages
  • POST /v1/messages/count_tokens
  • GET /health
  • GET /auth/me
  • GET /admin/overview
  • GET /admin/users
  • GET /admin/trends
  • GET /admin/models
  • GET /admin/cost

POST /chat, POST /v1/messages, and POST /v1/messages/count_tokens are legacy FastAPI transport endpoints and are disabled by default. Set ENABLE_LEGACY_CLAUDE_TRANSPORT=true only for a temporary migration window.

POST /auth/claude-code-token is deprecated and returns 410 Gone. Claude Code should use a LiteLLM virtual key instead.

Admins can create a LiteLLM virtual key for an app user with:

POST /admin/users/{user_id}/litellm-key

Admin auth

Admin routes accept bearer tokens returned by POST /auth/login. The dashboard now requires login before loading / or /settings.

On a fresh Postgres volume, Docker seeds an admin user automatically:

username/id: anase
password: numnum2001
role: admin

Use a strong AUTH_SECRET in .env for production deployments.

For local dashboard access, keep ALLOWED_ORIGINS aligned with the frontend URL. By default it allows:

http://localhost:3000
http://127.0.0.1:3000

Example chat request

{
  "user_id": "u_123",
  "model": "claude-sonnet-4-6",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Summarize the latest deployment notes."
    }
  ]
}

LiteLLM Transport

LiteLLM runs as a separate service in Docker Compose and listens on port 4000.

The local LiteLLM config is:

litellm/config.yaml

It uses:

  • Postgres-backed LiteLLM key management through DATABASE_URL
  • LITELLM_MASTER_KEY for admin/control-plane calls
  • x-litellm-api-key as the virtual-key header
  • claude-code-sonnet as the local default model name

For local development, configure these in .env:

LITELLM_PROXY_URL=http://localhost:4000
LITELLM_INTERNAL_URL=http://litellm:4000
LITELLM_MASTER_KEY=sk-local-litellm-master-key
LITELLM_DEFAULT_MODEL=claude-code-sonnet
ENABLE_LEGACY_CLAUDE_TRANSPORT=false

Developer CLI

The company-ai CLI lets developers configure Claude Code to use LiteLLM while the FastAPI app remains the admin/control plane.

Install from PyPI:

pip install --upgrade company-ai

Install the Python requirements first:

pip install -r requirements.txt

For a real company-ai command on PATH, install the local package:

pip install -e .

Check the installed version:

company-ai --version

Log in once:

company-ai login --gateway http://localhost:8000

The CLI prompts for email and password, calls POST /auth/login, stores the app session token in the OS keychain through keyring, and saves non-secret config in:

~/.config/company-ai/config.json

Configure Claude Code:

company-ai setup-claude --litellm-url http://localhost:4000 --litellm-key sk-your-user-virtual-key --model claude-code-sonnet

This safely updates:

~/.claude/settings.json

with:

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:4000",
    "ANTHROPIC_CUSTOM_HEADERS": "x-litellm-api-key: Bearer sk-your-user-virtual-key",
    "ANTHROPIC_MODEL": "claude-code-sonnet"
  }
}

Claude Code should remain logged in with Claude subscription auth client-side. The LiteLLM virtual key is sent separately in ANTHROPIC_CUSTOM_HEADERS.

Releasing the CLI

Release notes and tag/publish steps live in RELEASING.md.

Claude Subscription Limit Breaker

Claude Code traffic is protected by a global subscription-limit circuit breaker. This is separate from app quotas and model policy. It represents the real upstream Claude subscription lockout, such as the Claude Max 5-hour plan limit.

The flow is:

  1. LiteLLM forwards Claude Code traffic upstream.
  2. If the upstream provider returns a subscription-limit/reset error, the LiteLLM callback reports the sanitized error to FastAPI at POST /internal/litellm/subscription-limit.
  3. FastAPI stores an active block in system_runtime_blocks with the reason claude_subscription_limit_reached, the detected time, sanitized upstream message, and a parsed UTC reset time when available.
  4. The LiteLLM policy check at POST /internal/litellm/policy checks this block before local quotas, model policy, and request guardrails.
  5. While the block is active, new Claude requests are rejected before any upstream call with a fatal terminal message that includes the reset time when known.
  6. The Alerts page shows a critical alert titled Team reached Claude subscription limit.
  7. If reset_at is known, the block clears automatically after that time on the next policy/admin check. If the reset time is unknown, an admin can clear it manually after verifying Claude access has recovered.

Admin endpoints:

GET /admin/system/subscription-limit-state
POST /admin/system/subscription-limit-state/clear
POST /admin/system/subscription-limit-state/probe

The probe endpoint reports the current state. In Claude subscription mode the server cannot perform a real upstream probe without client-side Claude Code subscription credentials, so unknown-reset blocks should be cleared manually after a user confirms Claude works again.

You can also provide setup values through environment variables:

COMPANY_AI_LITELLM_URL=http://localhost:4000
COMPANY_AI_LITELLM_KEY=sk-your-user-virtual-key
COMPANY_AI_LITELLM_MODEL=claude-code-sonnet

After setup, run:

claude

Then verify with /status.

To remove the stored app session:

company-ai logout

Dashboard

A minimal Next.js dashboard is included under admin-dashboard/.

cd admin-dashboard
npm install
npm run dev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

company_ai-0.2.1.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

company_ai-0.2.1-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file company_ai-0.2.1.tar.gz.

File metadata

  • Download URL: company_ai-0.2.1.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for company_ai-0.2.1.tar.gz
Algorithm Hash digest
SHA256 cd0293b9b8887e86bbda305c6736c998ce60e173646fe0790df9e178e82b959f
MD5 9a2e31feea1b0cb63ce62e5d82a47a1e
BLAKE2b-256 edc8da3f73f2f615d0b8d84850b79f59867ac279321ba5fc147a96e175a00365

See more details on using hashes here.

Provenance

The following attestation bundles were made for company_ai-0.2.1.tar.gz:

Publisher: publish-pypi.yml on ElharrariAnas/Claude-Control-layer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file company_ai-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: company_ai-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for company_ai-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b20f0fac83da4f12638b6f44b071a40fea79f2eea3d3e7266d244e8c86745c2d
MD5 da3c9d901e4dc45f8866aee82c7de369
BLAKE2b-256 72827fb8909c71d1d3960878b235fcd42a8f90d1c670ff8d649d890b9b09758c

See more details on using hashes here.

Provenance

The following attestation bundles were made for company_ai-0.2.1-py3-none-any.whl:

Publisher: publish-pypi.yml on ElharrariAnas/Claude-Control-layer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page