GoogleCloudPlatform / policy-library

A library of constraint templates and sample constraints for Constraint Framework tools
Apache License 2.0
223 stars 129 forks source link

Feature Request: Generic Policy Example #35

Open Red-Five opened 5 years ago

Red-Five commented 5 years ago

Request for a very generic example

E.g along similar lines to the older KE scanner examples here where a key and value are used

https://github.com/forseti-security/forseti-security/blob/v2.14.0/rules/ke_scanner_rules.yaml

abombss commented 5 years ago

This is a good idea, I just added PR #76 which has very basic support for something like this. I have some thoughts on how to take it much further. For what you are asking for it might be better served as a plugin or PR directly to OPA. However, I assume performance might be an issue.

abombss commented 5 years ago

@t12g @ddremund @morgante I created a basic POC for a more generic constraint template

https://github.com/abombss/policy-library/tree/feature/generic-template

Its inspired by the Cloud Custodian generic filter syntax.

It's not feature complete yet, but I think it could be a very powerful base template for people to quickly develop constraints and iterate on them without having to dive deep into rego and opa. Modeling one of the new bq location constraints looks like this.

https://github.com/abombss/policy-library/blob/a8c6bcd8aa914dd60ff3b95a4770a6806e32fd72/validator/test/fixtures/generic_constraint/constraints/bq_dataset_location/allowlist_one_exemption/data.yaml#L15-L36

Here is another sample as well. https://github.com/abombss/policy-library/blob/7a586e33a4d82bf412162432ffe4e8ba1fa43fe5/validator/test/fixtures/generic_constraint/constraints/subnets/data.yaml#L15-L54

Before I take this further I would like to open the discussion to get feedback and ideas. There are certainly some challenges with doing this in native opa and rego. Currently there is no support for recursion so we need to hard code the levels of nesting for the logical operators. I currently stopped at 3 levels but we could do something more reasonable like 8. Projections are also a weak spot. Today I only support very direct keys "resource.data.labels.foo", dealing with collections and aggregations will be tricky.

Assuming we like this approach and move forward, I would consider closing #76 in favor of this since its far more powerful.

Status

t12g commented 5 years ago

I have some concerns about the testability of this approach. Looking at the example, the conditional logic is moved from template to constraint. I think we'd still want to test it (essentially shifting the testing focus from templates to constraints). We can reuse the existing unit test framework, but that still requires some understanding of rego and test setup. Does that diminish the usefulness of this generic policy? Can we simplify/streamline the test setup for each generic policy constraint?

abombss commented 5 years ago

@t12g That is a valid concern and something we should probably have a solution for regardless of this template. I think we can spin up a simple little framework so end users can write tests for their constraints by just supplying a json file of the assets and the expected names of assets for violations.

While this does shift the burden of logic from the template to the constraint, another advantage is the transparency and readability of the constraint. Currently templates are black boxes and unless you are a rego expert you won't understand what it is actually doing. There is no way I could show an auditor or one of my IS people the rego and expect them to understand, I would have a lot better luck walking them through the simple boolean filters. In both instances test cases validating the functionality of the constraint and not just the template would be important.

The only other thought I had to reduce the overhead and learning curve of adding constraints was creating a SQL like syntax and then doing rego codegen for the template and constraint. I am not sure which approach would be better.