{"id":13788016,"url":"https://github.com/k8spin/opa-k8s-development","last_synced_at":"2025-09-16T04:54:17.853Z","repository":{"id":124627495,"uuid":"207083512","full_name":"k8spin/opa-k8s-development","owner":"k8spin","description":"Contains a valid OPA unit testing environment","archived":false,"fork":false,"pushed_at":"2019-09-08T11:14:15.000Z","size":134,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-15T17:46:57.035Z","etag":null,"topics":["development","kubernetes","mutation","opa","openpolicyagent","rego","testing","validation"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/k8spin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-08T08:29:18.000Z","updated_at":"2024-07-10T08:37:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a753e43-f3b4-4445-a37d-5edebdc329e1","html_url":"https://github.com/k8spin/opa-k8s-development","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/k8spin/opa-k8s-development","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k8spin%2Fopa-k8s-development","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k8spin%2Fopa-k8s-development/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k8spin%2Fopa-k8s-development/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k8spin%2Fopa-k8s-development/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/k8spin","download_url":"https://codeload.github.com/k8spin/opa-k8s-development/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k8spin%2Fopa-k8s-development/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275364727,"owners_count":25451515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-16T02:00:10.229Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["development","kubernetes","mutation","opa","openpolicyagent","rego","testing","validation"],"created_at":"2024-08-03T21:00:34.493Z","updated_at":"2025-09-16T04:54:17.835Z","avatar_url":"https://github.com/k8spin.png","language":null,"funding_links":[],"categories":["Kubernetes"],"sub_categories":["Built with Wasm"],"readme":"# OPA Kubernetes validation and mutation testing environment\n\n![OPA Logo](./assets/opa.png)\n\nThis project makes easy to develop `deny` rules and `patches` mutations. In this repository, you will find a `main.rego` file which is in charge of generating the expected Kubernetes API `json` response in the validation and mutation stage along with a set of basic `deny` rules and it's tests + mocks.\n\n[![Build Status](https://travis-ci.org/k8spin/opa-k8s-development.svg?branch=master)](https://travis-ci.org/k8spin/opa-k8s-development)\n\n## TL;DR\n\n```bash\n$ opa test -v .\n[angel@elitebook opa-k8s-development]$ opa test -v .\ndata.kubernetes.admission.test_create_ingress_existing_in_other_namespace: PASS (719.34µs)\ndata.kubernetes.admission.test_create_client_valid_ingress: PASS (503.277µs)\ndata.system.test_default_response: PASS (495.764µs)\ndata.kubernetes.admission.test_invalid_client_pod_priorityclass: PASS (527.651µs)\ndata.kubernetes.admission.test_valid_client_pod_priorityclass: PASS (472.089µs)\n--------------------------------------------------------------------------------\nPASS: 5/5\n\n```\n\n## OPA Webhooks\n\nOPA and Kubernetes has to be configured registering a validation and mutation webhook into the Kubernetes API. This topic is out of the scope of this project but you can read more about it in the [official OPA documentation](https://www.openpolicyagent.org/docs/latest/kubernetes-admission-control).\n\nBut, you have to keep in your mind the following diagram:\n\n![Kubernetes Request FLOW](./assets/flow.png)\n\nThe important thing here is to know that the mutation phase is triggered before the validation one.\n\n## Project structure\n\nThis repository contains three different types of rego files to make it easy to extend this environment:\n\n- `[KIND].rego`: This file contains the `deny` or `patches` rules to validate or mutate a request.\n- `[KIND]-test.rego`: This one contains a set of tests related to the testing kind specified in its name.\n- `[KIND]-mocks.rego`: This file contains a series of Kubernetes requests to use as mocked requests in the tests.\n\nThere are also a couple of special rego files:\n\n- `main.rego` and `main-test.rego`: It contains the structures to build the kubernetes api responses used to validate and mutate the incoming requests.\n\n### main.rego\n\n```rego\npackage system\n\nimport data.kubernetes.admission\n\nmain = {\n\t\"apiVersion\": \"admission.k8s.io/v1beta1\",\n\t\"kind\": \"AdmissionReview\",\n\t\"response\": response,\n}\n\ndefault response = {\"allowed\": true}\n\nresponse = {\n\t\"allowed\": false,\n\t\"status\": {\"reason\": reason},\n} {\n\treason := concat(\", \", admission.deny)\n\treason != \"\"\n}\n\nresponse = {\n\t\"allowed\": true,\n\t\"patchType\": \"JSONPatch\",\n\t\"patch\": patch_bytes,\n} {\n\treason := concat(\", \", admission.deny)\n\treason == \"\"\n\tpatch := {xw | xw := admission.patches[_][_]}\n\tpatch_json := json.marshal(patch)\n\tpatch_bytes := base64.encode(patch_json)\n}\n```\n\nLet's review this **important** file. The `main` structure contains the common part of a validate and mutate response. In the `main` structure it's present a `response` attribute. This attribute will get three different values depending of the rules (deny and patches) applied to the incoming requests:\n\n- If no deny and no patches applied to the incoming request, it will use the `default response`.\n- If not deny rules applied, `reason == \"\"`, the response will be `\"patchType\": \"JSONPatch\",` with the patches applied to the request *(can be empty)*.\n- If some deny rules returned a reason, `reason != \"\"`, the response will be `\"allowed\": false, \"status\": {\"reason\": reason},`. The client will get the reason message in the response.\n\nIt's really important to know that the same input has to generate only one output. OPA allows a function to return two different outputs, but kubernetes only accepts one. This is the reason why both *(no default)* response structures is exclusive using the *reason empty comparison*.\n\n\n## Using it\n\nTo use this testing environment you will need to clone this repository and download the latest [OPA](https://www.openpolicyagent.org/) release *(actual version: [v0.13.5](https://github.com/open-policy-agent/opa/releases/tag/v0.13.5))*. It's not needed to have a kubernetes cluster. Remember, this project is useful in the [OPA](https://www.openpolicyagent.org/) rules/mutations development stage.\n\n\nThe following commands have been executed in a [`centos:7` container image](https://hub.docker.com/_/centos?tab=tags) to make it repeatable and cleaner:\n```bash\n$ docker run -it --rm centos:7 /bin/bash\n[root@d8997b63a370 /]# yum install -y wget git # Output hidden\n[root@d8997b63a370 /]# git clone https://github.com/k8spin/opa-k8s-development.git\nCloning into 'opa-k8s-development'...\nremote: Enumerating objects: 26, done.\nremote: Counting objects: 100% (26/26), done.\nremote: Compressing objects: 100% (20/20), done.\nremote: Total 26 (delta 10), reused 19 (delta 5), pack-reused 0\nUnpacking objects: 100% (26/26), done.\n[root@d8997b63a370 /]# wget -q https://github.com/open-policy-agent/opa/releases/download/v0.13.5/opa_linux_amd64 -O opa\n[root@d8997b63a370 /]# chmod +x opa\n[root@d8997b63a370 /]# ./opa test -v opa-k8s-development/\ndata.kubernetes.admission.test_create_ingress_existing_in_other_namespace: PASS (748.309µs)\ndata.kubernetes.admission.test_create_client_valid_ingress: PASS (522.186µs)\ndata.system.test_default_response: PASS (550.857µs)\ndata.kubernetes.admission.test_invalid_client_pod_priorityclass: PASS (520.333µs)\ndata.kubernetes.admission.test_valid_client_pod_priorityclass: PASS (609.106µs)\n--------------------------------------------------------------------------------\nPASS: 5/5\n```\n\n## Disclaimer\n\nThis project was released by the [K8Spin](https://k8spin.cloud) team to show you how we develop new `deny` and `patch` kubernetes rules. \nThis is the main structure with a set of basic rules *(demo rules)*. [K8Spin](https://k8spin.cloud) has it owns rules *(no released, security matters)*. \nSo, you are free to pick up this project and start developing new rules without having to deploy untested rules to a kubernetes cluster.\n\nIf you find out a better way to develop OPA rules, let us know :). Don't forget to [join our slack group](https://slack.k8spin.cloud).\n\nThanks!\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk8spin%2Fopa-k8s-development","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fk8spin%2Fopa-k8s-development","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk8spin%2Fopa-k8s-development/lists"}