How to Store the PIN Code in the Azure Key Vault?

X-Road Autologin utility can be used to automatically enter the PIN code after xroad-signer has started. The utility can be used to automate entering the PIN code after rebooting the host server. This article explains how the PIN code can be securely stored in the Microsoft Azure Key Vault so that the Autologin utility is able to read it from there.

Azure Key Vault is a cloud service that works as a secure secrets store. It is possible to securely store keys, passwords, certificates, and other secrets.

More information about the Azure Key Vault can be found at: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-overview

Accessing the Secrets

Azure Key Vault can be accessed in multiple ways: web portal, Azure CLI, Powershell, Resource Manager Templates and programming language specific libraries. Below there's an example how to access an existing secret using bash.

Get parameter "mySecret" from vault "niistestkeyvault"
# Step 1: Fetch an access token from an MSI-enabled Azure resource      
# Note that the resource here is https://vault.azure.net for the public cloud, and api-version is 2018-02-01

$ curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net"

{
  "access_token": "...",
  "expires_in": "28800",
  "expires_on": "1566144113",
  "ext_expires_in": "28800",
  "not_before": "1566115013",
  "resource": "https://vault.azure.net",
  "token_type": "Bearer"
}

# Step 2: Pass the access token received from the previous HTTP GET call to the key vault
# Note that "niistestkeyvault" is the name of the vault and "mySecret" is the name of secret to be fetched

$ curl -H "Authorization: Bearer <ACCESS_TOKEN>" "https://niistestkeyvault.vault.azure.net/secrets/mySecret?api-version=2016-10-01"

{
  "value": "SecretValue",
  "id": "https://niistestkeyvault.vault.azure.net/secrets/mySecret/606c7554b9cb4b359e339a9c21330bef",
  "attributes": {
    "enabled": true,
    "created": 1566115101,
    "updated": 1566115101,
    "recoveryLevel": "Purgeable"
  }
}

The example above to work the virtual machine on which the commands are run must have a system assigned managed identity, and the identity must have a permission (list, get) to access the Key Vault where the secret is stored.

Before running the commands above the following steps must be completed (more information):

  1. Create a virtual machine with a system assigned managed identity.
  2. Create a Key Vault.
  3. Add a secret to the Key Vault.
  4. Give the VM identity permission to Key Vault.

Once the steps 1-4 have been completed, the script below can be used for testing. The script requires two arguments:  1) Key Vault name (KEY_VAULT_NAME) and 2) the name of the secret (SECRET_NAME). If the name of the Key Vault is "niistestkeyvault" and the name of the secret is "mySecret", the script is executed like this:

$ ./test.sh niistestkeyvault mySecret

./test.sh <KEY_VAULT_NAME> <SECRET_NAME>
#!/bin/bash
TOKEN=$(curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net"  | jq -r '.access_token')
PIN_CODE=$(curl -H "Authorization: Bearer $TOKEN" "https://$1.vault.azure.net/secrets/$2?api-version=2016-10-01" | jq -r '.value')
echo "${PIN_CODE}"
exit 0

Storing Security Server PIN Code in Key Vault

Security Server PIN code can be stored in Key Vault. In that case a custom bash script (/usr/share/xroad/autologin/custom-fetch-pin.sh) must be implemented according to the auto-login documentation. The script must fetch the PIN code from Key Vault and output the PIN code to stdout. Curl and jq must be installed on the host server. The host server must have an identity that has sufficient permissions to read the Key Vault secret storing the PIN code.

Curl and jq must be installed on the host server.

The host server must have an identity that has sufficient permissions to read the Key Vault secret storing the PIN code.


/usr/share/xroad/autologin/custom-fetch-pin.sh
#!/bin/bash
TOKEN=$(curl --silent -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net"  | jq -r '.access_token')
PIN_CODE=$(curl --silent -H "Authorization: Bearer $TOKEN" "https://<KEY_VAULT_NAME>.vault.azure.net/secrets/<SECRET_NAME>?api-version=2016-10-01" | jq -r '.value')
echo "${PIN_CODE}"
exit 0