Here's the big idea. When you create a new set of Vault policies, you should be able to write tests that confirm your intention. The tests should be easy to write and can be run against a development Vault server that mimics production, or against the production environment, without altering the production environment beyond adding temporary policies.
Let's start with the testing process. Each policy will have a corresponding test file written in yaml
that describes the tests to run against the policy. The test file will contain a series of tests that confirm the policy works as intended. The tests will leverage the sys/capabilities
endpoint to confirm the policy is working as intended.
The test suite will run as part of a CI/CD process. I imagine that initial tests should be able to run locally, creating a temporary development Vault server. Once the policies are committed to the repository and a pull request is created, the test suite will run against a production Vault server (maybe, have to be careful about this part) or against a temporary dev server, depending on the user's preference. The test suite could be run against the production Vault server before a pull request is merged.
Each test should include the following:
path
- The path to be testedactions
- List of action(s) to testresult
- The desired result of the actiontrue
- the action(s) are allowedfalse
- the action(s) are denied
Each test will be a be represented as a map with the path
, actions
, and result
keys. The script will iterate through each test and return a pass or fail result. This will be based on the capabilities response from Vault. If the action is in the capabilities response and the desired result is true
, the test passes. If the action is not in the capabilities response, and the desired result is false
, the test passes. Otherwise the test will fail.
Here's an example of the test file format:
tests:
- path: 'secret/data/taco'
actions: [read]
result: false
- path: 'secret/data/taco'
actions: [update]
result: false
- path: 'secret/data/taco/recipe'
actions: [read, list]
result: true
The Vault namespace, address, and token can defined as part of the run process using environment variables. The script will use the VAULT_ADDR
and VAULT_TOKEN
environment variables to connect to Vault. The VAULT_NAMESPACE
environment variable will be used to set the namespace. If the namespace is not set, the script will use the root namespace.
The Python file test_capabilities.py
will be used to run the tests. The script will take the following arguments:
-p
or-path
- the path to the policy file-t
or-tests
- the path to the test file-d
or-directory
- the path to a directory containing multiple policy files (assumes test files are in atests
subdirectory)-v
or-vaultdev
- spins up a temporary Vault dev server (assumes vault executable is in thePATH
)-j
or-jsonout
- writes the policies being tested to JSON files in the current working directory (useful for OPA testing)
During the testing process, the script will use the token stored in VAULT_TOKEN
to create a temporary policy and token with that policy. Then the script will use the sys/capabilities
and token to test the policy.
The script also checks to see if the tested path is root
protected, and thus needs the sudo
action. If the sudo
action is not found in the capabilities response for a root
protected path and the result
is supposed to be true
, the script will fail the test.
The list of root
protected paths is defined in the sudo_paths.json
file. The list can be updated as needed.
When the testing is complete, the policy token will be revoked and the temporary policy will be removed.
You should start by creating a virtual environment and installing the dependencies:
python -m venv venv
# Linux
source venv/Scripts/activate
# Windows
.\venv\Scripts\Activate.ps1
And install the dependencies:
pip install -r requirements.txt
Run the script to spin up a temporary Vault dev instance and test one of the existing policies:
python test_capabilities.py -p ".\policies\taco.hcl" -t ".\policies\tests\taco.yaml" -v
You can also test all the policies in a directory:
python test_capabilities.py -d ".\policies" -v
You can update the contents of the taco.hcl
and taco_test.yaml
files to test different policies and actions.