A security policy generator which generates policies for two purposes:
- Typical policies enforced in a HIPAA aligned GCP environment.
- Policies based on Terraform states to monitor GCP changes that are not deployed by Terraform.
Currently supported Policy Libraries:
- Policy Library as YAML files.
NOTE: Google Cloud Platform Organization Policy Constraints are now generated by tfengine as Terraform configs. See example.
-
Install the following dependencies and add them to your PATH:
- gcloud
- Terraform 0.14.8 (consistent with the version of Terraform used by CICD)
- Go 1.14+
-
Get familiar with Policy Library Constraints.
Download a pre-built policygen binary:
VERSION=v0.8.0
wget -O /usr/local/bin/policygen https://github.com/GoogleCloudPlatform/healthcare-data-protection-suite/releases/download/${VERSION}/policygen_${VERSION}_linux-amd64
chmod +x /usr/local/bin/policygen
or build it yourself:
git clone https://github.com/GoogleCloudPlatform/healthcare-data-protection-suite
cd healthcare-data-protection-suite
go install ./cmd/policygen
-
Set up helper environment variables:
CONFIG_PATH=examples/policygen/config.hcl STATE_PATHS=/path/to/your/tfstate OUTPUT_PATH=/tmp/policygen
-
Edit config with values of your infra:
TIP: Prefer to remotely fetch templates from a release which can be more stable than using the HEAD templates. In your config:
template_dir = "github.com/GoogleCloudPlatform/healthcare-data-protection-suite//templates/policygen?ref=policies-v0.1.0"
-
Generate policies:
policygen --config_path=$CONFIG_PATH --state_paths=$STATE_PATHS --output_path=$OUTPUT_PATH
--state_paths
supports a comma-separated list of paths to Terraform states,
and each entry can be a single local file, a local directory or a Google Cloud
Storage bucket (indicated by gs://
prefix).
- If the path is a single local file, it loads Terraform states from it, regardless of the file name.
- If the path is a local directory, it walks the directory recursively and
loads Terraform states from each
.tfstate
file. - If the path is a Cloud Storage bucket, it walks the bucket recursively and
loads Terraform states from each
.tfstate
file. It only reads the bucket name from the--state_paths
and ignores the file/dir, if specified. All.tfstate
file from the bucket will be read. The program uses Application Default Credentials to authenticate with GCP. Make sure you have at leastroles/storage.objectViewer
permission on the bucket.
To use Policy Library Constraints with Forseti, follow How to use Forseti Config Validator. Forseti Terraform module version >= 5.2.1 is needed.
The generated policies are structured in a format that can be read by Forseti Config Validator Scanner.
To upload policies to the Forseti server bucket:
gsutil -m rsync -d -r $OUTPUT_PATH/forseti_policies gs://forseti-server-{suffix}/policy-library
To use Policy Library Constraints with Terraform Validator, follow How to use Terraform Validator.
The generated policies are structured in a format that can be read by Terraform Validator.
To use Policy Library Constraints with CFT Scorecard, follow Scorecard User Guide.
The generated policies are structured in a format that can be read by CFT Scorecard.
The target
value under the match
block in the generated policies based on
Terraform state might need to be adjusted manually to include the ancestor paths
in the composite_root_resources
field set in your Forseti Terraform module or
the --ancestry
path set when you run Terraform Validator.
For example, a Terraform state based allow_iam_roles.yaml
policy might look
like the following, which is to restrict allowed IAM roles in project with
project number 789.
apiVersion: constraints.gatekeeper.sh/v1alpha1
kind: GCPIAMAllowBanRolesConstraintV1
metadata:
name: iam_allow_roles
spec:
severity: high
match:
target:
- "projects/789"
parameters:
mode: "allow"
roles:
- roles/cloudsql.client
- roles/logging.logWriter
- roles/storage.objectCreator
Assume project 789 is located under folder 456 in organization 123. If the
composite_root_resources
in the Forseti Terraform module is configured at
project level, e.g. projects/789
or projects/*
, then the policy is good to
go. However, if the composite_root_resources
is set to higher level ancestors,
e.g. organizations/123/*
or folders/456/*
, then your target
field should
be modified to include the ancestors in the target
path as well. In this
example, your target
field should be modified to be
organizations/123/folders/456/projects/789
and folders/456/projects/789
,
respectively.