-
Notifications
You must be signed in to change notification settings - Fork 5
Example: How can you use Lowkey Vault in your tests
Although it is not rocket-science to use Lowkey Vault, it is not trivial either. We have prepared example projects to make it a bit more easy. Before you would scroll down to find the example you need, please consider reading the following general description.
To start Lowkey Vault, and integrate it with your test code, you need the things listed below.
You have multiple options (Jar, Docker, Testcontainers) to start up your app, but one thing is common: you need to figure out which features you will need and set the start-up parameters accordingly. You can find the complete list of supported parameters here.
In case you decide to use Docker, you can start with the readme for the basics or see this example project to see a more complex demo.
You will need to remember which port you are using, and whether you have automatically initialized vaults and test data.
If you have already initialized Lowkey Vault by importing vaults/keys/secrets at startup, and you don't need anything else for your tests, you can skip this step. Otherwise, you should connect to your Lowkey Vault instance using the management API to manage your vaults and add content to them using the familiar Keys or Secrets SDK of the language you are using for Azure integration. Please read the following steps to see how you can connect in case you are not familiar with it so far.
As Azure Key Vault is using HTTPS connections, it is advisable for the test double to mimic this, and use HTTPS as well. Therefore, Lowkey Vault is shipping with a self-signed certificate. This means that every respectable language will give some kind of error by default as trusting self-signed certificates can be risky. In order to solve this, you will need to either trust only the self-signed certificate of Lowkey Vault, or you may choose to trust all self-signed certificates on your development or CI environment but use proper certificate validation in every other case.
Note
In case you need help with exporting/importing certificates, you might want to refer to this page.
Tip
You can also configure Lowkey Vault to use your own certificate for HTTPS communication. Please read this page for more details.
It is recommended to rely on strict certificate validation by default and only accept self-signed certificates as an exception on the specific envs.
If you need only one vault, you can simply use https://localhost:8443
(or the port number you have selected in step 1).
In every other case, you need to read this section. As the actual vaults inside Lowkey Vault are identified by their base URLs due to the fact that client SDKs are expecting this too, we needed to allow using different subdomains for each vault. At the same time, we will still end up using localhost when connecting to the instance. To solve this, you might want to consider using the Host
HTTP header to tell Lowkey Vault which vault you want to use, while sending your requests to the localhost address. The Java client can solve this by introducing the concept of logical and physical addresses, sending the request to the physical address, but automatically setting the Host
header to the value provided by the test code. For example our test code would set up a client to connect to https://default.localhost:8443
but under the hood the logical address would be translated to https://localhost:10443
where the container is listening and the request is sent there with the Host
header using the logical default.localhost:8443
value.
By default, the real Azure Key Vault authentication supports a number of ways we can provide our credentials. Unfortunately, since Lowkey Vault is not a real service and does not integrate with any Azure services, we can't and shouldn't rely on the real authentication. This means in practice, that when we are preparing our test Key Vault client of the Azure SDK we are using, we need to use a Fake credential token. This is roughly the same on each language. There is a base type for token credentials which is the root of all specific credentials. We need to set up our own credential implementation that is not doing anything in general, only returning a dummy string when asked for a token.
If you wish to minimize the amount of custom code that is added to the application just for the sake of the tests, then you can try running Lowkey Vault with an additional Assumed Identity container. On a local machine, even the "default" configuration should work most of the time, starting a container with the 169.254.269.254
IP. This will confuse the ManagedIdentityCredential implementation behind the DefaultAzureCredential to use the dummy token provided by Assumed Identity and bypass authentication in Lowkey Vault (as it does not require a real token, just the existence of the header).
If you need to execute your tests in the cloud (for example on a CI instance running in Azure), then you cannot use the "default" configuration because 169.254.269.254
will be most likely already in use. To solve this, you need to run Assumed Identity in a non-default configuration, for example by using the exposed port of 8080, accepting requests at http://localhost:8080. In this case, you need to set some environment variable to tell the ManagedIdentityCredential to connect to localhost instead of the default 169.254.269.254
IP. The different client implementations of the different languages require different environment variables, please see these in the example projects or in the table below:
Name | Java | .Net | Python | Go | NodeJs | Example value |
---|---|---|---|---|---|---|
AZURE_POD_IDENTITY_AUTHORITY_HOST | X | X | http://localhost:8080/ | |||
IMDS_ENDPOINT | X | http://localhost:8080/ | ||||
IDENTITY_ENDPOINT | X | X | X | X | http://localhost:8080/metadata/identity/oauth2/token | |
IDENTITY_HEADER | X | X | X | header |
Tip
If you are using the Assumed Identity container with other than the 169.254.269.254
IP, the same functionality is provided by the recent Lowkey Vault containers as well on the :8080/metadata/identity/oauth2/token
endpoint, so you don't need two containers.
When your tests are running, you can use Lowkey Vault instead of the real Azure Key Vault by following the steps described above. If your tests are read-only (not changing any vault content) you can get away with a single vault, but as soon as your tests are writing the vaults, you will need to consider test isolation and potentially setting up multiple vaults for the different scenarios to avoid dependencies between test cases.
When you are finished with the test execution, you can simply throw away Lowkey Vault data by stopping the container (or the Jar process).
- Java: https://github.com/nagyesta/lowkey-vault-example
- .Net: https://github.com/nagyesta/lowkey-vault-example-dotnet
- Python: https://github.com/nagyesta/lowkey-vault-example-python
- Go: https://github.com/nagyesta/lowkey-vault-example-go
- Node.js: https://github.com/nagyesta/lowkey-vault-example-nodejs
- Docker: https://github.com/nagyesta/lowkey-vault-example-docker