Claude on Vertex AI has no API key. The AnthropicVertex client authenticates through Google Cloud's Application Default Credentials (ADC) — a lookup convention where the Google auth libraries find whatever credentials the environment provides. This is the feature that makes a clean development workflow possible: your application code never chooses how to authenticate; the environment does. The goal of this article is a setup where the only thing that changes between laptop, CI, and production is which identity ADC resolves to.
On your laptop: your own identity, borrowed briefly
For local development, run once:
gcloud auth application-default login
This opens a browser, authenticates you, and stores credentials where ADC looks for them. From then on, the client works with no further configuration:
from anthropic import AnthropicVertex
client = AnthropicVertex(project_id="my-dev-project", region="global")
msg = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Say hello from local dev"}],
)
print(msg.content[0].text)
Your user account needs the Vertex AI User role (roles/aiplatform.user), which carries the aiplatform.endpoints.predict permission required to make prompt requests. Point local work at a dedicated development project so experiments never touch production quota or production audit logs. Note what you do not need day-to-day: the Consumer Procurement Entitlement Manager role (roles/consumerprocurement.entitlementManager) is only for the one-time act of enabling Claude models in Model Garden, and shouldn't be granted broadly.
In CI: a service identity, ideally keyless
CI runners should not authenticate as a person, and they should avoid long-lived service account key files, which are the classic leaked-credential story. The modern pattern is keyless: your CI system exchanges its own proof of identity for short-lived Google Cloud credentials (workload identity federation), or the pipeline impersonates a dedicated service account, obtaining temporary tokens to act as it. Either way, ADC picks up the result and your test code is unchanged. IAM grants use the same mechanism as for humans — the principal is just serviceAccount: instead of user::
gcloud projects add-iam-policy-binding my-ci-project \
--member=serviceAccount:ci-claude@my-ci-project.iam.gserviceaccount.com \
--role=roles/aiplatform.user
Give the CI identity access to a test project only, and remember that real Claude calls in CI cost real tokens — keep integration tests small and mock the client in unit tests (see testing and mocking). The details of the keyless setup are covered in workload identity for Vertex and service account auth.
In production: the attached identity, zero configuration
On Google Cloud compute — Cloud Run, GKE, Cloud Functions, Compute Engine — the cleanest answer is the service account attached to the workload itself. ADC finds it automatically; there is nothing to install, mount, or rotate. Grant that service account roles/aiplatform.user on the production project and nothing else it doesn't need. Because the audit trail records which principal made each call, one dedicated service account per application keeps the question "what called Claude?" answerable — a theme picked up in the audit log query cookbook.
The payoff: one code path, three identities
| Environment | Identity ADC resolves | Setup step |
|---|---|---|
| Laptop | Your user account | gcloud auth application-default login |
| CI | Dedicated CI service account (federated or impersonated) | Pipeline auth step; no key files |
| Production | Service account attached to the workload | Attach SA; grant roles/aiplatform.user |
Configuration that legitimately varies — project ID, region, model — belongs in environment variables, not code, so promoting a change from dev to prod never means editing the call site.
Where to go next
If you haven't made a first call yet, start with your first Claude call on Vertex AI. For the deployment side, see deploying on Cloud Run; for the conceptual auth story, the ADC explainer.