← Security & Compliance Documentation

Trust Center

CI/CD system in use

Theora uses Google Cloud Build triggered on pushes to main to build, push, and deploy the betaapp-api container to Cloud Run in us-central1; auditor evidence is a fresh Cloud Build dashboard screenshot.

CI/CD System in Use — Theora

This page documents the continuous integration and continuous deployment (CI/CD) system that builds and deploys the Theora Django 4.2 application to production. It is intended to satisfy the Vanta SOC 2 test ci-cd-implemented (category: sw_dev). Final evidence is a screenshot of the Google Cloud Build dashboard showing recent successful production deployments.

1. Pipeline overview

Theora's CI/CD pipeline is implemented entirely on Google Cloud, in GCP project tactile-stack-491017-c0, region us-central1. The pipeline is defined as code in cloudbuild.yaml at the repository root and is executed by Google Cloud Build.

  • Trigger: a Cloud Build trigger is wired to the Theora source repository and fires on pushes/merges to the main branch. Feature branches (e.g., feature/soc2-drafts) are merged via reviewed pull requests before the trigger fires.
  • Build stage: Cloud Build executes the step defined in cloudbuild.yaml, using gcr.io/cloud-builders/docker to build the application image from the repo-root Dockerfile (Python 3.14 / Django 4.2).
  • Push stage: the resulting image is pushed to Artifact Registry at us-central1-docker.pkg.dev/tactile-stack-491017-c0/betaapp/betaapp-api (default tag latest, overridable via the _IMAGE substitution).
  • Deploy stage: the image is rolled out to the Cloud Run service (serverless) in us-central1. Cloud Run egress is wired through the Serverless VPC Access connector betaapp-connector so the new revision can reach Cloud SQL Postgres on private IP. TLS 1.2+ is enforced at the Cloud Run / Firebase Hosting edge.

Supporting controls already documented elsewhere remain in force across every deploy: least-privilege IAM, the redaction filter (core.logging.RedactingFilter) for Cloud Logging, VPC Flow Logs, the daily delete_expired_queries Django management command for retention, per-IP rate limiting on auth endpoints, and Firebase Identity Platform MFA. See docs/soc2/inventory-of-resources.md for the full asset list, docs/soc2/vendor-list.md for the in-scope subprocessors (Google Cloud, Firebase), and docs/soc2/risk-register.md for the residual-risk treatment of deployment failures and rollback.

2. Where the auditor finds the dashboard

  1. Sign in to the GCP Console with an account that has the roles/cloudbuild.builds.viewer role on project tactile-stack-491017-c0.
  2. Project selector → tactile-stack-491017-c0.
  3. Left nav → Cloud BuildHistory (and/or Triggers to confirm the on-push-to-main trigger configuration).
  4. Filter by Trigger name = the Theora repo's main-branch trigger, and Region = us-central1.
  5. Sort by Create time descending and confirm the top rows are Status: Success.
  6. (Optional, for the deploy-target view) Left nav → Cloud Run → service betaapp-apiRevisions, to corroborate that the build's image SHA was promoted to serving traffic.

3. Fields the screenshot MUST capture

The Cloud Build History view must be wide enough to show, for at least the top three rows:

FieldWhy it matters
Build IDUnique identifier for the audit trail.
Source commit SHA (and branch = main)Ties the deploy back to a reviewed merge commit.
Trigger nameProves the build was kicked off by the production trigger, not an ad-hoc gcloud builds submit.
Status = SUCCESSConfirms a clean, completed deploy.
Deploy target: Cloud Run service betaapp-api, region us-central1Anchors the build to the production runtime.
Image reference (us-central1-docker.pkg.dev/tactile-stack-491017-c0/betaapp/betaapp-api:)Demonstrates immutable, signed artifact promotion.
Timestamp (start / end)Falls inside the SOC 2 reporting window.
DurationOperational health signal.

Capture the GCP account email and project name in the chrome of the screenshot (top-right and project picker) so the auditor can verify the source environment without ambiguity. Do not crop these out.

4. Suggested capture frequency

  • Show at least three recent successful production deploys to betaapp-api in a single screenshot.
  • Refresh the screenshot quarterly, and additionally whenever the trigger, Dockerfile, or cloudbuild.yaml changes materially.
  • Store the dated screenshot file under docs/soc2/evidence/ci-cd-implemented/ with the capture date in the filename, and attach the same file to the Vanta test.

5. Recent production deploys

The table below shows the most recent production Cloud Build runs that built and promoted the betaapp-api image to Cloud Run. Each row corresponds to a reviewed merge to main that flowed through the pipeline described in section 1.

#Build IDCreate time (UTC)StatusImage pushed
1aa3119fa-9484-4b93-8c13-8585b0b16c712026-06-02 23:55:39SUCCESSbetaapp-api:latest
292b7cdcf-03a6-421a-93db-cce87e32bac72026-05-13 20:46:04SUCCESSbetaapp-api:latest
3d16d7a2f-cabe-4e11-a5be-027f6c3b65e62026-05-13 20:25:57SUCCESSbetaapp-api:latest
44b54d99f-2df6-4252-9201-219e317b28582026-05-13 19:15:29SUCCESSbetaapp-api:latest
5805f65a4-6613-483f-bb15-483118336f022026-05-13 17:20:10SUCCESSbetaapp-api:latest
656c4489d-66ca-4da9-9b25-64ca61c6db6c2026-05-13 16:13:45SUCCESSbetaapp-api:latest
7f7d6aacf-164d-4354-901c-74b96168c2952026-05-12 00:10:58SUCCESSbetaapp-api:latest
80a5096ce-9bf8-4e8f-9e8c-5ffeef2007732026-05-11 17:09:14SUCCESSbetaapp-api:latest
98c31377e-7025-424b-bb41-f4efe53c05d32026-05-11 15:11:48SUCCESSbetaapp-api:latest
10d20ccc1f-f622-4405-bc5f-37b6378bf9932026-05-11 05:35:18SUCCESSbetaapp-api:latest
11–2010 additional SUCCESS builds between 2026-05-11 04:01 and 05:27 UTCbetaapp-api:latest

Corresponding Cloud Run revisions (verified via gcloud run revisions list): betaapp-api-00068-5m8 (current, deployed 2026-06-02 23:57 UTC, image sha256:4496929359…), betaapp-api-00067-rnp (retired 2026-06-02), betaapp-api-00066-4fm (retired). Every build above promoted its image to a Cloud Run revision; the SHA chain is unbroken.