Skip to content

Cloud Storage (GCS)

Runway can provision a managed Cloud Storage bucket for your GKE workload and grant the workload’s service account object access to it. Runway owns the lifecycle of the bucket: it creates one bucket per environment in the Runway GCP projects, attaches a bucket-scoped IAM grant to your workload, and publishes the bucket name and project to Vault.

This guide assumes you already have a working Runway for Kubernetes deployment. If you do not, start with Getting Started first.

Provisioning a bucket touches two files in the provisioner:

  1. Define the bucket in config/runtimes/gke/gcs.yml — name, location, lifecycle, and labels.
  2. Grant your workload access in config/runtimes/gke/workloads.yml — references the bucket by its name via a gcs_buckets list.

A bucket belongs to a single service: each bucket may be referenced by at most one workload. One bucket is provisioned per environment (staging and production), in the gitlab-runway-staging and gitlab-runway-production GCP projects. The physical bucket is named <name>-<environment> — the -<environment> suffix is appended in code so the bucket name is globally unique.

File an MR to add your bucket to config/runtimes/gke/gcs.yml in the Runway provisioner:

config/runtimes/gke/gcs.yml
- name: runway-example-service
location: US-EAST1
versioning: true
soft_delete_retention_days: 7
retention_policy:
retention_days: 30
is_locked: false
lifecycle_rules:
- action:
type: Delete
condition:
age: 90
labels:
gl_service: example-service-gke # required
owner_email_handle: my-team
department: eng-infra
department_group: eng-infra-my-group
product_category: my-category
FieldRequiredDefaultNotes
nameyesMust match ^runway-[a-z0-9]([a-z0-9-]*[a-z0-9])?$ (max 52 chars). The runway- prefix is enforced. The physical bucket is <name>-<environment>; the -<environment> suffix is appended for GCS global uniqueness. Must be unique across all buckets.
labelsyesRequired infrastructure labels. gl_service is required; owner_email_handle, department, department_group, and product_category are optional. See the Infrastructure Standards.
locationnoUS-EAST1Any valid GCS bucket location (region, dual-region, or multi-region).
versioningnotrueEnable object versioning.
soft_delete_retention_daysnoGCS default (7 days)Soft-delete retention in days. Omit for the GCS default; 0 disables soft delete.
retention_policynononeObject: retention_days (required, ≥ 1) and is_locked (default false). Omit for no retention policy.
lifecycle_rulesno[]Bucket lifecycle rules, passed through unchanged. Each rule has an action (Delete, SetStorageClass, or AbortIncompleteMultipartUpload) and a condition.

Uniform bucket-level access is always enabled and legacy ACLs are disabled — this is fixed and not configurable.

Create the MR and assign it to a Runway team member (see CODEOWNERS), and ensure the pipeline passes before requesting review.

In config/runtimes/gke/workloads.yml, add a gcs_buckets key to your workload entry, referencing the bucket by its name:

config/runtimes/gke/workloads.yml
- runway_service_id: example-service-gke
project_id: 12345678
regions:
- us-east1
gcs_buckets:
- runway-example-service

This grants the workload’s service account roles/storage.objectUser on the bucket — read, write, and delete objects, scoped to this bucket only. Remember that each bucket may be referenced by only one workload; the inventory validation fails if two workloads claim the same bucket or if you reference a bucket that is not defined in gcs.yml.

On apply, the provisioner creates, for each environment:

  • The bucket <name>-<environment> in the environment’s Runway GCP project, with uniform bucket-level access enabled.

  • An IAM grant of roles/storage.objectUser to the workload service account gke-<runway_service_id>@<project>.iam.gserviceaccount.com, condition-scoped to the exact bucket (an exact resource match plus its object prefix).

  • A Vault secret (mount runway) at platform/<runway_service_id>/gcs/<bucket>/<environment>, containing:

    {
    "bucket_name": "runway-example-service-production",
    "project": "gitlab-runway-production"
    }

Your workload’s service account already has object access to the bucket through Workload Identity, so you do not need to handle any storage credentials — you only need to know the bucket name. Read it from the Vault secret the provisioner publishes (see What gets created), for example with an ExternalSecret that points at platform/<runway_service_id>/gcs/<bucket>/<environment> on the runway mount and surfaces bucket_name (and project) into your namespace. See Secrets management for how Runway wires Vault into your deployment. Your application then talks to GCS using its ambient Workload Identity credentials and the bucket name from that secret.

  • Review the GCS schema for the authoritative field definitions.
  • See Secrets management for other secret needs your service may have.
  • Ask the Runway team in #f_runway for help or to track deploy-time GCS support.