Skip to content

Example: How can you use Lowkey Vault in your tests

Esta Nagy edited this page Jul 12, 2024 · 15 revisions

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.

In general

To start Lowkey Vault, and integrate it with your test code, you need the things listed below.

1. Start Lowkey Vault

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.

2. Prepare your test double

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.

3. Connecting using HTTPS

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.

4. Using multiple subdomains (optional)

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.

5. Authentication

Easy option

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.

Using DefaultAzureCredential

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.

6. Using the vault

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.

7. Clean-up

When you are finished with the test execution, you can simply throw away Lowkey Vault data by stopping the container (or the Jar process).

Examples