-
Notifications
You must be signed in to change notification settings - Fork 6
Rego tests #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Rego tests #14
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
b17b3b4
Added unit tests for the rego policies
kommendorkapten 189ff62
add workflow to test rego policies
kommendorkapten 70b2540
merge fixes
kommendorkapten 99b23e2
merge changes
kommendorkapten 248e0a0
added newline
kommendorkapten 40e83f2
install opa agent
kommendorkapten 2ffbeaf
spelling errors
kommendorkapten ca86363
comments and consistent rego
kommendorkapten aaf42e9
make sure the predicate is a SLSA build provenance
kommendorkapten be288d6
added test to verify custom predicates too
kommendorkapten e6de0d3
Updated documentation
kommendorkapten 4954c91
Policy updates.
kommendorkapten 7d6594e
use bash
kommendorkapten 1d8eb84
chmod +x
kommendorkapten e541004
added comment
kommendorkapten c6f5cd4
fixed a spelling error
kommendorkapten 272afe0
spelling fix
kommendorkapten File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| name: Test rego examples | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| pull_request: {} | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| name: Test | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
|
|
||
| - name: Setup OPA | ||
| uses: open-policy-agent/setup-opa@34a30e8a924d1b03ce2cf7abe97250bbb1f332b5 # 2.2.0 | ||
| with: | ||
| version: latest | ||
|
|
||
| - name: Test | ||
| run: | | ||
| make test-rego | ||
|
|
||
| - name: Verify constraint files | ||
| shell: bash | ||
| run: | | ||
| ./scripts/diff_policy.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Policy tests | ||
|
|
||
| The example policies in the OPA Gatekeeper constraint files are also | ||
| defined in [policies.rego], with added unit tests. These policies are | ||
| the ones that are copied into the [constraint | ||
| templates](../validation). | ||
|
|
||
| These tests and example data provide a great starting place for users | ||
| that want to customize the policies, and would like to have the | ||
| opportunity to test the policy on real data. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package policies | ||
|
|
||
| fromOrg (resp, orgs) if { | ||
| some i, j, k, l | ||
| provenance := "https://slsa.dev/provenance/v1" | ||
| issuer := "https://token.actions.githubusercontent.com" | ||
|
|
||
| provenance == resp.responses[i][j][k].statement.predicateType | ||
| issuer == resp.responses[i][j][k].signature.certificate.issuer | ||
| orgUri := resp.responses[i][j][k].signature.certificate.sourceRepositoryOwnerURI | ||
| # Prefix the org name with / before doing comparison | ||
| endswith(orgUri, concat("", ["/", orgs[l]])) | ||
| } | ||
|
|
||
| fromRepo (resp, repos) if { | ||
| some i, j, k, l | ||
| provenance := "https://slsa.dev/provenance/v1" | ||
| issuer := "https://token.actions.githubusercontent.com" | ||
|
|
||
| provenance == resp.responses[i][j][k].statement.predicateType | ||
| issuer == resp.responses[i][j][k].signature.certificate.issuer | ||
| uri := resp.responses[i][j][k].signature.certificate.sourceRepositoryURI | ||
| # Prefix the repo name with / before doing comparison | ||
| endswith(uri, concat("", ["/", repos[l]])) | ||
| } | ||
|
|
||
| fromOrgWithSignerRepo(resp, orgs, signerRepos) if { | ||
| some i, j, k, l, m | ||
| provenance := "https://slsa.dev/provenance/v1" | ||
| issuer := "https://token.actions.githubusercontent.com" | ||
|
|
||
| provenance == resp.responses[i][j][k].statement.predicateType | ||
| issuer == resp.responses[i][j][k].signature.certificate.issuer | ||
| orgUri := resp.responses[i][j][k].signature.certificate.sourceRepositoryOwnerURI | ||
| signerUri := resp.responses[i][j][k].signature.certificate.buildSignerURI | ||
| # Verify source owner org is allowed | ||
| endswith(orgUri, concat("", ["/", orgs[l]])) | ||
| # Verify signer org is allowed | ||
| # Remove the path to the repo, workflow and ref | ||
| # find the occurence of `/.github/` and trim everything after it | ||
| p := indexof(signerUri, "/.github/") | ||
| signerRepoTrim := substring(signerUri, 0, p) | ||
| # add back the / prefix to get proper delimiter when doing comparison | ||
| signerRepo := concat("", ["/", signerRepoTrim]) | ||
| endswith(signerRepo, concat("", ["/", signerRepos[m]])) | ||
| } | ||
|
|
||
| # This is an example showing how custom attestations can be verified | ||
| customAttestation(resp, val) if { | ||
| some i, j, k | ||
| custom := "https://example.com/custom/v1" | ||
|
|
||
| custom == resp.responses[i][j][k].statement.predicateType | ||
| val == resp.responses[i][j][k].statement.predicate.key1 | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| package policies_test | ||
|
|
||
| import data.policies | ||
| import data.fixtures | ||
|
|
||
| # From org should pass if at least one correct org is provided | ||
| test_from_org_pass if { | ||
| policies.fromOrg(fixtures.octo_org, ["unkown", "octoorg"]) | ||
| } | ||
|
|
||
| # Should fail when issuer is not matching | ||
| test_from_org_issuer if { | ||
| not policies.fromOrg(fixtures.custom_issuer, ["unkown", "octoorg"]) | ||
| } | ||
|
|
||
| # Empty org should fail | ||
| test_from_org_empty if { | ||
| not policies.fromOrg(fixtures.octo_org, [""]) | ||
| } | ||
|
|
||
| test_from_org_empty if { | ||
| not policies.fromOrg(fixtures.octo_org, []) | ||
| } | ||
|
|
||
| # Verify that no prefix weakness exists | ||
| test_from_org_invalid if { | ||
| not policies.fromOrg(fixtures.octo_org, ["unkown", "octoorga", "ctoorg", "aoctoorg"]) | ||
| } | ||
|
|
||
| test_from_org_non_provenance if { | ||
| not policies.fromOrg(fixtures.non_provenance, ["octoorg"]) | ||
| } | ||
|
|
||
| # From repo should pass if at least one repo is valid | ||
| test_from_repo_pass if { | ||
| policies.fromRepo(fixtures.octo_org, ["unkown/unkown", "octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # Should fail when issuer is not matching | ||
| test_from_repo_issuer if { | ||
| not policies.fromRepo(fixtures.custom_issuer, ["unkown/unkown", "octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # Empty repo shoud fail | ||
| test_from_repo_empty if { | ||
| not policies.fromRepo(fixtures.octo_org, [""]) | ||
| } | ||
|
|
||
| test_from_repo_empty if { | ||
| not policies.fromRepo(fixtures.octo_org, []) | ||
| } | ||
|
|
||
| # Verify that no prefix weakness exists | ||
| test_from_repo_invalid if { | ||
| not policies.fromRepo(fixtures.octo_org, ["unkown/unkown", "ctoorg/octorepo", "aoctoorg/octorepo", "octoorga/octorepo", "octoorg/aoctorepo", "octoorg/octorep", "octoorg/octorepoa"]) | ||
| } | ||
|
|
||
| test_from_repo_non_provenance if { | ||
| not policies.fromRepo(fixtures.non_provenance, ["octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # Same repo and signer | ||
| test_with_signer_pass if { | ||
| policies.fromOrgWithSignerRepo(fixtures.octo_org, ["unknown", "octoorg"], ["unkown/octorepo", "octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # With a signer from a different org | ||
| test_with_signer_pass if { | ||
| policies.fromOrgWithSignerRepo(fixtures.reusable, ["unknown", "octoorg"], ["octoorg/octorepo", "buildorg/build-scripts"]) | ||
| } | ||
|
|
||
| # Should fail when issuer is not matching | ||
| test_with_signer_issuer if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.custom_issuer, ["unknown", "octoorg"], ["octoorg/octorepo", "buildorg/build-scripts"]) | ||
| } | ||
|
|
||
| # Empty input | ||
| test_with_signer_empty if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, [], []) | ||
| } | ||
|
|
||
| test_with_signer_empty if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, [""], []) | ||
| } | ||
|
|
||
| test_with_signer_empty if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, [], [""]) | ||
| } | ||
|
|
||
| test_with_signer_empty if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, [""], [""]) | ||
| } | ||
|
|
||
| # Verify that no prefix weakness exists for the orgs | ||
| test_with_signer_invalid if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, ["unkown", "ctoorg", "octoor", "aoctoorg", "octoorga"], ["octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # Verify that no prefix weakness exists for the signer repos | ||
| test_with_signer_invalid if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.reusable, ["octoorg"], ["ctoorg/octorepo", "octoorg/octorep", "octoor/octorepo", "octoorg/ctorepo"]) | ||
| } | ||
|
|
||
| # Make sure that a JSON doc matching the provenance does not pass | ||
| # if the predicate type is differing | ||
| test_with_signer_non_provenance if { | ||
| not policies.fromOrgWithSignerRepo(fixtures.non_provenance, ["octoorg"], ["buildorg/build-scripts"]) | ||
| } | ||
|
|
||
| # If multiple attestations are returned, the verification should still pass | ||
| test_multiple_attestations if { | ||
| policies.fromOrgWithSignerRepo(fixtures.multiple, ["octoorg"], ["octoorg/octorepo"]) | ||
| } | ||
|
|
||
| # Custom attestations should also work | ||
| test_custom_attestation if { | ||
| policies.customAttestation(fixtures.multiple, "value1") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -ue -o pipefail | ||
|
|
||
| # The policy definitions differs slightly from within the constraint | ||
| # tempalte, and the rego definitions used during testing. | ||
| # Extract the policies from both definitions, strip newlines and white | ||
| # spaces, then compare them to detect drift. | ||
|
|
||
| diffp() { | ||
| file=$1 | ||
| func=$2 | ||
|
|
||
| # The regex to match the function definition contains three preceding | ||
| # whitespaces to not match the location where it's called. | ||
| got=`perl -0777 -ne "print \\$1 if /( ${func}.*?})/s" validation/${file} \ | ||
| | perl -ne '$. > 1 && print'| tr -d ' \n'` | ||
| want=`perl -0777 -ne "print \\$1 if /(${func}.*?})/s" rego/policies.rego \ | ||
| | perl -ne '$. > 1 && print' | tr -d ' \n'` | ||
|
|
||
| if [ "${got}" != "${want}" ]; then | ||
| echo "policy ${func} differs in constraint template ${file}" | ||
| echo ${got} | ||
| echo vs | ||
| echo ${want} | ||
| exit 1 | ||
| fi | ||
| } | ||
|
|
||
| diffp from-org-constraint-template.yaml fromOrg | ||
| diffp from-org-with-signer-constraint-template.yaml fromOrgWithSigner | ||
| diffp from-repo-constraint-template.yaml fromRepo | ||
|
|
||
| echo "No differences detected" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.