Add IAM deny policies support (#3970)

* Added IAM denial policies

* Moved default to empty, removed trys, added condition vars to expression

* remove redundant null checks

* reduce line length

* boilerplate and principal context expansion

* update readmes

* add explicit validation against null values

* add context tests

* Add missing license headers to examples

---------

Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
kovagoadam
2026-05-21 02:38:06 +00:00
committed by GitHub
parent 36ca3c33a5
commit 1907c38e22
41 changed files with 1829 additions and 10 deletions

View File

@@ -173,4 +173,7 @@ module "organization-iam" {
tags_config = {
force_context_ids = true
}
iam_deny_policies = lookup(
local.organization, "iam_deny_policies", {}
)
}

View File

@@ -357,6 +357,85 @@
"iam_by_principals_conditional": {
"$ref": "#/$defs/iam_by_principals_conditional"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"name": {
"type": "string"
},

View File

@@ -112,6 +112,29 @@
- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))*
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **name**: *string*
- **org_policies**: *object*
<br>*additional properties: false*

View File

@@ -344,6 +344,85 @@
"iam_by_principals_additive": {
"$ref": "#/$defs/iam_by_principals"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"kms": {
"type": "object",
"additionalProperties": false,

View File

@@ -110,6 +110,29 @@
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_by_principals_additive**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **kms**: *object*
<br>*additional properties: false*
- **autokeys**: *object*

View File

@@ -357,6 +357,85 @@
"iam_by_principals_conditional": {
"$ref": "#/$defs/iam_by_principals_conditional"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"name": {
"type": "string"
},

View File

@@ -112,6 +112,29 @@
- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))*
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **name**: *string*
- **org_policies**: *object*
<br>*additional properties: false*

View File

@@ -344,6 +344,85 @@
"iam_by_principals_additive": {
"$ref": "#/$defs/iam_by_principals"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"kms": {
"type": "object",
"additionalProperties": false,

View File

@@ -110,6 +110,29 @@
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_by_principals_additive**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **kms**: *object*
<br>*additional properties: false*
- **autokeys**: *object*

View File

@@ -357,6 +357,85 @@
"iam_by_principals_conditional": {
"$ref": "#/$defs/iam_by_principals_conditional"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"name": {
"type": "string"
},

View File

@@ -112,6 +112,29 @@
- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))*
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **name**: *string*
- **org_policies**: *object*
<br>*additional properties: false*

View File

@@ -344,6 +344,85 @@
"iam_by_principals_additive": {
"$ref": "#/$defs/iam_by_principals"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"kms": {
"type": "object",
"additionalProperties": false,

View File

@@ -110,6 +110,29 @@
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_by_principals_additive**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **kms**: *object*
<br>*additional properties: false*
- **autokeys**: *object*

View File

@@ -357,6 +357,85 @@
"iam_by_principals_conditional": {
"$ref": "#/$defs/iam_by_principals_conditional"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"name": {
"type": "string"
},

View File

@@ -112,6 +112,29 @@
- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))*
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **name**: *string*
- **org_policies**: *object*
<br>*additional properties: false*

View File

@@ -344,6 +344,85 @@
"iam_by_principals_additive": {
"$ref": "#/$defs/iam_by_principals"
},
"iam_deny_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"required": [
"rules"
],
"properties": {
"display_name": {
"type": "string"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"denied_permissions",
"denied_principals"
],
"properties": {
"description": {
"type": "string"
},
"denied_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"denied_principals": {
"type": "array",
"items": {
"type": "string"
}
},
"denial_condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "string"
}
}
},
"exception_permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"exception_principals": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"kms": {
"type": "object",
"additionalProperties": false,

View File

@@ -110,6 +110,29 @@
- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_by_principals_conditional**: *reference([iam_by_principals_conditional](#refs-iam_by_principals_conditional))*
- **iam_by_principals_additive**: *reference([iam_by_principals](#refs-iam_by_principals))*
- **iam_deny_policies**: *object*
<br>*additional properties: false*
- **`^[a-z0-9-]+$`**: *object*
<br>*additional properties: false*
- **display_name**: *string*
- ⁺**rules**: *array*
- items: *object*
<br>*additional properties: false*
- **description**: *string*
- ⁺**denied_permissions**: *array*
- items: *string*
- ⁺**denied_principals**: *array*
- items: *string*
- **denial_condition**: *object*
<br>*additional properties: false*
- ⁺**expression**: *string*
- **title**: *string*
- **description**: *string*
- **location**: *string*
- **exception_permissions**: *array*
- items: *string*
- **exception_principals**: *array*
- items: *string*
- **kms**: *object*
<br>*additional properties: false*
- **autokeys**: *object*