Gateway config
Generate (or validate) the LLM Governance on AI Gateway configuration for the project — token quotas, model allowlist, fallback policy, per-agent rate limits. Output is a `.claude/ai-gateway.<env>.json` file the org's gateway service consumes.From its SKILL.md
npx -y skills add vhmarquez/argo --skill gateway-configAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.8 KB, as published. Nobody here has run it
You are producing the AI Gateway configuration that controls token usage, model selection, and fallback behavior for agents in this org. The gateway is the org-level chokepoint for LLM traffic — sensible defaults here prevent surprise bills and cap blast-radius for misbehaving agents.
Read Project Config First
source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/config.sh"
PROJECT_NAME="$(sf_config_get '.project.name' "$ENV")"
DEFAULT_ENV="${ENV:-base}"
The output path follows the env-override convention:
--env prod→ writes.claude/ai-gateway.prod.json- (no env) → writes
.claude/ai-gateway.json(the base config)
Per-env overrides deep-merge over the base in the same way sf-project.<env>.json does.
Input
$ARGUMENTS:
- (empty) — interactive walk through the sections below
--profile dev|qa|prod— apply a recommended bundle (see below)--validate— verify the existing gateway config; no changes--env <name>— write to env override file--ci— non-interactive, profile or explicit fields required
Configuration sections
Models
| Field | Purpose | Default |
|---|---|---|
models.allowlist | Models permitted from this org | ["sf-proprietary","claude-sonnet","gpt-5"] |
models.default | Default for non-specialized work | "sf-proprietary" |
models.byAgent | Per-agent model override | {} |
Quotas
| Field | Purpose | Default (dev / prod) |
|---|---|---|
quotas.tokensPerHour.org | Org-wide ceiling | 1_000_000 / 10_000_000 |
quotas.tokensPerHour.perAgent | Per-agent ceiling | 100_000 / 1_000_000 |
quotas.requestsPerMinute.perAgent | Per-agent rate limit | 60 / 600 |
quotas.maxContextTokens | Per-request context cap | 100_000 |
quotas.maxOutputTokens | Per-response output cap | 4_096 |
Fallback
| Field | Purpose | Default |
|---|---|---|
fallback.policy | What to do when primary model fails or quota exceeded | "degrade" (use cheaper model) |
fallback.chain | Ordered fallback list | ["claude-sonnet","gpt-5","sf-proprietary"] |
fallback.refuseAfter | Stop trying after N attempts | 3 |
fallback.userMessage | Message shown when refusing | "I'm temporarily unavailable. Please try again in a minute." |
Audit
| Field | Purpose | Default |
|---|---|---|
audit.logAllRequests | Log every request for compliance | true |
audit.retainDays | Log retention | 90 (dev) / 365 (prod) |
audit.alertWebhook | Webhook for quota-exceeded events | (project's notifications.webhooks.slack) |
Profiles
| Profile | Token / hour cap | Model | Audit retention |
|---|---|---|---|
dev | 1M | sf-proprietary (cheap, fast iteration) | 30d |
qa | 5M | claude-sonnet | 60d |
prod | 10M | claude-sonnet (with gpt-5 fallback) | 365d |
Each profile is a JSON template under ${CLAUDE_PLUGIN_ROOT}/templates/gateway/<profile>.json (the skill copies + merges).
Steps
--profile prod
- Read template
${CLAUDE_PLUGIN_ROOT}/templates/gateway/prod.json - Substitute project-specific fields:
audit.alertWebhook←notifications.webhooks.slackfrom sf-project.jsonmodels.byAgent← infer frombotDefinitions/(if there are agents in source)
- Write to
.claude/ai-gateway.prod.json
Interactive (no profile)
Walk through each section, showing defaults from the closest matching profile, asking the user to override or accept.
--validate
- Load current
.claude/ai-gateway[.<env>].json - Cross-check against constraints:
- Each agent in
botDefinitions/is either in the allowlist or has a per-agent model override - Default model is in the allowlist
- Fallback chain doesn't include disallowed models
- Token quotas are positive and per-agent ≤ org-wide
notifications.webhooks.slackresolves (if used)
- Each agent in
- Report findings with rule IDs
GATEWAY-AGENT-NO-MODEL,GATEWAY-FALLBACK-DISALLOWED,GATEWAY-QUOTA-INVERTED, etc.
Output
Default Markdown after generate:
# AI Gateway Config: <project.name> (env=prod)
✅ Wrote .claude/ai-gateway.prod.json (merged template + project context)
Models:
- Allowlist: claude-sonnet, gpt-5, sf-proprietary
- Default: claude-sonnet
- Per-agent: order_helper → claude-sonnet, support_triage → claude-sonnet
Quotas:
- Org tokens/hour: 10,000,000
- Per-agent: 1,000,000
- Per-agent rate: 600 req/min
- Max context: 100,000 tokens
- Max output: 4,096 tokens
Fallback:
- Policy: degrade
- Chain: claude-sonnet → gpt-5 → sf-proprietary → refuse
- Refuse after: 3 attempts
Audit:
- Log all: true
- Retain: 365 days
- Alert webhook: https://hooks.slack.com/... (from notifications.webhooks.slack)
## Next steps
- Apply via the org's AI Gateway admin (Setup → Einstein → AI Gateway → Import)
- Schedule periodic /argo:gateway-config --validate runs to detect drift
- Review /argo:trust-eval reports to tune token quotas based on actual usage
--validate output:
# Gateway Config Validation: <project.name> (env=prod)
✅ Allowlist: valid
✅ Default model: in allowlist
✅ Fallback chain: in allowlist
⚠️ Per-agent override: support_triage references "claude-haiku" not in allowlist (GATEWAY-FALLBACK-DISALLOWED)
✅ Quotas: per-agent ≤ org-wide
✅ Webhook: resolves
Exit codes
- 0 — config written or validate clean
- 1 —
--validatefound issues - 2 — invocation error
Rules
- Don't write secrets. Webhook URLs are sensitive; the file should reference
${SLACK_WEBHOOK_URL}env var indirection rather than the literal URL where possible - Per-env scoping is normal. dev caps low; prod caps high. Use override files
- Don't auto-apply. This skill writes config; an operator imports it into the org's Gateway. Don't try to PUT it via API automatically (gateway changes are operator decisions)
- Validate before deploy. Recommend running
--validateon PR; failed validation blocks the merge in CI - Quotas are guardrails, not optimization. Set them generously enough that legitimate users don't hit them, low enough that runaway agents can't drain credits
Consumers
- Gateway operators (admins) import the JSON via Setup
/argo:agent-deploycross-references the agent against the gateway model allowlist; warns if a deployed agent references a non-allowed model/argo:trust-evalreferences quota-exceeded events captured in the audit log