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
mainbranch. 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, usinggcr.io/cloud-builders/dockerto build the application image from the repo-rootDockerfile(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 taglatest, overridable via the_IMAGEsubstitution). - 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 connectorbetaapp-connectorso 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
- Sign in to the GCP Console with an account that has the
roles/cloudbuild.builds.viewerrole on projecttactile-stack-491017-c0. - Project selector → tactile-stack-491017-c0.
- Left nav → Cloud Build → History (and/or Triggers to confirm the on-push-to-main trigger configuration).
- Filter by Trigger name = the Theora repo's main-branch trigger, and Region =
us-central1. - Sort by Create time descending and confirm the top rows are Status: Success.
- (Optional, for the deploy-target view) Left nav → Cloud Run → service
betaapp-api→ Revisions, 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:
| Field | Why it matters |
|---|---|
| Build ID | Unique identifier for the audit trail. |
Source commit SHA (and branch = main) | Ties the deploy back to a reviewed merge commit. |
| Trigger name | Proves the build was kicked off by the production trigger, not an ad-hoc gcloud builds submit. |
| Status = SUCCESS | Confirms a clean, completed deploy. |
Deploy target: Cloud Run service betaapp-api, region us-central1 | Anchors 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. |
| Duration | Operational 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-apiin a single screenshot. - Refresh the screenshot quarterly, and additionally whenever the trigger, Dockerfile, or
cloudbuild.yamlchanges 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 ID | Create time (UTC) | Status | Image pushed |
|---|---|---|---|---|
| 1 | aa3119fa-9484-4b93-8c13-8585b0b16c71 | 2026-06-02 23:55:39 | SUCCESS | betaapp-api:latest |
| 2 | 92b7cdcf-03a6-421a-93db-cce87e32bac7 | 2026-05-13 20:46:04 | SUCCESS | betaapp-api:latest |
| 3 | d16d7a2f-cabe-4e11-a5be-027f6c3b65e6 | 2026-05-13 20:25:57 | SUCCESS | betaapp-api:latest |
| 4 | 4b54d99f-2df6-4252-9201-219e317b2858 | 2026-05-13 19:15:29 | SUCCESS | betaapp-api:latest |
| 5 | 805f65a4-6613-483f-bb15-483118336f02 | 2026-05-13 17:20:10 | SUCCESS | betaapp-api:latest |
| 6 | 56c4489d-66ca-4da9-9b25-64ca61c6db6c | 2026-05-13 16:13:45 | SUCCESS | betaapp-api:latest |
| 7 | f7d6aacf-164d-4354-901c-74b96168c295 | 2026-05-12 00:10:58 | SUCCESS | betaapp-api:latest |
| 8 | 0a5096ce-9bf8-4e8f-9e8c-5ffeef200773 | 2026-05-11 17:09:14 | SUCCESS | betaapp-api:latest |
| 9 | 8c31377e-7025-424b-bb41-f4efe53c05d3 | 2026-05-11 15:11:48 | SUCCESS | betaapp-api:latest |
| 10 | d20ccc1f-f622-4405-bc5f-37b6378bf993 | 2026-05-11 05:35:18 | SUCCESS | betaapp-api:latest |
| 11–20 | 10 additional SUCCESS builds between 2026-05-11 04:01 and 05:27 UTC | betaapp-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.