Skip to content
This repository was archived by the owner on Aug 20, 2025. It is now read-only.

Commit f0dc14c

Browse files
charliewolfjoecheuk
authored andcommitted
VPC SC: Ensure project in service perimiter (#215)
1 parent 0f02024 commit f0dc14c

File tree

6 files changed

+239
-0
lines changed

6 files changed

+239
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
apiVersion: templates.gatekeeper.sh/v1alpha1
17+
kind: ConstraintTemplate
18+
metadata:
19+
name: gcp-vpc-sc-ensure-project-v1
20+
spec:
21+
crd:
22+
spec:
23+
names:
24+
kind: GCPVPCSCEnsureProjectConstraintV1
25+
plural: gcpvpcscensureprojectconstraintsv1
26+
validation:
27+
openAPIV3Schema:
28+
properties:
29+
required_projects:
30+
description: "Required project IDs"
31+
type: array
32+
items: string
33+
targets:
34+
validation.gcp.forsetisecurity.org:
35+
rego: | #INLINE("validator/vpc_sc_ensure_project.rego")
36+
#
37+
# Copyright 2019 Google LLC
38+
#
39+
# Licensed under the Apache License, Version 2.0 (the "License");
40+
# you may not use this file except in compliance with the License.
41+
# You may obtain a copy of the License at
42+
#
43+
# http://www.apache.org/licenses/LICENSE-2.0
44+
#
45+
# Unless required by applicable law or agreed to in writing, software
46+
# distributed under the License is distributed on an "AS IS" BASIS,
47+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48+
# See the License for the specific language governing permissions and
49+
# limitations under the License.
50+
#
51+
52+
package templates.gcp.GCPVPCSCEnsureProjectConstraintV1
53+
54+
import data.validator.gcp.lib as lib
55+
56+
deny[{
57+
"msg": message,
58+
"details": metadata,
59+
}] {
60+
constraint := input.constraint
61+
asset := input.asset
62+
63+
asset.asset_type == "cloudresourcemanager.googleapis.com/Organization"
64+
lib.has_field(asset, "service_perimeter")
65+
66+
lib.get_constraint_params(constraint, params)
67+
required_projects_array := lib.get_default(params, "required_projects", [])
68+
required_projects := {sprintf("projects/%v", [p]) | p = required_projects_array[_]}
69+
70+
perimeter_resources := {r | r = asset.service_perimeter.status.resources[_]}
71+
72+
count(perimeter_resources - required_projects) != count(perimeter_resources) - count(required_projects)
73+
74+
message := sprintf("Required project missing from service perimeter %v.", [asset.service_perimeter.name])
75+
76+
metadata := {"resource": asset.name, "service_perimeter_name": asset.service_perimeter.name}
77+
}
78+
#ENDINLINE

samples/vpc_sc_ensure_project.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
apiVersion: constraints.gatekeeper.sh/v1alpha1
16+
kind: GCPVPCSCEnsureProjectConstraintV1
17+
metadata:
18+
name: vpc_sc_ensure_project
19+
spec:
20+
severity: high
21+
match:
22+
gcp:
23+
target: ["organization/*"]
24+
parameters:
25+
required_projects:
26+
- "179891054369"
27+
- "179891054370"
28+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[{
2+
"name": "//cloudresourcemanager.googleapis.com/organizations/660570133860",
3+
"asset_type": "cloudresourcemanager.googleapis.com/Organization",
4+
"service_perimeter": {
5+
"name": "accessPolicies/1008882730433/servicePerimeters/Test_Service_Perimeter_Good",
6+
"title": "Test Service Perimeter Good",
7+
"status": {
8+
"resources": ["projects/179891054368", "projects/179891054369", "projects/179891054370"],
9+
"access_levels": ["accessPolicies/1008882730433/accessLevels/abcb"],
10+
"restricted_services": ["container.googleapis.com"]
11+
}
12+
},
13+
"ancestors": ["organizations/660570133860"]
14+
},
15+
{
16+
"name": "//cloudresourcemanager.googleapis.com/organizations/660570133861",
17+
"asset_type": "cloudresourcemanager.googleapis.com/Organization",
18+
"service_perimeter": {
19+
"name": "accessPolicies/1008882730434/servicePerimeters/Test_Service_Perimeter_Bad",
20+
"title": "Test Service Perimeter Bad",
21+
"status": {
22+
"resources": ["projects/179891054368", "projects/179891054369"],
23+
"access_levels": ["accessPolicies/1008882730433/accessLevels/abcb"],
24+
"restricted_services": ["container.googleapis.com"]
25+
}
26+
},
27+
"ancestors": ["organizations/660570133861"]
28+
}
29+
]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
apiVersion: constraints.gatekeeper.sh/v1alpha1
16+
kind: GCPVPCSCEnsureProjectConstraintV1
17+
metadata:
18+
name: vpc_sc_ensure_project
19+
spec:
20+
severity: high
21+
match:
22+
gcp:
23+
target: ["organization/*"]
24+
parameters:
25+
required_projects:
26+
- "179891054369"
27+
- "179891054370"
28+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#
2+
# Copyright 2019 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
package templates.gcp.GCPVPCSCEnsureProjectConstraintV1
18+
19+
import data.validator.gcp.lib as lib
20+
21+
deny[{
22+
"msg": message,
23+
"details": metadata,
24+
}] {
25+
constraint := input.constraint
26+
asset := input.asset
27+
28+
asset.asset_type == "cloudresourcemanager.googleapis.com/Organization"
29+
lib.has_field(asset, "service_perimeter")
30+
31+
lib.get_constraint_params(constraint, params)
32+
required_projects_array := lib.get_default(params, "required_projects", [])
33+
required_projects := {sprintf("projects/%v", [p]) | p = required_projects_array[_]}
34+
35+
perimeter_resources := {r | r = asset.service_perimeter.status.resources[_]}
36+
37+
count(perimeter_resources - required_projects) != count(perimeter_resources) - count(required_projects)
38+
39+
message := sprintf("Required project missing from service perimeter %v.", [asset.service_perimeter.name])
40+
41+
metadata := {"resource": asset.name, "service_perimeter_name": asset.service_perimeter.name}
42+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#
2+
# Copyright 2019 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
package templates.gcp.GCPVPCSCEnsureProjectConstraintV1
18+
19+
import data.validator.gcp.lib as lib
20+
21+
all_violations[violation] {
22+
resource := data.test.fixtures.vpc_sc_ensure_project.assets[_]
23+
constraint := data.test.fixtures.vpc_sc_ensure_project.constraints
24+
25+
issues := deny with input.asset as resource
26+
with input.constraint as constraint
27+
28+
violation := issues[_]
29+
}
30+
31+
test_violations_basic {
32+
violation_resources := {r | r = all_violations[_].details.service_perimeter_name}
33+
violation_resources == {"accessPolicies/1008882730434/servicePerimeters/Test_Service_Perimeter_Bad"}
34+
}

0 commit comments

Comments
 (0)