diff --git a/modules/cloud-run-v2/README.md b/modules/cloud-run-v2/README.md
index 330fd02584..631fa3b185 100644
--- a/modules/cloud-run-v2/README.md
+++ b/modules/cloud-run-v2/README.md
@@ -20,6 +20,7 @@ Cloud Run Services and Jobs, with support for IAM roles and Eventarc trigger cre
- [Creating Cloud Run Jobs](#creating-cloud-run-jobs)
- [Tag bindings](#tag-bindings)
- [IAP Configuration](#iap-configuration)
+- [Binary Authorization](#binary-authorization)
- [Adding GPUs](#adding-gpus)
- [Variables](#variables)
- [Outputs](#outputs)
@@ -881,6 +882,49 @@ module "cloud_run" {
# tftest inventory=iap.yaml e2e
```
+## Binary Authorization
+
+Binary Authorization can be enabled on services, jobs and worker pools. Setting `use_default = true` opts the resource into the [project default policy](https://cloud.google.com/binary-authorization/docs/run/enabling-binauthz-cloud-run); use `policy` instead to attach a custom Cloud Run Binary Authorization policy by its full resource path. `breakglass_justification` bypasses Binary Authorization checks for the current revision and emits a high-severity audit log entry — only set it for ad-hoc breakglass deploys.
+
+```hcl
+module "cloud_run" {
+ source = "./fabric/modules/cloud-run-v2"
+ project_id = var.project_id
+ name = "example-binauthz"
+ region = var.region
+ containers = {
+ hello = {
+ image = "us-docker.pkg.dev/cloudrun/container/hello"
+ }
+ }
+ binary_authorization = {
+ use_default = true
+ }
+ deletion_protection = false
+}
+# tftest inventory=binary-authorization.yaml e2e
+```
+
+```hcl
+module "job" {
+ source = "./fabric/modules/cloud-run-v2"
+ project_id = var.project_id
+ name = "example-binauthz-job"
+ region = var.region
+ type = "JOB"
+ containers = {
+ hello = {
+ image = "us-docker.pkg.dev/cloudrun/container/hello"
+ }
+ }
+ binary_authorization = {
+ policy = "projects/${var.project_id}/platforms/cloudRun/policies/example-policy"
+ }
+ deletion_protection = false
+}
+# tftest inventory=binary-authorization-job.yaml
+```
+
## Adding GPUs
GPU support is available for all types of Cloud Run resources: jobs, services and worker pools.
@@ -981,26 +1025,27 @@ module "worker" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [name](variables.tf#L182) | Name used for Cloud Run service. | string | ✓ | |
-| [project_id](variables.tf#L187) | Project id used for all resources. | string | ✓ | |
-| [region](variables.tf#L192) | Region used for all resources. | string | ✓ | |
-| [containers](variables.tf#L17) | Containers in name => attributes format. | map(object({…})) | | {} |
-| [context](variables.tf#L97) | Context-specific interpolations. | object({…}) | | {} |
-| [deletion_protection](variables.tf#L119) | Deletion protection setting for this Cloud Run service. | string | | null |
-| [encryption_key](variables.tf#L125) | The full resource name of the Cloud KMS CryptoKey. | string | | null |
-| [iam](variables.tf#L131) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} |
-| [job_config](variables.tf#L137) | Cloud Run Job specific configuration. | object({…}) | | {} |
-| [labels](variables.tf#L152) | Resource labels. | map(string) | | {} |
-| [launch_stage](variables.tf#L158) | The launch stage as defined by Google Cloud Platform Launch Stages. | string | | null |
-| [managed_revision](variables.tf#L175) | Whether the Terraform module should control the deployment of revisions. | bool | | true |
-| [revision](variables.tf#L197) | Revision template configurations. | object({…}) | | {} |
+| [name](variables.tf#L214) | Name used for Cloud Run service. | string | ✓ | |
+| [project_id](variables.tf#L219) | Project id used for all resources. | string | ✓ | |
+| [region](variables.tf#L224) | Region used for all resources. | string | ✓ | |
+| [binary_authorization](variables.tf#L17) | Binary Authorization configuration. Applies to services, jobs and worker pools. Set `use_default = true` to enforce the project default policy, or `policy` to a custom Cloud Run policy resource path. `breakglass_justification` bypasses Binary Authorization checks for the resource and emits a high-severity audit log entry. | object({…}) | | null |
+| [containers](variables.tf#L49) | Containers in name => attributes format. | map(object({…})) | | {} |
+| [context](variables.tf#L129) | Context-specific interpolations. | object({…}) | | {} |
+| [deletion_protection](variables.tf#L151) | Deletion protection setting for this Cloud Run service. | string | | null |
+| [encryption_key](variables.tf#L157) | The full resource name of the Cloud KMS CryptoKey. | string | | null |
+| [iam](variables.tf#L163) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} |
+| [job_config](variables.tf#L169) | Cloud Run Job specific configuration. | object({…}) | | {} |
+| [labels](variables.tf#L184) | Resource labels. | map(string) | | {} |
+| [launch_stage](variables.tf#L190) | The launch stage as defined by Google Cloud Platform Launch Stages. | string | | null |
+| [managed_revision](variables.tf#L207) | Whether the Terraform module should control the deployment of revisions. | bool | | true |
+| [revision](variables.tf#L229) | Revision template configurations. | object({…}) | | {} |
| [service_account_config](variables-serviceaccount.tf#L17) | Service account configurations. | object({…}) | | {} |
-| [service_config](variables.tf#L264) | Cloud Run service specific configuration options. | object({…}) | | {} |
-| [tag_bindings](variables.tf#L327) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} |
-| [type](variables.tf#L334) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | string | | "SERVICE" |
-| [volumes](variables.tf#L344) | Named volumes in containers in name => attributes format. | map(object({…})) | | {} |
+| [service_config](variables.tf#L296) | Cloud Run service specific configuration options. | object({…}) | | {} |
+| [tag_bindings](variables.tf#L359) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} |
+| [type](variables.tf#L366) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | string | | "SERVICE" |
+| [volumes](variables.tf#L376) | Named volumes in containers in name => attributes format. | map(object({…})) | | {} |
| [vpc_connector_create](variables-vpcconnector.tf#L17) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null |
-| [workerpool_config](variables.tf#L378) | Cloud Run Worker Pool specific configuration. | object({…}) | | {} |
+| [workerpool_config](variables.tf#L410) | Cloud Run Worker Pool specific configuration. | object({…}) | | {} |
## Outputs
diff --git a/modules/cloud-run-v2/job-managed.tf b/modules/cloud-run-v2/job-managed.tf
index c65578712e..30612573b5 100644
--- a/modules/cloud-run-v2/job-managed.tf
+++ b/modules/cloud-run-v2/job-managed.tf
@@ -23,6 +23,16 @@ resource "google_cloud_run_v2_job" "job" {
labels = var.labels
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection
+
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
template {
labels = var.revision.labels
task_count = var.job_config.task_count
diff --git a/modules/cloud-run-v2/job-unmanaged.tf b/modules/cloud-run-v2/job-unmanaged.tf
index 1961acad63..2ec65941ad 100644
--- a/modules/cloud-run-v2/job-unmanaged.tf
+++ b/modules/cloud-run-v2/job-unmanaged.tf
@@ -23,6 +23,16 @@ resource "google_cloud_run_v2_job" "job_unmanaged" {
labels = var.labels
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection
+
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
template {
labels = var.revision.labels
task_count = var.job_config.task_count
diff --git a/modules/cloud-run-v2/service-managed.tf b/modules/cloud-run-v2/service-managed.tf
index a6078c13d2..44c1812735 100644
--- a/modules/cloud-run-v2/service-managed.tf
+++ b/modules/cloud-run-v2/service-managed.tf
@@ -28,6 +28,15 @@ resource "google_cloud_run_v2_service" "service" {
deletion_protection = var.deletion_protection
iap_enabled = var.service_config.iap_config != null
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
template {
labels = var.revision.labels
encryption_key = var.encryption_key
diff --git a/modules/cloud-run-v2/service-unmanaged.tf b/modules/cloud-run-v2/service-unmanaged.tf
index 033004330f..4782314536 100644
--- a/modules/cloud-run-v2/service-unmanaged.tf
+++ b/modules/cloud-run-v2/service-unmanaged.tf
@@ -28,6 +28,15 @@ resource "google_cloud_run_v2_service" "service_unmanaged" {
deletion_protection = var.deletion_protection
iap_enabled = var.service_config.iap_config != null
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
template {
labels = var.revision.labels
encryption_key = var.encryption_key
diff --git a/modules/cloud-run-v2/variables.tf b/modules/cloud-run-v2/variables.tf
index 5d74fc09fc..f0043b7f0a 100644
--- a/modules/cloud-run-v2/variables.tf
+++ b/modules/cloud-run-v2/variables.tf
@@ -14,6 +14,38 @@
* limitations under the License.
*/
+variable "binary_authorization" {
+ description = "Binary Authorization configuration. Applies to services, jobs and worker pools. Set `use_default = true` to enforce the project default policy, or `policy` to a custom Cloud Run policy resource path. `breakglass_justification` bypasses Binary Authorization checks for the resource and emits a high-severity audit log entry."
+ type = object({
+ breakglass_justification = optional(string)
+ policy = optional(string)
+ use_default = optional(bool, false)
+ })
+ default = null
+ validation {
+ condition = (
+ var.binary_authorization == null
+ ? true
+ : (
+ var.binary_authorization.use_default
+ || var.binary_authorization.policy != null
+ )
+ )
+ error_message = "Either binary_authorization.use_default must be true or binary_authorization.policy must be set."
+ }
+ validation {
+ condition = (
+ var.binary_authorization == null
+ ? true
+ : !(
+ var.binary_authorization.use_default
+ && var.binary_authorization.policy != null
+ )
+ )
+ error_message = "binary_authorization.use_default and binary_authorization.policy are mutually exclusive."
+ }
+}
+
variable "containers" {
description = "Containers in name => attributes format."
type = map(object({
diff --git a/modules/cloud-run-v2/workerpool-managed.tf b/modules/cloud-run-v2/workerpool-managed.tf
index 19bacb034d..535caf575f 100644
--- a/modules/cloud-run-v2/workerpool-managed.tf
+++ b/modules/cloud-run-v2/workerpool-managed.tf
@@ -24,6 +24,15 @@ resource "google_cloud_run_v2_worker_pool" "default_managed" {
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
dynamic "scaling" {
for_each = var.workerpool_config.scaling == null ? [] : [""]
content {
diff --git a/modules/cloud-run-v2/workerpool-unmanaged.tf b/modules/cloud-run-v2/workerpool-unmanaged.tf
index 5f05eca58c..4e5f10ea27 100644
--- a/modules/cloud-run-v2/workerpool-unmanaged.tf
+++ b/modules/cloud-run-v2/workerpool-unmanaged.tf
@@ -24,6 +24,15 @@ resource "google_cloud_run_v2_worker_pool" "default_unmanaged" {
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection
+ dynamic "binary_authorization" {
+ for_each = var.binary_authorization == null ? [] : [""]
+ content {
+ breakglass_justification = var.binary_authorization.breakglass_justification
+ policy = var.binary_authorization.policy
+ use_default = var.binary_authorization.use_default
+ }
+ }
+
dynamic "scaling" {
for_each = var.workerpool_config.scaling == null ? [] : [""]
content {
diff --git a/tests/modules/cloud_run_v2/examples/binary-authorization-job.yaml b/tests/modules/cloud_run_v2/examples/binary-authorization-job.yaml
new file mode 100644
index 0000000000..e084b18eba
--- /dev/null
+++ b/tests/modules/cloud_run_v2/examples/binary-authorization-job.yaml
@@ -0,0 +1,87 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+values:
+ module.job.google_cloud_run_v2_job.job[0]:
+ annotations: null
+ binary_authorization:
+ - breakglass_justification: null
+ policy: projects/project-id/platforms/cloudRun/policies/example-policy
+ use_default: false
+ client: null
+ client_version: null
+ deletion_policy: DELETE
+ deletion_protection: false
+ effective_labels:
+ goog-terraform-provisioned: 'true'
+ labels: null
+ location: europe-west8
+ name: example-binauthz-job
+ project: project-id
+ run_execution_token: null
+ start_execution_token: null
+ template:
+ - annotations: null
+ labels: null
+ template:
+ - containers:
+ - args: null
+ command: null
+ depends_on: null
+ env: []
+ image: us-docker.pkg.dev/cloudrun/container/hello
+ name: hello
+ ports: []
+ volume_mounts: []
+ working_dir: null
+ encryption_key: null
+ gpu_zonal_redundancy_disabled: null
+ max_retries: 3
+ node_selector: []
+ service_account: example-binauthz-job@project-id.iam.gserviceaccount.com
+ volumes: []
+ vpc_access: []
+ terraform_labels:
+ goog-terraform-provisioned: 'true'
+ timeouts: null
+ module.job.google_project_iam_member.default["roles/logging.logWriter"]:
+ condition: []
+ member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
+ project: project-id
+ role: roles/logging.logWriter
+ module.job.google_project_iam_member.default["roles/monitoring.metricWriter"]:
+ condition: []
+ member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
+ project: project-id
+ role: roles/monitoring.metricWriter
+ module.job.google_service_account.service_account[0]:
+ account_id: example-binauthz-job
+ create_ignore_already_exists: null
+ deletion_policy: DELETE
+ description: null
+ disabled: false
+ display_name: example-binauthz-job
+ email: example-binauthz-job@project-id.iam.gserviceaccount.com
+ member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
+ project: project-id
+ timeouts: null
+
+counts:
+ google_cloud_run_v2_job: 1
+ google_project_iam_member: 2
+ google_service_account: 1
+ modules: 1
+ resources: 4
+
+outputs: {}
diff --git a/tests/modules/cloud_run_v2/examples/binary-authorization.yaml b/tests/modules/cloud_run_v2/examples/binary-authorization.yaml
new file mode 100644
index 0000000000..5f4d716119
--- /dev/null
+++ b/tests/modules/cloud_run_v2/examples/binary-authorization.yaml
@@ -0,0 +1,98 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+values:
+ module.cloud_run.google_cloud_run_v2_service.service[0]:
+ annotations: null
+ binary_authorization:
+ - breakglass_justification: null
+ policy: null
+ use_default: true
+ build_config: []
+ client: null
+ client_version: null
+ custom_audiences: null
+ default_uri_disabled: null
+ deletion_policy: DELETE
+ deletion_protection: false
+ description: null
+ effective_labels:
+ goog-terraform-provisioned: 'true'
+ iap_enabled: false
+ invoker_iam_disabled: false
+ labels: null
+ location: europe-west8
+ multi_region_settings: []
+ name: example-binauthz
+ project: project-id
+ template:
+ - annotations: null
+ containers:
+ - args: null
+ base_image_uri: null
+ command: null
+ depends_on: null
+ env: []
+ image: us-docker.pkg.dev/cloudrun/container/hello
+ liveness_probe: []
+ name: hello
+ readiness_probe: []
+ source_code: []
+ volume_mounts: []
+ working_dir: null
+ encryption_key: null
+ execution_environment: EXECUTION_ENVIRONMENT_GEN1
+ gpu_zonal_redundancy_disabled: null
+ health_check_disabled: null
+ labels: null
+ node_selector: []
+ revision: null
+ service_account: example-binauthz@project-id.iam.gserviceaccount.com
+ service_mesh: []
+ session_affinity: null
+ volumes: []
+ vpc_access: []
+ terraform_labels:
+ goog-terraform-provisioned: 'true'
+ timeouts: null
+ module.cloud_run.google_project_iam_member.default["roles/logging.logWriter"]:
+ condition: []
+ member: serviceAccount:example-binauthz@project-id.iam.gserviceaccount.com
+ project: project-id
+ role: roles/logging.logWriter
+ module.cloud_run.google_project_iam_member.default["roles/monitoring.metricWriter"]:
+ condition: []
+ member: serviceAccount:example-binauthz@project-id.iam.gserviceaccount.com
+ project: project-id
+ role: roles/monitoring.metricWriter
+ module.cloud_run.google_service_account.service_account[0]:
+ account_id: example-binauthz
+ create_ignore_already_exists: null
+ deletion_policy: DELETE
+ description: null
+ disabled: false
+ display_name: example-binauthz
+ email: example-binauthz@project-id.iam.gserviceaccount.com
+ member: serviceAccount:example-binauthz@project-id.iam.gserviceaccount.com
+ project: project-id
+ timeouts: null
+
+counts:
+ google_cloud_run_v2_service: 1
+ google_project_iam_member: 2
+ google_service_account: 1
+ modules: 1
+ resources: 4
+
+outputs: {}