Skip to content

Commit 0fe3079

Browse files
authored
Merge branch 'main' into kris.kennaway/fix-issetstmt-unmarshal
2 parents 959bab4 + f6c20b0 commit 0fe3079

File tree

3 files changed

+99
-72
lines changed

3 files changed

+99
-72
lines changed

docs/content/contrib-code.md

+22-12
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@ If you are contributing code, please consider the following:
1111
- Most changes should be accompanied with tests.
1212
- All commits must be signed off (see next section).
1313
- Related commits must be squashed before they are merged.
14-
- All tests must pass and there must be no warnings from the `make
15-
check` target.
14+
- All tests must pass and there must be no warnings from the `make check` target.
1615

17-
If you are new to Go, consider reading [Effective
18-
Go](https://golang.org/doc/effective_go.html) and [Go Code Review
19-
Comments](https://github.com/golang/go/wiki/CodeReviewComments) for
20-
guidance on writing idiomatic Go code.
16+
If you are new to Go, consider reading
17+
[Effective Go](https://golang.org/doc/effective_go.html) and
18+
[Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
19+
for guidance on writing idiomatic Go code.
2120

2221
When you implement new features in OPA, consider whether the
2322
types/functions you are adding need to be exported. Prefer
@@ -35,7 +34,7 @@ OPA users (e.g., vendoring conflicts, security, debugging, etc.)
3534

3635
### Commit Messages
3736

38-
Commit messages should explain *why* the changes were made and should probably
37+
Commit messages should explain _why_ the changes were made and should probably
3938
look like this:
4039

4140
```
@@ -62,6 +61,7 @@ format:
6261
```
6362

6463
For example, a change to the `ast` package:
64+
6565
```
6666
ast: Fix X when Y happens
6767
@@ -72,6 +72,7 @@ Signed-off-by: Random J Developer <[email protected]>
7272
```
7373

7474
or a change in the OPA website content (found in `./docs/content`):
75+
7576
```
7677
docs/website: Add X to homepage for Y
7778
@@ -103,6 +104,16 @@ Git has a `-s` command line option to do this automatically.
103104

104105
You can find the full text of the DCO here: https://developercertificate.org/
105106

107+
{{< info >}}
108+
**Note:** If using AI or machine learning tools to assist in the authoring
109+
of OPA patches, you must ensure the code you produce is compliant with the
110+
DCO requirements, and OPA's license. All commits in your patch _must_ be signed
111+
off by a human author.
112+
113+
The OPA maintainers reserve the right to request additional information about
114+
patches and reject PRs where code origin cannot be verified.
115+
{{< /info >}}
116+
106117
### Code Review
107118

108119
Before a Pull Request is merged, it will undergo code review from other members
@@ -130,7 +141,7 @@ their own commit and added to the PR.
130141

131142
If your Pull Request is small though, it is acceptable to squash changes during
132143
the review process. Use your judgement about what constitutes a small Pull
133-
Request. If you aren't sure, send a message to the OPA slack or post a comment
144+
Request. If you aren't sure, send a message to the OPA slack or post a comment
134145
on the Pull Request.
135146

136147
### Vulnerability scanning
@@ -140,8 +151,7 @@ is up to standard. Part of this process is also to run vulnerability scanning
140151
on the code and on the generated container image.
141152

142153
[Trivy](https://aquasecurity.github.io/trivy/) is used to run the aforementioned
143-
vulnerability scanning. To install, follow the [installation instructions](
144-
https://aquasecurity.github.io/trivy/v0.29.2/getting-started/installation/).
154+
vulnerability scanning. To install, follow the [installation instructions](https://aquasecurity.github.io/trivy/v0.29.2/getting-started/installation/).
145155

146156
To run the vulnerability scanning, on the code-base, run the following command:
147157

@@ -172,6 +182,6 @@ Before submitting large changes, please open an issue on GitHub outlining:
172182
- Alternative solutions or approaches if applicable.
173183

174184
Use your judgement about what constitutes a large change. If you aren't sure,
175-
send a message in
176-
[#contributors](https://openpolicyagent.slack.com/archives/C02L1TLPN59) on Slack
185+
send a message in
186+
[#contributors](https://openpolicyagent.slack.com/archives/C02L1TLPN59) on Slack
177187
or submit [an issue on GitHub](https://github.com/open-policy-agent/opa/issues).

docs/content/contributing.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ Slack.
3636

3737
If you want to contribute code check out the
3838
[development reference](../contrib-development/) for pointers on how to get
39-
started.
39+
started. Please note we have some restrictions around the use of AI tooling
40+
which are documented here.
4041

4142
## I'd like to help improve the documentation
4243

@@ -61,4 +62,3 @@ Sounds interesting, we'd love to hear all about it,
6162
drop a message in the
6263
[#contributors](https://openpolicyagent.slack.com/archives/C02L1TLPN59)
6364
channel.
64-

docs/content/terraform.md

+75-58
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ Terraform is about to make before it makes them. Such tests help in different wa
1212
* tests can auto-approve run-of-the-mill infrastructure changes and reduce the burden of peer-review
1313
* tests can help catch problems that arise when applying Terraform to production after applying it to staging
1414

15-
16-
Terraform is a popular integration case for OPA and there are already a number of popular tools for
15+
Terraform is a popular integration case for OPA and there are already a number of popular tools for
1716
running policy on HCL and plan JSONs.
1817
{{<
1918
ecosystem_feature_link
@@ -38,8 +37,9 @@ This tutorial requires
3837
* [Terraform 0.12.6](https://releases.hashicorp.com/terraform/0.12.6/)
3938
* [OPA](https://github.com/open-policy-agent/opa/releases)
4039

41-
(This tutorial *should* also work with the [latest version of Terraform](https://www.terraform.io/downloads.html), but
42-
it is untested. Contributions welcome!)
40+
(This tutorial _should_ also work with the
41+
[latest version of Terraform](https://www.terraform.io/downloads.html), but
42+
it is untested. Contributions welcome!)
4343

4444
# Getting Started
4545

@@ -48,8 +48,8 @@ it is untested. Contributions welcome!)
4848
### 1. Create and save a Terraform plan
4949

5050
Create a [Terraform](https://www.terraform.io/docs/index.html) file that includes an
51-
auto-scaling group and a server on AWS. (You will need to modify the `shared_credentials_file`
52-
to point to your AWS credentials.)
51+
auto-scaling group and a server on AWS.
52+
(You will need to modify the `shared_credentials_file` to point to your AWS credentials.)
5353

5454
```shell
5555
cat >main.tf <<EOF
@@ -97,7 +97,7 @@ terraform show -json tfplan.binary > tfplan.json
9797

9898
Here is the expected contents of `tfplan.json`.
9999

100-
```live:terraform:input
100+
```json
101101
{
102102
"format_version": "0.1",
103103
"terraform_version": "0.12.6",
@@ -467,7 +467,7 @@ practice you would vary the threshold depending on the user.)
467467

468468
**policy/terraform.rego**:
469469

470-
```live:terraform:module:openable
470+
```rego
471471
package terraform.analysis
472472
473473
import input as tfplan
@@ -502,61 +502,72 @@ authz if {
502502
503503
# Compute the score for a Terraform plan as the weighted sum of deletions, creations, modifications
504504
score := s if {
505-
all := [x |
506-
some resource_type
507-
crud := weights[resource_type]
508-
del := crud["delete"] * num_deletes[resource_type]
509-
new := crud["create"] * num_creates[resource_type]
510-
mod := crud["modify"] * num_modifies[resource_type]
505+
all_resources := [x |
506+
some resource_type, crud in weights
507+
508+
del := crud.delete * num_deletes[resource_type]
509+
new := crud.create * num_creates[resource_type]
510+
mod := crud.modify * num_modifies[resource_type]
511511
x := (del + new) + mod
512512
]
513-
s := sum(all)
513+
s := sum(all_resources)
514514
}
515515
516516
# Whether there is any change to IAM
517517
touches_iam if {
518-
all := resources.aws_iam
519-
count(all) > 0
518+
all_resources := resources.aws_iam
519+
count(all_resources) > 0
520520
}
521521
522522
####################
523523
# Terraform Library
524524
####################
525525
526526
# list of all resources of a given type
527-
resources[resource_type] := all if {
528-
some resource_type
529-
resource_types[resource_type]
530-
all := [name |
531-
name := tfplan.resource_changes[_]
527+
resources[resource_type] := all_resources if {
528+
some resource_type, _ in resource_types
529+
530+
all_resources := [name |
531+
some name in tfplan.resource_changes
532532
name.type == resource_type
533533
]
534534
}
535535
536536
# number of creations of resources of a given type
537537
num_creates[resource_type] := num if {
538-
some resource_type
539-
resource_types[resource_type]
540-
all := resources[resource_type]
541-
creates := [res | res := all[_]; res.change.actions[_] == "create"]
538+
some resource_type, _ in resource_types
539+
540+
all_resources := resources[resource_type]
541+
creates := [res |
542+
some res in all_resources
543+
"create" in res.change.actions
544+
]
542545
num := count(creates)
543546
}
544547
545548
# number of deletions of resources of a given type
546549
num_deletes[resource_type] := num if {
547-
some resource_type
548-
resource_types[resource_type]
549-
all := resources[resource_type]
550-
deletions := [res | res := all[_]; res.change.actions[_] == "delete"]
550+
some resource_type, _ in resource_types
551+
552+
all_resources := resources[resource_type]
553+
554+
deletions := [res |
555+
some res in all_resources
556+
"delete" in res.change.actions
557+
]
551558
num := count(deletions)
552559
}
553560
554561
# number of modifications to resources of a given type
555562
num_modifies[resource_type] := num if {
556-
some resource_type
557-
resource_types[resource_type]
558-
all := resources[resource_type]
559-
modifies := [res | res := all[_]; res.change.actions[_] == "update"]
563+
some resource_type, _ in resource_types
564+
565+
all_resources := resources[resource_type]
566+
567+
modifies := [res |
568+
some res in all_resources
569+
"update" in res.change.actions
570+
]
560571
num := count(modifies)
561572
}
562573
```
@@ -569,12 +580,17 @@ ask it to evaluate `terraform/analysis/authz`.
569580
```shell
570581
opa exec --decision terraform/analysis/authz --bundle policy/ tfplan.json
571582
```
572-
```live:terraform/authz:query:hidden
573-
data.terraform.analysis.authz
574-
```
575-
```live:terraform/authz:output
576-
```
577583

584+
```json
585+
{
586+
"result": [
587+
{
588+
"path": "tfplan.json",
589+
"result": true
590+
}
591+
]
592+
}
593+
```
578594

579595
If you're curious, you can ask for the score that the policy used to make the authorization decision.
580596
In our example, it is 11 (10 for the creation of the auto-scaling group and 1 for the creation of the server).
@@ -583,16 +599,21 @@ In our example, it is 11 (10 for the creation of the auto-scaling group and 1 fo
583599
opa exec --decision terraform/analysis/score --bundle policy/ tfplan.json
584600
```
585601

586-
```live:terraform/score:query:hidden
587-
data.terraform.analysis.score
588-
```
589-
```live:terraform/score:output
602+
```json
603+
{
604+
"result": [
605+
{
606+
"path": "tfplan.json",
607+
"result": 11
608+
}
609+
]
610+
}
590611
```
591612

592613
If as suggested in the previous step, you want to modify your policy to make an authorization decision
593614
based on both the user and the Terraform plan, the input you would give to OPA would take the form
594615
`{"user": <user>, "plan": <plan>}`, and your policy would reference the user with `input.user` and
595-
the plan with `input.plan`. You could even go so far as to provide the Terraform state file and the AWS
616+
the plan with `input.plan`. You could even go so far as to provide the Terraform state file and the AWS
596617
EC2 data to OPA and write policy using all of that context.
597618

598619
### 5. Create a Large Terraform plan and Evaluate it
@@ -697,7 +718,7 @@ You learned a number of things about Terraform Testing with OPA:
697718
* OPA gives you fine-grained policy control over Terraform plans.
698719
* You can use data other than the plan itself (e.g. the user) when writing authorization policies.
699720

700-
Keep in mind that it's up to you to decide how to use OPA's Terraform tests and authorization decision. Here are some ideas.
721+
Keep in mind that it's up to you to decide how to use OPA's Terraform tests and authorization decision. Here are some ideas.
701722

702723
* Add it as part of your Terraform wrapper to implement unit tests on Terraform plans
703724
* Use it to automatically approve run-of-the-mill Terraform changes to reduce the burden of peer-review
@@ -712,7 +733,9 @@ If you'd like to explore an additional example that uses terraform modules pleas
712733
### 1. Create and save Terraform module plan
713734

714735
Create a new Terraform file that includes a
715-
security group and security group from a module. (This example uses the module from https://github.com/terraform-aws-modules/terraform-aws-security-group)
736+
security group and security group from a module.
737+
(This example uses the module from
738+
[terraform-aws-modules](https://github.com/terraform-aws-modules/terraform-aws-security-group))
716739

717740
```shell
718741
cat >main.tf <<EOF
@@ -793,12 +816,13 @@ The policy uses the walk keyword to explore the json structure, and uses conditi
793816
package terraform.module
794817
795818
deny contains msg if {
819+
some r
796820
desc := resources[r].values.description
797821
contains(desc, "HTTP")
798822
msg := sprintf("No security groups should be using HTTP. Resource in violation: %v", [r.address])
799823
}
800824
801-
resources := {r |
825+
resources contains r if {
802826
some path, value
803827
804828
# Walk over the JSON tree and check if the node we are
@@ -807,14 +831,11 @@ resources := {r |
807831
walk(input.planned_values, [path, value])
808832
809833
# Look for resources in the current value based on path
810-
rs := module_resources(path, value)
811-
812-
# Aggregate them into `resources`
813-
r := rs[_]
834+
some r in module_resources(path, value)
814835
}
815836
816837
# Variant to match root_module resources
817-
module_resources(path, value) := rs if {
838+
module_resources(path, value) := value if {
818839
# Expect something like:
819840
#
820841
# {
@@ -829,11 +850,10 @@ module_resources(path, value) := rs if {
829850
830851
reverse_index(path, 1) == "resources"
831852
reverse_index(path, 2) == "root_module"
832-
rs := value
833853
}
834854
835855
# Variant to match child_modules resources
836-
module_resources(path, value) := rs if {
856+
module_resources(path, value) := value if {
837857
# Expect something like:
838858
#
839859
# {
@@ -855,12 +875,9 @@ module_resources(path, value) := rs if {
855875
856876
reverse_index(path, 1) == "resources"
857877
reverse_index(path, 3) == "child_modules"
858-
rs := value
859878
}
860879
861-
reverse_index(path, idx) := value if {
862-
value := path[count(path) - idx]
863-
}
880+
reverse_index(path, idx) := path[count(path) - idx]
864881
```
865882

866883
### 4. Evaluate the OPA policy on the Terraform module plan

0 commit comments

Comments
 (0)