-
Check the latest OPA release and download it.
-
Put the binary file in the
PATH
of your system -
Allow its execution with something like
chmod 755 ~/opa
-
Run opa in server mode with the sample policies:
cd examples opa run -s data.json app.rego
In this folder (examples) you will find a simple app.py
file that contains endpoints to test how you can see some
data using OPA. For commodity purposes the user id will be passed in the request using the header Authorization.
Run the app.py file with your IDE. It will run in http://localhost:5000
-
Check the home page curl http://localhost:5000
-
Check list of users using a non admin user: Denied
curl -X GET \ http://localhost:5000/list \ -H 'Authorization: paul' \ -H 'Content-Type: application/json'
-
Check list of users using an admin user: Granted
curl -X GET \ http://localhost:5000/list \ -H 'Authorization: eliux' \ -H 'Content-Type: application/json'
-
Add a new user (steve) data using an admin user: Granted
curl -X POST \ http://localhost:5000/data/steve \ -H 'Authorization: steve' \ -H 'Content-Type: application/json' \ -d '{ "fullname": "Steve Perez", "city": "New York", "salary": 3400, "biography": "Studied in harvard. Leaves in Miami, Florida" }'
-
Get new user's data using another non admin user: Denied
curl -X GET \ http://localhost:5000/data/steve \ -H 'Authorization: paul' \ -H 'Content-Type: application/json'
-
Get new user's data using an admin user: Granted
curl -X GET \ http://localhost:5000/data/steve \ -H 'Authorization: eliux' \ -H 'Content-Type: application/json'
-
Get new user's data using same user, yet not a admin one: Granted
curl -X GET \ http://localhost:5000/data/steve \ -H 'Authorization: steve' \ -H 'Content-Type: application/json'
-
Try to delete a user using the same user but not an admin one: Denied
curl -X DELETE \ http://localhost:5000/data/steve \ -H 'Authorization: steve' \ -H 'Content-Type: application/json'
-
Try to delete a user using an admin user: Granted
curl -X DELETE \ http://localhost:5000/data/steve \ -H 'Authorization: eliux' \ -H 'Content-Type: application/json'
When you try to enforce policies beyond the endpoint layer you may not want to evaluate policies just depending on the data related to the user request, but probably you need to be aware of the parameters of a function. E.g.
- We want to create a function for logging data in a remote server. For this purpose we will create a log dedicated
function called
log_remotely
, which will be used in multiple endpoints. - The log function will be allowed to log only info generated by admin users or if the content to be logged names any admin user.
- As the logging will be used in difference execution points of our app, the input of the corresponding policies should be independent of the request. In such cases its better to use a Policy Enforcement Point to enforce specialized policies for this particular scenario of security.
- A new OPA package called
logging
will be created to enforce this particular set of policies.
In this example project, logging a message will be allowed if:
- The requesting user is administrator or
- The logged content contains information about an administrator
You can see the implementation of the PEP in Python in utils.py and the policies in logging.rego.
Follow the following steps to demo this functionality.
- Create a valid non admin user
curl -X POST \
http://localhost:5000/data/steve \
-H 'Authorization: eliux' \
-H 'Content-Type: application/json' \
-d '{
"fullname": "Steve Perez",
"city": "New York",
"salary": 3400,
"biography": "Studied in harvard. Leaves in Miami, Florida"
}'
As the user executing the query is administrator you will see a log that says:
Updated user steve with data {...}
Which means that when the function utils.log_remotely
the OPA
returned true
for the given input and the logging
routing was executed successfully.
- List the created user data with a non valid user
curl -X GET \
http://localhost:5000/data/steve \
-H 'Authorization: steve' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: dba83620-3117-4a57-b330-f1b0efd93c0b' \
-H 'cache-control: no-cache'
For the previous request the OPA
policies of the application (app.rego) will allow steve to see its own data.
Nonetheless, as steve is not an administrator and no admin user was referenced in the added content the previous
request wont be logged.
- Lets try the previous request but this time with an admin user.
curl -X GET \
http://localhost:5000/data/steve \
-H 'Authorization: eliux' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: dba83620-3117-4a57-b330-f1b0efd93c0b' \
-H 'cache-control: no-cache'
You should get something like
Logged remotely: Queried user steve
Check the logging_test.rego to check other valid and invalid queries.