A successful cloud build does not prove that an AI application should receive traffic. On Google Cloud, keep five decisions separate: approved source, passing tests and evaluations, the exact built image, the health of the new revision, and permission to move traffic. Automation executes the path; evidence still decides promote, hold, or rollback.
Sanitized use case
A conversational product with a protected build boundary#
Consider a production conversational application with a public web surface, a model-backed application programming interface (API), external tools and private research material in the same development repository. The first deployment risk is not the model—it is accidentally packaging what should never be public.
The build context therefore starts from deny-by-default rules and an exact reviewed manifest. The container receives only runtime files; research, reports, scripts, credentials and paid content remain outside.
Once the build boundary excludes protected material, the delivery workflow can follow the exact candidate from source to traffic.
Whether a specific Cloud Run revision should receive traffic
Candidate deploy, promotion script, and release record
Immutable image, candidate URL, previous revision, and smoke suite
Delivery workflow
Five evidence boundaries from commit to traffic#
Each boundary proves one fact and leaves the next decision open. Keep the artifact identity unchanged as evidence moves forward.
- 01
Source gate
Reviewable build context, locked dependencies, no secret or private-content hit.
- 02
Quality gate
Syntax, tests, evals, security checks, localization and route contracts.
- 03
Artifact gate
Cloud Build records the pushed image digest in Artifact Registry.
- 04
Revision gate
Deploy a new Cloud Run revision without immediate traffic and run smoke/readiness.
- 05
Traffic gate
Evaluate the candidate revision against the release policy.
- PROMOTEMigrate traffic
Evidence passes; the candidate becomes the serving revision.
- HOLDKeep traffic where it is
Evidence is missing or inconclusive; investigate without exposing users.
- ROLLBACKRestore known-good
A promoted revision violates the stop signal; route traffic back.
A compact release record connects those five boundaries without copying sensitive content.
Copyable release record
Make the decision portable across build, revision, and incident#
A compact record connects what was built, what was tested, who decided, and where traffic can return. Store references and verdicts rather than copying sensitive prompts or responses into a release log.
The fields below are a minimum working contract, not a vendor requirement. Add product-specific invariants and retention rules without turning the record into an unreviewable data dump.
Deploy a candidate first; move traffic second
This sanitized pattern is derived from a production GCP delivery path. Cloud Build creates a tagged revision with no traffic; evidence gates decide whether it is promoted.
steps:
- name: gcr.io/cloud-builders/docker
args: [build, -t, "${_IMAGE_URI}", .]
- name: gcr.io/cloud-builders/docker
args: [push, "${_IMAGE_URI}"]
- name: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
entrypoint: gcloud
args:
- run
- deploy
- "${_SERVICE}"
- --image
- "${_IMAGE_URI}"
- --region
- "${_REGION}"
- --no-traffic
- --tag
- candidate
- --quiet
options:
logging: CLOUD_LOGGING_ONLY#!/usr/bin/env bash
set -euo pipefail
: "${SERVICE:?set SERVICE}"
: "${REGION:?set REGION}"
: "${PROJECT:?set PROJECT}"
: "${ACCOUNT:?set ACCOUNT}"
: "${CANDIDATE_URL:?set CANDIDATE_URL}"
: "${CANDIDATE_REVISION:?set CANDIDATE_REVISION}"
: "${PREVIOUS_REVISION:?set PREVIOUS_REVISION}"
rollback() {
gcloud run services update-traffic "$SERVICE" \
--region "$REGION" \
--project "$PROJECT" \
--account "$ACCOUNT" \
--to-revisions "$PREVIOUS_REVISION=100" \
--quiet
}
trap rollback ERR
probe() {
local url="$1"
local -a auth_header=()
if [[ -n "${CANDIDATE_ID_TOKEN:-}" ]]; then
auth_header=(-H "Authorization: Bearer $CANDIDATE_ID_TOKEN")
fi
curl --fail --silent --show-error "${auth_header[@]}" "$url"
}
# Set CANDIDATE_ID_TOKEN for an IAM-protected revision. Leave it unset only
# when these candidate endpoints are intentionally public.
probe "$CANDIDATE_URL/health"
probe "$CANDIDATE_URL/critical-journey"
gcloud run services update-traffic "$SERVICE" \
--region "$REGION" \
--project "$PROJECT" \
--account "$ACCOUNT" \
--to-revisions "$CANDIDATE_REVISION=100" \
--quiet
trap - ERR{
"artifact": "image@sha256:<digest>",
"candidate_revision": "service-00042-abc",
"previous_revision": "service-00041-xyz",
"evidence_uri": "<immutable-evidence-reference>",
"verdict": "PROMOTE",
"rollback_target": "service-00041-xyz"
}Failure exercised. Any candidate gate failure leaves production traffic untouched. A promotion failure invokes rollback to the known-good revision.
Production boundary. Placeholders replace project, account, service, secret, and internal test identifiers. Set CANDIDATE_ID_TOKEN for an IAM-protected revision; leave it unset only for intentionally public endpoints.
The record identifies what may be promoted; service identities and secret handling limit what that candidate may access.
Identity and secrets
Keep credentials out of source and build output#
Use dedicated service identities with the minimum roles required for build, registry and runtime. Store secrets in Secret Manager and bind them at runtime; do not bake values into the image or print them in build logs.
Separate human deploy authority from runtime identity. An application that can call a model does not need permission to modify its own infrastructure.
With access bounded, readiness tests can exercise the exact no-traffic revision that may be promoted.
No-traffic readiness
Test the revision you are about to promote#
A successful deploy proves that Cloud Run accepted a revision, not that the product works. Probe health, public routes, authentication boundaries, model/tool dependencies, analytics and critical journeys against the candidate revision.
For an agentic system, include at least one deterministic journey and one evaluated open-ended journey. Store the revision and artifact identifiers beside the verdict.
Passing readiness permits a traffic decision, but only a predefined rollback signal makes that decision reversible.
Traffic and rollback
Make promotion reversible#
Cloud Run revisions are immutable and support traffic migration. This enables testing a tagged revision, gradual rollout, and routing traffic back to a known-good revision.
Define the rollback signal before promotion: error rate, latency, policy violation, failed business journey, or evidence pipeline failure. If observability is broken, HOLD is safer than a blind rollout.
The successful stages now need explicit limits so “green” is not mistaken for proof of the whole product journey.
Green is not ready
Know what each successful stage still cannot prove#
Read each pair from left to right: the evidence proves a narrow fact, while the adjacent limit names the next unanswered question.
CAN
- A successful build identifies a reproducible artifact
- A ready revision proves the container starts on Cloud Run
- A route smoke proves selected public paths answer
- A traffic decision records accepted residual risk
CANNOT
- Prove the agent completes its business journey from a build alone
- Prove model and tool permissions work from container health
- Cover open-ended or adversarial behavior with one smoke
- Guarantee future reliability or safety after promotion
The final checklist verifies that none of those unanswered questions was silently treated as a pass.
Operational checklist
Before migrating traffic#
Complete these items for one image digest and one candidate revision. Mixing evidence from different builds breaks the chain.
- Build context matches an exact reviewed manifest.
- Dependencies and base image are pinned and audited.
- No secret or protected content enters the artifact.
- Tests, evals, security and localization gates pass.
- Image digest is tied to the commit and used for deployment.
- Candidate revision serves no traffic during readiness checks.
- Critical routes and agent journeys pass against that revision.
- Service account roles follow least privilege.
- Secrets are runtime-bound and absent from logs.
- Known-good revision and rollback command are recorded.
- Traffic migration has an owner and stop signal.
- Post-promotion smoke is ready for the public hostname.
Only then does deployment produce a candidate whose promotion has evidence, an owner, and a known return path.
Conclusion
Deployment creates a candidate; evidence promotes it#
A successful build and a healthy Cloud Run revision prove that an artifact exists and a container starts. They do not prove that the agent completes its business journey, respects permissions, or should receive production traffic. Promotion is a separate decision.
Keep the build boundary exact, tie the image digest to the change, deploy the candidate without traffic, exercise critical deterministic and evaluated journeys, and record the owner and rollback signal. Move traffic only when that evidence is complete. If observability or recovery is missing, HOLD is the operationally correct result.
Primary sources
Primary sources
- Cloud Build: deploy to Cloud Run
Build, push to Artifact Registry, and deploy.
- Deploying Cloud Run revisions
Immutable revisions and deployment without immediate traffic.
- Cloud Run rollouts and rollbacks
Tagged revisions, traffic migration, and rollback.
- Secret Manager best practices
Secret storage, access, and lifecycle guidance.
From prototype to operated service