spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / examples / gateway / gcp / gateway.yaml.example
156 lines · 9.2 KBRaw
1# gateway.yaml.example — Claude Gateway config template, GCP-shaped (walkthrough §6).
2#
3# Google Workspace IdP + Agent Platform (formerly Vertex AI) upstream, following
4# the walkthrough at https://code.claude.com/docs/en/claude-apps-gateway-on-gcp.
5# The active sections
6# below are a strict subset of the full configuration reference at
7# https://code.claude.com/docs/en/claude-apps-gateway; optional keys are included
8# commented-out.
9#
10# USAGE — this is the shippable TEMPLATE. Copy it to gateway.yaml and fill it in:
11# cp gateway.yaml.example gateway.yaml
12# setup.sh and terraform/ read gateway.yaml (your filled-in copy, which is
13# gitignored). It is published as the Secret Manager secret `gateway-config`
14# (§6) and mounted at /etc/claude/gateway.yaml — the container ENTRYPOINT runs
15# `claude gateway --config /etc/claude/gateway.yaml`.
16#
17# Secret expansion: ${ENV_VAR} reads an env var; ${file:/path} reads a mounted file.
18# On Cloud Run, setup.sh injects the JWT / OIDC / Postgres secrets as ENV VARS
19# (Cloud Run can't mount multiple secrets into a single directory), and mounts
20# only gateway.yaml itself as a file at /etc/claude. On GKE you may use file mounts.
21#
22# BEFORE DEPLOY — replace every REPLACE_ME placeholder below (setup.sh refuses to
23# publish the config secret while any remain), and create the referenced secrets:
24# gateway-jwt-secret (setup.sh generates this)
25# gateway-oidc-client-secret (from the Google Cloud Console OAuth client)
26# gateway-postgres-url (setup.sh generates this)
27
28# ── Listener ─────────────────────────────────────────────────────────────────
29listen:
30 host: 0.0.0.0
31 port: 8080 # Cloud Run sets PORT=8080; leave as-is
32 # Required. Fixes the IdP redirect_uri, the OIDC discovery doc, and the
33 # gateway-token issuer so none are derived from the client-controlled Host
34 # header (X-Forwarded-Host/-Proto are likewise never trusted). On Cloud Run
35 # the run.app URL is only assigned on the first deploy, so this starts as a
36 # placeholder for the provisioning-only first pass (login does NOT work until
37 # the real URL is set). After the first deploy, setup.sh prints the run.app
38 # URL: set it here (or your LB hostname) and re-run; setup.sh republishes the
39 # config and redeploys. Register the same host's /oauth/callback on the
40 # Google OAuth client.
41 public_url: https://set-after-first-deploy.invalid
42 # Register this exact redirect URI on the Google OAuth client:
43 # https://<public_url host>/oauth/callback
44 #
45 # On Cloud Run (or behind any L7 LB) every request arrives via Google's front
46 # end, so the gateway sees one peer IP for all developers — set trusted_proxies
47 # so X-Forwarded-For from those proxies is trusted and per-IP rate limiting /
48 # audit IPs record the real client. 169.254.0.0/16 is Cloud Run's fixed
49 # link-local serving range; the proxy-only subnet is the one your internal ALB
50 # uses in this VPC.
51 # trusted_proxies:
52 # - 169.254.0.0/16 # Cloud Run serving proxy (link-local peer)
53 # - <proxy-only-subnet-cidr> # add if fronted by your internal ALB (its proxy-only subnet)
54 #
55 # Alternative — terminate TLS in the gateway itself instead of at a proxy:
56 # tls:
57 # cert: /certs/gateway.crt
58 # key: /certs/gateway.key
59
60# ── Identity provider — Google Workspace ─────────────────────────────────────
61oidc:
62 issuer: https://accounts.google.com
63 client_id: REPLACE_ME # Google OAuth client ID (not secret; from Cloud Console)
64 client_secret: ${OIDC_CLIENT_SECRET}
65 allowed_email_domains: [REPLACE_ME] # e.g. [example.com] — reject id_tokens outside your org
66 # Google ignores the default offline_access scope; these two are what actually
67 # yield refresh tokens (silent renewal + the deprovision leash) from Google.
68 scopes: [openid, profile, email]
69 extra_auth_params: { access_type: offline, prompt: consent }
70 # NOTE: Google id_tokens carry NO groups claim. For group-based RBAC with
71 # Google as IdP, set `google_groups` (below) and the gateway fetches each
72 # user's Workspace groups at login via the Admin SDK Directory API.
73 # Otherwise, use email_domain matching (see managed.policies below).
74 # google_groups:
75 # service_account_json_path: /secrets/google-sa.json # SA with domain-wide delegation on admin.directory.group.readonly
76 # admin_email: admin@example.com # a Workspace admin the SA impersonates
77 # groups_claim: groups # Okta=groups, Entra app roles=roles — NOT Google
78 # ca_cert_pem: ${file:/secrets/idp-ca.pem} # only for an IdP behind a private CA
79
80# ── Sessions ─────────────────────────────────────────────────────────────────
81session:
82 jwt_secret: ${GATEWAY_JWT_SECRET} # >= 32 bytes; openssl rand -base64 32
83 # Google issues refresh tokens (above), so sessions renew silently and this
84 # mainly bounds deprovision latency. 8 is a sane default; lower toward 1 for
85 # tighter revocation. Array form rotates keys: [new, old] (index 0 signs, all verify).
86 ttl_hours: 8
87
88# ── Store (REQUIRED — the gateway refuses to boot without it) ─────────────────
89store:
90 postgres_url: ${GATEWAY_POSTGRES_URL} # private-IP Cloud SQL; built with ?sslmode=require by setup.sh
91
92# ── Upstreams — Agent Platform ───────────────────────────────────────────────
93upstreams:
94 - provider: vertex
95 region: us-east5 # a region where the Claude models you need are published in Model Garden
96 project_id: REPLACE_ME # your GCP project ID for Agent Platform access
97 auth: {} # ADC via Cloud Run SA / GKE Workload Identity (preferred — no static keys)
98 # base_url: https://us-east5-aiplatform.p.googleapis.com # Private Service Connect endpoint
99 # Add more upstreams for failover (tried top→bottom on 5xx/timeout/501): a
100 # second region, or an anthropic/bedrock fallback. See
101 # https://code.claude.com/docs/en/claude-apps-gateway.
102
103# ── Telemetry fan-out (OPTIONAL) ─────────────────────────────────────────────
104# The CLI sends OTLP/HTTP to the gateway; the gateway fans out, stamping
105# user.id/user.email/user.groups server-side. On GCP, point at an OpenTelemetry
106# Collector with the googlecloud exporter (-> Cloud Trace / Managed Prometheus).
107# Takes effect after the second pass (once public_url is the real URL, not the
108# placeholder): when forward_to and public_url are both configured the gateway pushes
109# CLAUDE_CODE_ENABLE_TELEMETRY and the OTEL exporter selectors to every client
110# automatically — no per-developer config needed.
111# telemetry:
112# forward_to:
113# - url: https://otel-collector.internal.example.com:4318
114# headers:
115# Authorization: ${file:/secrets/otlp-token}
116# metrics: true # safe aggregate counters (default)
117# logs: false # carries bash commands / tool inputs — opt in deliberately
118# traces: false
119
120# ── RBAC + managed settings (OPTIONAL; first-match-wins, top -> bottom) ───────
121# With Google as IdP, match on email_domain, or on group email addresses
122# (e.g. eng@example.com) once oidc.google_groups is configured above.
123# managed:
124# policies:
125# - match: { email_domain: example.com }
126# cli:
127# availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
128# permissions: { deny: ["Read(./.env)", "Read(./secrets/**)"] }
129# - match: {} # catch-all floor — keep LAST
130# cli:
131# availableModels: [claude-sonnet-4-6, claude-haiku-4-5]
132
133# ── Admin API (OPTIONAL — enables db-mode runtime config + spend caps) ───────
134# admin_groups needs a groups claim — with Google as IdP, set
135# oidc.google_groups (above) so Workspace group email addresses populate the
136# claim, or use the bootstrap keys below instead. Named keys for
137# attribution in the audit log; 32-char minimum on key values. On Cloud Run add
138# these as env vars to --set-secrets (or terraform env value_source blocks),
139# same as the JWT/OIDC/Postgres secrets above; on GKE you may use ${file:...}.
140# admin:
141# write_keys:
142# - id: terraform
143# key: ${GATEWAY_ADMIN_WRITE_KEY}
144# read_keys:
145# - id: reporting
146# key: ${GATEWAY_ADMIN_READ_KEY}
147# # admin_groups: [platform-finops@example.com] # group emails via oidc.google_groups, or any groups-capable IdP
148
149# ── Model catalog (OPTIONAL) ─────────────────────────────────────────────────
150# Default true: every built-in Claude model is exposed and auto-translated per
151# upstream. Set false + a models: list to pin IDs (e.g. provisioned throughput).
152# auto_include_builtin_models: true
153# models:
154# - id: claude-opus-4-8
155# label: Claude Opus 4.8
156# upstream_model: { vertex: claude-opus-4-8 }