fugue / regula

Regula checks infrastructure as code templates (Terraform, CloudFormation, k8s manifests) for AWS, Azure, Google Cloud, and Kubernetes security and compliance using Open Policy Agent/Rego
https://regula.dev/
Apache License 2.0
961 stars 109 forks source link

Waiving rules for dynamic resources? #127

Open christophetd opened 3 years ago

christophetd commented 3 years ago

Say I'm creating a bunch of unencrypted S3 buckets:

resource "aws_s3_bucket" "bucket" {
  count = 20
  bucket = "christophe-my-sample-unencrypted-bucket-${count.index}"
}

and using regula to scan my Terraform plan:

+--------------------------+---------------+-----------+----------+--------------+--------------------------+---------+--------+
|         Resource         |     Type      | Filepath  | Severity |   Rule ID    |        Rule Name         | Message | Result |
+--------------------------+---------------+-----------+----------+--------------+--------------------------+---------+--------+
| aws_s3_bucket.bucket     | aws_s3_bucket | .         | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | WAIVED |
| aws_s3_bucket.bucket[0]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[10] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[11] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[12] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[13] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[14] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[15] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[16] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[17] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[18] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[19] | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[1]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[2]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[3]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[4]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[5]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[6]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[7]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[8]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
| aws_s3_bucket.bucket[9]  | aws_s3_bucket | plan.json | Unknown  | S3_ENCRYPTED | aws_s3_bucket_encryption |         | FAIL   |
+--------------------------+---------------+-----------+----------+--------------+--------------------------+---------+--------+
|                          |               |           |          |              |                          | Overall |   FAIL |
+--------------------------+---------------+-----------+----------+--------------+--------------------------+---------+--------+

And I want to suppress this rule for this specific resource aws_s3_bucket.bucket[*] resource. How can I achieve it?

Waiving aws_s3_bucket.bucket[0] works but will only waive the failure for 1 resource. Same problem for resources created with for_each

christophetd commented 3 years ago

Just noticed this is being worked on as part of #125.

jaspervdj-luminal commented 3 years ago

regula

Hi @christophetd, thanks for reporting this! The PR you linked to only applies to processing .tf files directly -- not to terraform plans.

One option would be for us to support more expressive string globs for waivers. However, you can do something like that in rego as well. If you create a waivers configuration like this:

package fugue.regula.config

import data.fugue.resource_view

# This grabs all resource IDs from the internal resource view.
all_resource_ids[id] {
  single := input[_].content
  resource_view.resource_view[id] with input as single
}

waivers[waiver] {
  # Waive all IDs that match the regex.
  all_resource_ids[id]
  regex.match(`^aws_s3_bucket\.bucket\[[0-9]+\]$`, id)
  waiver := {"resource_id": id, "rule_id": "FG_R00099"}
}

And then pass it in using:

regula run -i waivers.rego tfplan.json

Does that help?

ameliafugue commented 3 years ago

Hi @christophetd,

This is a future roadmap item and I entered it as a request here: https://feedback.eu.pendo.io/app/#/case/136142?section=requests