Write an authorization policy that controls which HTTP APIs individual users are permitted to execute. The following APIs return the JSON value true if the API call is authorized and false otherwise.
Method | Path | Meaning |
---|---|---|
POST |
/v1/cars |
Create a new car |
GET |
/v1/cars/<id> |
Read details of the given car |
PUT |
/v1/cars/<id> |
Update details of the given car |
DELETE |
/v1/cars/<id> |
Delete the given car |
The input for this policy (the input provided to OPA) is the JSON shown below.
Schema | Example |
---|---|
{ "method": string, "path": array of strings "user": string } |
{ "method": "GET", "path": ["v1", "cars", "id1234"] "user": "alice, } |
Access policy:
- Anyone can run a GET
- Employees can update a car via PUT
- Employees can create new cars via POST
- Only the employee who created a car can DELETE it
Additional information:
- Employees:
- alice
- eve
- ricardo
- carmen
- Car creator:
- id1234: alice
- id2345: alice
- id3456: ricardo
I started by Googling "OPA HTTP API"
and found the following result: https://www.openpolicyagent.org/docs/v0.11.0/http-api-authorization/.
The document was well written and easy to follow, but I didn't see a link to the source code anywhere. I decided to pull down the openpolicyagent/demo-restful-api:0.2
image and look inside the container. I used the code in there as a starting point/template.
I decided to create a VSCode project using some docker-compose
scaffolding that I typically use. I've included everything in this repo. This allowed me to spin up a development/test environment and enable live reloading of the Python Flask application. I wasn't able to figure out if it was possible to enable live reloading of the opa
server so I ended up restarting using docker-compose
to make changes live in the opa
container.
It took some tweaking and tuning of the Flask application to get it working correctly with the Python 3.8.4 Alpine image. Once the Flask application was working, it was straightforward to create the Repo policy and test everything out. I used the following Rego documents as reference https://www.openpolicyagent.org/docs/latest/policy-language/ and https://www.openpolicyagent.org/docs/latest/policy-reference/. I then created requests in Postman to test the various scenarios and started experimenting, debugging, and fixing any issues. Seeing that VSCode has a REST Client extension, I would probably convert the Postman requests to use that so I could keep everything in a single project.
Overall it probably took me around an hour or two to get everything to a point where I was satisfied with the results.
I would probably extend this even further to create a more "production" grade Dockerfile
and docker-compose.yml
file as well as Kubernetes YAML.
- Put the link to any source code for examples at the start of the tutorial/exercise. It wasn't until I completed the exercise that I noticed the link at the bottom of the page.
- Provide a direct link to the source code https://github.com/open-policy-agent/contrib/tree/master/api_authz instead of https://github.com/open-policy-agent/contrib
- Easier to find or better documentation on the possible
opa run
flags, a simple man page style section would be helpful. - A more guided experience or walkthrough of the Rego language with real-world examples and exercises.
This repo only requires that you have docker
and docker-compose
installed. You can use your IDE of choice; I prefer VSCode.
Once you clone the repository, you can use the development-compose-up.sh
and development-compose-down.sh
scripts located in the bin
directory to spin up a development environment.
Saving changes to the server.py
file will trigger a live reload of the Flask application, but changes to the api_authz.rego
file will require restarting the application.