Odile Gate

Put Gate in front of your AI model API key

Your agents call a model API with one provider key. Put Gate in between: each agent gets its own Gate key, only the calls you allow pass, a stuck agent repeating the same request is stopped before it reaches the provider, and your provider key never leaves Gate.

Set it up

  1. Create a project whose upstream is your provider's API base URL and whose secret header is your provider key (for an OpenAI-compatible API, Authorization: Bearer <key>; for Anthropic, "header_name": "x-api-key"). The key is stored encrypted (AES-GCM). You get the project id and an admin key once.
  2. Add one app per agent with only the calls it needs, its calls per minute and, if you like, the only models it may ask for. You get that agent's Gate key once.
  3. Point the agent's SDK base URL at https://gate.odilelabs.com/g/<project id> and give it its own Gate key instead of the provider key. Streaming answers pass straight through.
curl -sS https://gate.odilelabs.com/api/projects -H 'content-type: application/json' \
  -d '{"name":"Model API","upstream":"https://api.openai.com/v1","header_value":"Bearer '"$PROVIDER_KEY"'"}'

curl -sS -X POST "https://gate.odilelabs.com/api/projects/$PROJECT/apps" \
  -H "Authorization: Bearer $ODILE_GATE_ADMIN_KEY" -H 'content-type: application/json' \
  -d '{"name":"support-agent","routes":["POST /chat/completions"],"per_minute":60,"models":["gpt-4.1-mini"]}'
# Python, OpenAI SDK: the agent holds only its Gate key
from openai import OpenAI
client = OpenAI(base_url="https://gate.odilelabs.com/g/" + PROJECT, api_key=GATE_APP_KEY)

# Python, Anthropic SDK (project header_name x-api-key): send the Gate key as a bearer token
from anthropic import Anthropic
client = Anthropic(base_url="https://gate.odilelabs.com/g/" + PROJECT, auth_token=GATE_APP_KEY)

What it stops

Rotate the provider key

Replace the stored key in place, or remove it, with the project admin key. The value is never returned or logged.

curl -sS -X PUT "https://gate.odilelabs.com/api/projects/$PROJECT/secret" \
  -H "Authorization: Bearer $ODILE_GATE_ADMIN_KEY" -H 'content-type: application/json' \
  -d '{"header_value":"Bearer '"$NEW_PROVIDER_KEY"'"}'

What Gate keeps

Gate never stores prompts or answers: request and response bodies, headers and query values are not kept. The audit log has the time, agent, allowed or refused call, status, duration, body size and a hash.

Plans

Free: 3 apps and 10,000 calls a month. Pro: $29 a month, 25 apps and 1,000,000 calls a month. Your model usage is billed by your provider as before.