Skip to main content

The DfE technical guidance and its content is intended for internal use by the DfE community.

Managing secrets

Azure Key Vault offers a secure and convenient way to store secrets required for application environments and infrastructure configuration.

Key Vault

Create a resource group following the standard naming convention like s146d01-rg where s146 is the project id, d is the development subscription (t for test and p for production) and 01 is an identifier. This can be automated using PowerShell and an ARM template.

The resource group must have the mandatory tags associated with your subscription.

Create a Key Vault in this resource group and name it for example s146d01-shared-kvin region West Europe with Standard pricing tier. Leave Networking defaults (public endpoint).

Repeat for each subscription (development, test, production).

Developer Access

You could grant access in the Access Policies section to yourself and other members of the team who you will allow to access the vault. Remember to grant minimum permissions; if they don’t need to edit, then don’t grant them write.

A better solution is to use a specific user role (using RBAC), which can be elevated via PIM to give access to secrets. This pattern is detailed on the CIP documentation and the implementation is explained below.

Azure service Principal

To be able to retrieve the secrets from an external system like Github actions, you need an Azure Service Principal, which takes the form of an app registration in Azure AD.

See instructions here.

Request roles

You will need to raise a request in Service Now to request roles for both the service principal and for the users to be able to manage the secrets. The sample request may be used for all the subscriptions or one at a time.

Sample Request

Create a request in Service Now: Request something, Non-Standard, Any Other Request, Select an appropriate Category: Non Standard, Business Service: Shared IT Core services, Service Offering: CIP Platform

Configure PIM access to Key Vault following the pattern in https://docs.platform.education.gov.uk/docs/blogs/platform-engineering/key-vault-rbac.html :

- Please create a new role with the name `s146-getintoteachingwebsite-Contributor and Key Vault editor` with the following roles:
    - `Contributor`
    - `Key Vault Certificates Officer`
    - `Key Vault Crypto Officer`
    - `Key Vault Secrets Officer`
- Configure PIM for the `s146-getintoteachingwebsite-Contributor-Delivery Team` user group to access this role

- Change `s146d01-shared-kv` Key Vault permission model to "Azure role-based access control"
- Change `s146t01-shared-kv` Key Vault permission model to "Azure role-based access control"
- Change `s146p01-shared-kv` Key Vault permission model to "Azure role-based access control"

- Please give `Key Vault Reader` and `Key Vault Secrets` roles to service principal `s146d01-keyvault-readonlyaccess` at subscription level in `s146-getintoteachingwebsite-development`.
- Please give `Key Vault Reader` and `Key Vault Secrets` roles to service principal `s146t01-keyvault-readonlyaccess` at subscription level in `s146-getintoteachingwebsite-test`.
- Please give `Key Vault Reader` and `Key Vault Secrets` roles to service principal `s146p01-keyvault-readonlyaccess` at subscription level in `s146-getintoteachingwebsite-production`.

Access secrets from GitHub Actions

Login using the service principal in the workflow.

The secrets can then be retrieved using the Azure/get-keyvault-secrets action.

Access secrets from Terraform

Login using the service principal in Terraform.

The secrets can then be retrieved using the azurerm_key_vault data source.

Store multiple values per secret

The name of a secret must be hard coded in the systems retrieving it. When using infrastructure as code, this name may be present in multiple files which creates a burden to rename or add more secrets.

An alternative is to store a file containing multiple secrets as key-value pairs, for example with YAML. The secrets can be added, removed or updated in the file without changing anything in the code. There are a number of ways to edit or read the secrets.

Edit using Azure CLI

Create a YAML local file and upload it:

az keyvault secret set  --vault-name sXXXd01-kv --name TTA-KEYS --file local_file.yml

Make sure to delete the local file after use.

Read using Azure CLI

Print the file content:

az keyvault secret show  --vault-name sXXXd01-kv --name TTA-KEYS

Make sure to clear the command line after use.

Download to a local file:

az keyvault secret download  --vault-name sXXXd01-kv --name TTA-KEYS --file local_file.yml

Make sure to delete the local file after use.

Read using GitHub Actions

Use the keyvault-yaml-secret action to retrieve a secret from the YAML file.

Read using Terraform

Use the yamldecode function to parse the YAML file and access individual values:

infra_secrets = yamldecode(data.azurerm_key_vault_secret.infra_secrets.value)
paas_password = infra_secrets["paas_password"]

Read and write using the fetch_config.rb script

fetch_config.rb is a convenient ruby script to read and write securely to and from Azure Key Vault and transform into multiple formats.

It is routinely used by developers. See print-app-secrets and edit-app-secrets in this Makefile for example.