Last active
October 12, 2021 15:01
-
-
Save rshettynj/c49868a45d7a9208d56465637326c20d to your computer and use it in GitHub Desktop.
Writing OPA rules for JSON files
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
| How to create custom polices as a rule in OPA (Open Policy Agent)? | |
| Requirement: | |
| In DevOPs Practice, you may want to make sure the JSON input files are adhering certain company standards. You need to have a way to | |
| apply such custom polciies as a rule or set of rules and trigger against the JSON file. | |
| You will then fail or pass the JSON in your pipeline based on the status of the policy check. | |
| Scenarios where JSON files needs to be validated: | |
| 1. JSON linting //Basic formatting and Syntax checks. | |
| 2. Sematic checks and business logic checks. | |
| 3. Making sure cloudbees/jenkins/spinnaker/Kubernetes manifests/server configs (all json files essentially) do not have some | |
| questionable or undesired configuration that can mess up someone else's configuration. | |
| 4. DevSecOps. | |
| 5. Cost management where cpu/memory sizing and other cost values/tags needs to be validated/controlled. | |
| With OPA, you can write custom rules for all the above polcies, validate the JSON on the fly and let it pass/fail. | |
| OPA also has integrations with many 3rd party software such as Spinnaker/Kubernetes/Nginx etc.. You can make sure of API calls, | |
| install it as standalone for testing rules as well. | |
| example scenario: | |
| You may be asked to make sure the following in your json - | |
| 1. "limitconcurrent" should be always true. | |
| 2. "lastModifiedBy" should be always be xxx@email.com. | |
| Steps: | |
| 1. Install OPA executable on your jumpbox for testing. | |
| Linux install: curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64 | |
| copy the "opa" binary to your preferred path location. | |
| 2. Create a directory and create two files there. | |
| cat pipeline.json | |
| { | |
| "limitconcurrent": true, | |
| "lastModifiedBy": "xxx@email.com", | |
| "priority": high, | |
| "createdby": "Dan", | |
| "approvedby": "Mac" | |
| } | |
| cat policy.rego | |
| package example | |
| getval = true { | |
| input.limitconcurrent == true | |
| input.lastModifiedBy == "xxx@email.com" | |
| } | |
| //input is the standard name. (do not change). It identifies that value is coming in as input. OPA reads the input file supplied with | |
| handle name called "input". Think of it like json parser like "jq". | |
| In the above rule, if two conditions are true, then getval get true value. | |
| 3. Execute opa eval | |
| opa eval -i pipeline.json -d policy.rego "data.example.getval" | |
| //data is the standard name, do not change. example should match included package name specified. | |
| getval is the function you wrote in policy.rego. | |
| //submitted data should follow this standard: data.<packagename in the rego file>.<function name> | |
| If everything is good (json is as expected), result expression from above command will be true. Or else it will be false. | |
| based on the output you receive, take the next steps. (fail or pass the pipeline, reject or approve workflow etc..) | |
| You can write more complex rules now using OPA's extensive command library and expressions. REGO is the language OPA uses for writing | |
| the rules. | |
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
| Example OPA | |
| 1. checking count | |
| Manually from command line: | |
| cat myfile.json | opa eval --format=pretty -I 'count(input.stages)' | |
| In a rego file, syntax will be: | |
| package example | |
| stagescount = true { | |
| count(input.stages) == 8 | |
| } | |
| opa eval -i myfile.json -d myrego.rego 'data.example.stagescount' | |
| 2. Names of all the stages in the json. | |
| cat myfile.json | opa eval --format=pretty -I 'input.stages[_]' | |
| 3. unique stage names | |
| package example | |
| uniquestagenames = { names | | |
| names := input.stages[_].name | |
| } | |
| opa eval -i myfile.json -d myrego.rego 'data.example.uniquestagenames' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment