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: trueThe 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:
-por-path- the path to the policy file-tor-tests- the path to the test file-dor-directory- the path to a directory containing multiple policy files (assumes test files are in atestssubdirectory)-vor-vaultdev- spins up a temporary Vault dev server (assumes vault executable is in thePATH)-jor-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.ps1And install the dependencies:
pip install -r requirements.txtRun 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" -vYou can also test all the policies in a directory:
python test_capabilities.py -d ".\policies" -vYou can update the contents of the taco.hcl and taco_test.yaml files to test different policies and actions.