Add secrets to your app
You can add new secrets to your app on the GOV.UK Kubernetes platform.
Before you create a secret, check whether you need to use a secret or if you should use another method instead, such as AWS Identity and Access Management (IAM).
If you decide that you need to use a secret, check if that secret already exists in the AWS Secrets Manager. If the secret does exist, use this secret instead of duplicating it.
If the secret does not already exist, you need to create it. To create a secret, you must:
- have access to AWS
- create the secret in AWS Secrets Manager
- define an
ExternalSecret
in Kubernetes - use the resulting Kubernetes secret inside the app
The Kubernetes ExternalSecret
defines the mapping between the AWS Secrets Manager secret and the Kubernetes secret inside your app.
The Kubernetes secret itself is the sensitive information that this process stores, manages and retrieves.
Creating the secret in AWS Secrets Manager
You can create 2 types of secret in AWS Secrets Manager:
- an AWS managed database secret
- a non-database secret
Creating an AWS managed database secret
Open the AWS Secrets Manager console. You will need to sign in if you have not already.
You must create the secret in the 3 AWS accounts for integration, staging and production.
Select Store a new secret.
Select the appropriate secret type, for example Credentials for Amazon RDS database.
Enter the Username and Password for the database and select Next.
Select the database that you want to connect to and select Next.
Review the secret and then select Store.
Repeat this process for all 3 accounts.
Creating a non-database secret
Open the AWS Secrets Manager console. You will need to sign in if you have not already.
You must create the secret in the 3 AWS accounts for integration, staging and production.
Select Store a new secret.
Select the Other type of secret secret type, enter the secret Key and Value, and then select Next.
- Key is a unique identifier for the secret
- Value is the secret you want to store
Enter the Secret name. You should also enter a Description.
The description should describe what the secret is used for and where to get the secret value.
Add a Tag. Enter
added-manually
into the Key field andtrue
into the Value field, and select Next.Make sure Automatic rotation is not enabled and select Next.
Review the secret and then select Store.
Repeat this process for all 3 accounts.
Defining an ExternalSecret
in Kubernetes
The Kubernetes ExternalSecret
defines the mapping between the AWS Secrets Manager secret and the Kubernetes secret inside your app.
Go to the
external-secrets
chart in thegovuk-helm-charts
repo.Select your app’s folder, or create the folder if necessary.
Create a new
.yaml
file with a descriptive name.You should follow the same naming conventions as existing
.yaml
files:- use lowercase
- put hyphens between words
- do not include the app name
Define the
ExternalSecret
, using the following format:apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: <APPNAME-SECRETNAME> labels: {{- include "external-secrets.labels" . | nindent 4 }} annotations: kubernetes.io/description: > <DESCRIPTION> spec: refreshInterval: {{ .Values.externalSecrets.refreshInterval }} secretStoreRef: name: aws-secretsmanager kind: ClusterSecretStore target: name: <APPNAME-SECRETNAME> dataFrom: - extract: key: govuk/<APPNAME>/<SECRETNAME>
Where
<APPNAME>
is the name of the app and<SECRETNAME>
is the name of the secret.Make sure the
<DESCRIPTION>
is consistent with the description you created in the AWS Secrets Manager. If theExternalSecret
usesdataFrom.extract
, then the description should also document the fields expected in the YAML structure.For example, to create a secret for the Elections API for the GOV.UK Frontend app, use the following format:
apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: frontend-elections-api labels: {{- include "external-secrets.labels" . | nindent 4 }} annotations: kubernetes.io/description: > Credentials used by Frontend to access external Elections API service. Field names are "key" for the API key and "url" for the endpoint URL of the Elections API. spec: refreshInterval: {{ .Values.externalSecrets.refreshInterval }} secretStoreRef: name: aws-secretsmanager kind: ClusterSecretStore target: name: frontend-elections-api dataFrom: - extract: key: govuk/frontend/elections-api
Save the
.yaml
file and merge the change.Check the Argo CD dashboard for the following environments to find out whether you successfully changed the
external-secrets
chart:
Use the Kubernetes secret inside the app
You have:
- created the secret in AWS Secrets Manager
- defined the Kubernetes
ExternalSecret
, which maps the AWS Secrets Manager secret to the Kubernetes secret inside the app
Now you can use the Kubernetes secret inside the app referring to it in the app’s Helm values.
Go to the
app-config
chart.Select the
values-<ENVIRONMENT>.yaml
file that you want. For example, select thevalues-integration.yaml
for the integration environment.In this
.yaml
file, find the app that you are adding a secret to.Add a
secretKeyRef
to the app’sextraEnv
. This depends on:- what type of secret you selected in the AWS Secrets Manager (managed database or non-database)
- how you defined the mapping in the Kubernetes
ExternalSecret
For example, to define a non-database secret, you would use the following format or something similar:
- name: <ENV_VAR_NAME> valueFrom: secretKeyRef: name: <APPNAME-SECRETNAME> key: <KEY>
The
<ENV_VAR_NAME>
is the name of the environment variable whose value you want to be set to the value from the secret.The
<APPNAME-SECRETNAME>
in this file must match the<APPNAME-SECRETNAME>
in the.yaml
template in theexternal-secrets
chart.The
<KEY>
must match the Key in the AWS Secrets Manager secret.Save the
.yaml
file and merge the change.If you are not sure how to define the secret in the
.yaml
file, ask Platform Engineering team and we’ll help you.
Supporting information
The GOV.UK Kubernetes platform uses the External Secrets Operator to manage secrets.
The operator reads information from external APIs and automatically injects the information values into a Kubernetes secret.
For more information, see the: