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/policygenor 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
.tfstatefile. - If the path is a Cloud Storage bucket, it walks the bucket recursively and
loads Terraform states from each
.tfstatefile. It only reads the bucket name from the--state_pathsand ignores the file/dir, if specified. All.tfstatefile from the bucket will be read. The program uses Application Default Credentials to authenticate with GCP. Make sure you have at leastroles/storage.objectViewerpermission 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-libraryTo 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.objectCreatorAssume 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.