Skip to content

Commit

Permalink
Merge pull request #1 from fabriziosestito/feat/policy
Browse files Browse the repository at this point in the history
feat: policy
  • Loading branch information
fabriziosestito authored Oct 25, 2023
2 parents 2755e7c + ed7874f commit be8e444
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
on:
push:
branches:
- main
tags:
- "v*"

name: Release policy

jobs:
test:
name: run tests and linters
uses: kubewarden/github-actions/.github/workflows/reusable-test-policy-rego.yml@v3.1.10

release:
needs: test
permissions:
# Required to create GH releases
contents: write
# Required to push to GHCR
packages: write
# Required by cosign keyless signing
id-token: write

uses: kubewarden/github-actions/.github/workflows/reusable-release-policy-rego.yml@v3.1.10
with:
oci-target: ghcr.io/${{ github.repository_owner }}/tests/raw-validation-opa-policy
artifacthub: false
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
on: [push, pull_request]
name: Continuous integration
jobs:
test:
name: run tests and linters
uses: kubewarden/github-actions/.github/workflows/reusable-test-policy-rego.yml@v3.1.10
with:
artifacthub: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.wasm
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
SOURCE_FILES := $(shell find . -type f -name '*.rego')
# It's necessary to call cut because kwctl command does not handle version
# starting with v.
VERSION ?= $(shell git describe | cut -c2-)

policy.wasm: $(SOURCE_FILES)
opa build -t wasm -e policy/main utility/policy.rego -o bundle.tar.gz policy.rego
tar xvf bundle.tar.gz /policy.wasm
rm bundle.tar.gz
touch policy.wasm # opa creates the bundle with unix epoch timestamp, fix it

.PHONY: test
test:
opa test *.rego

annotated-policy.wasm: policy.wasm metadata.yml
kwctl annotate -m metadata.yml -u README.md -o annotated-policy.wasm policy.wasm

.PHONY: e2e-tests
e2e-tests: annotated-policy.wasm
bats e2e.bats

.PHONY: clean
clean:
rm -f *.wasm *.tar.gz
36 changes: 36 additions & 0 deletions e2e.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bats

@test "accept if the request is valid" {
run kwctl run --raw -e opa annotated-policy.wasm -r test_data/valid.json

# this prints the output when one the checks below fails
echo "output = ${output}"

# request accepted
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*true') -ne 0 ]
}

@test "reject if the request is invalid" {
run kwctl run --raw -e opa annotated-policy.wasm -r test_data/invalid.json

# this prints the output when one the checks below fails
echo "output = ${output}"

# request rejected
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*false') -ne 0 ]
[ $(expr "$output" : '.*User not allowed.*') -ne 0 ]
}

@test "reject if the request has no user field" {
run kwctl run --raw -e opa annotated-policy.wasm -r test_data/invalid_no_user_field.json

# this prints the output when one the checks below fails
echo "output = ${output}"

# request rejected
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*false') -ne 0 ]
[ $(expr "$output" : '.*User not allowed.*') -ne 0 ]
}
24 changes: 24 additions & 0 deletions metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
rules:
mutating: false
contextAware: false
policyType: raw
executionMode: opa
# Consider the policy for the background audit scans. Default is true. Note the
# intrinsic limitations of the background audit feature on docs.kubewarden.io;
# If your policy hits any limitations, set to false for the audit feature to
# skip this policy and not generate false positives.
backgroundAudit: true
annotations:
# kubewarden specific:
io.kubewarden.policy.ociUrl: ghcr.io/kubewarden/tests/raw-validation-opa-policy # must match release workflow oci-target
io.kubewarden.policy.title: raw-validation-opa-policy
io.kubewarden.policy.description: An OPA policy that validates a raw request
io.kubewarden.policy.author: "Kubewarden developers <cncf-kubewarden-maintainers@lists.cncf.io>"
io.kubewarden.policy.url: https://github.com/kubewarden/raw-validation-opa-policy
io.kubewarden.policy.source: https://github.com/kubewarden/raw-validation-opa-policy
io.kubewarden.policy.license: Apache-2.0
# The next two annotations are used in the policy report generated by the
# Audit scanner. Severity indicates policy check result criticality and
# Category indicates policy category. See more here at docs.kubewarden.io
io.kubewarden.policy.severity: medium # one of info, low, medium, high, critical. See docs.
io.kubewarden.policy.category: Resource validation
6 changes: 6 additions & 0 deletions policy.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package validation

deny[msg] {
not input.request.user == "tonio"
msg := "User not allowed"
}
15 changes: 15 additions & 0 deletions policy_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package validation

valid_request = {"request": {"user": "tonio", "action": "eats", "resource": "hay"}}

invalid_request = {"request": {"user": "wanda", "action": "eats", "resource": "banana"}}

test_accept {
res = deny with input as valid_request
count(res) = 0
}

test_reject {
res = deny with input as invalid_request
count(res) = 1
}
8 changes: 8 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": [
"config:base",
"group:allNonMajor",
"schedule:earlyMondays"
],
"labels": ["dependencies"]
}
5 changes: 5 additions & 0 deletions test_data/invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"user": "wanda",
"action": "eats",
"eats": "banana"
}
4 changes: 4 additions & 0 deletions test_data/invalid_no_user_field.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"action": "eats",
"eats": "banana"
}
5 changes: 5 additions & 0 deletions test_data/valid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"user": "tonio",
"action": "eats",
"eats": "hay"
}
12 changes: 12 additions & 0 deletions utility/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Open Policy Agent utility

This folder contains the entry point for Open Policy Agent policies.

Since Open Policy Agent policies have to produce a `RawReviewResponse`
object, this utility library contains the Rego entry point that
generates such `RawReviewResponse`, based on whether the `deny` query
inside the package `validation` (defined by the policy
itself) is evaluated to `true`.

If `deny` evaluates to true, the produced `RawReviewResponse` will
reject the request. Otherwise, it will be accepted.
25 changes: 25 additions & 0 deletions utility/policy.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package policy

import data.validation

main = {
"response": response,
}

default uid = ""

uid = input.request.uid

response = {
"uid": uid,
"allowed": false,
"status": {"message": reason},
} {
reason = concat(", ", validation.deny)
reason != ""
} else = {
"uid": uid,
"allowed": true,
} {
true
}

0 comments on commit be8e444

Please sign in to comment.