As of 10/29/2024
Basis Theory is no longer maintaining this repository.
The Basis Theory Azure KeyVault Emulator to mock interactions with Azure KeyVault using the official Azure KeyVault client
RSA1_5
RSA-OAEP
Azure KeyClient and SecretClient require HTTPS communication with a KeyVault instance.
When accessing the emulator on localhost
, configure a trusted TLS certificate with dotnet dev-certs.
For accessing the emulator with a hostname other than localhost
, a self-signed certificate needs to be generated and trusted by the client. See Adding to docker-compose for further instructions.
Azure KeyClient and SecretClient use a ChallengeBasedAuthenticationPolicy
to determine the authentication scheme used by the server. In order for the KeyVault Emulator to work with the Azure SDK, the emulator requires JWT authentication in the Authorization
header with Bearer
prefix.
KeyVault Emulator only validates the JWT is well-formed.
curl -X 'GET' \
'https://localhost:5551/secrets/foo' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE4OTAyMzkwMjIsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvIn0.bHLeGTRqjJrmIJbErE-1Azs724E5ibzvrIc-UQL6pws'
For the Azure KeyVault Emulator to be accessible from other containers in the same compose file, a new OpenSSL certificate has to be generated:
Replace <emulator-hostname>
and run the following script to generate a new public/private keypair:
openssl req \
-x509 \
-newkey rsa:4096 \
-sha256 \
-days 3560 \
-nodes \
-keyout <emulator-hostname>.key \
-out <emulator-hostname>.crt \
-subj '/CN=<emulator-hostname>' \
-extensions san \
-config <( \
echo '[req]'; \
echo 'distinguished_name=req'; \
echo '[san]'; \
echo 'subjectAltName=DNS.1:localhost,DNS.2:<emulator-hostname>,DNS.3:localhost.vault.azure.net,DNS.4:<emulator-hostname>.vault.azure.net')
Export a .pks
formatted key using the public/private keypair generated in the previous step:
openssl pkcs12 -export -out <emulator-hostname>.pfx \
-inkey <emulator-hostname>.key \
-in <emulator-hostname>.crt
Trust the certificate in the login keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <emulator-hostname>.crt
Add a service to docker-compose.yml for Azure KeyVault Emulator:
version: '3.9'
services:
...
azure-keyvault-emulator:
image: basis-theory/azure-keyvault-emulator:latest
hostname: <emulator-hostname>.vault.azure.net
ports:
- 5001:5001
- 5000:5000
volumes:
- <path-to-certs>:/https
environment:
- ASPNETCORE_URLS=https://+:5001;http://+:5000
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/<emulator-hostname>.pfx
- KeyVault__Name=<emulator-hostname>
Modify the client application's entrypoint to add the self-signed certificate to the truststore. Example using docker-compose.yml to override the entrypoint:
version: '3.9'
services:
my-awesome-keyvault-client:
container_name: my-awesome-client
build:
context: .
depends_on:
- azure-keyvault-emulator
entrypoint: sh -c "cp /https/<emulator-hostname>.crt /usr/local/share/ca-certificates/<emulator-hostname>.crt && update-ca-certificates && exec <original-entrypoint>"
volumes:
- <path-to-certs>:/https
environment:
- KeyVault__BaseUrl=https://<emulator-hostname>.vault.azure.net:5001/
(Optional) Azure KeyVault SDKs verify the challenge resource URL as of v4.4.0 (read more here). To satisfy the new challenge resource verification requirements, do one of the following:
.vault.azure.net
(e.g. localhost.vault.azure.net
). A new entry may need to be added to /etc/hosts
to properly resolve DNS (i.e. 127.0.0.1 localhost.vault.azure.net
).DisableChallengeResourceVerification
to true in your client options to disable verification.
var client = new SecretClient(
new Uri("https://localhost.vault.azure.net:5551/"),
new LocalTokenCredential(),
new SecretClientOptions
{
DisableChallengeResourceVerification = true
});
The provided scripts will check for all dependencies, start docker, build the solution, and run all tests.
Run the following command from the root of the project:
make verify