Skip to content

Google Secrets Manager

Warning

Google Secrets Manager integration with Kubernetes is currently available as an OPEN BETA. Please report any issues to the #nais channel on Slack.

You may store secrets in Google Secrets Manager as an alternative to the other offered solutions.

As a supplement to Kubernetes Secrets, we also offer one-way synchronization of secrets from Google Secrets Manager to Kubernetes Secrets that you may mount into your applications in the GCP clusters.

Getting started

Tip

See the examples for a complete illustration of the process.

Step 1: Create a Secret in Google Secret Manager

Check

Start at the GCP Console page.

Google Secret Manager start page

Click on the Create Secret button.

Secret Name Restrictions

In order to synchronize the secret to Kubernetes, ensure that the secret name adheres to the following restrictions:

  • Maximum length of 63 characters.
  • May only contain letters, numbers and hyphens (-).
  • Must be lowercase.
  • Must start with a lowercase letter or number.
  • Must end with a lowercase letter or number.

All secrets must exist in the region europe-north1.

This option is found when you click manually manage locations for this secret.

Google Secret Manager Region selection

Unfortunately, we cannot enforce a default value here.

Fill in the Secret value.

Google Secret Manager Secret value field

Step 2: Import Secret to Kubernetes

Only available in GCP

Importing a secret to Kubernetes is only possible in the GCP clusters.

One-way Synchronization

The secret in Google Secret Manager is the single source of truth.

Modifications to the secret in Kubernetes will NOT be synchronized back to Google Secret Manager.

Any modifications done in Kubernetes will be overwritten by the actual secret found in Google Secret Manager.

Check

Enable synchronization

Label your Secret with sync=true to enable synchronization to NAIS:

Google Secret Manager Sync label

Info

Synchronization only occurs when new secret versions are created.

If the secret already existed without this label, you must create a new secret version to effectuate the sync.

The latest secret version in Google Secret Manager will be copied into your Kubernetes namespace as a Kubernetes Secret.

Secret Naming

The name of the secret in Kubernetes will match the name of the secret in Google Secret Manager.

Naming collisions

If a secret with the same name already exists in Kubernetes, the secret will not be imported.

Step 2a: Secrets formatted as environment variables

Check

If your secret contains a list of environment variables:

Google Secret Manager environment variables example

Then additionally add the label env=true to your secret in Google Secret Manager:

Google Secret Manager environment variables label

This tells the synchronization mechanism to parse the secret as environment variables.

Step 3: Using the Kubernetes Secret in your applications

Check

Now that the Secret exists in your Kubernetes namespace, your application may refer to and use it.

There are two ways of mounting/exposing a Kubernetes Secret to your application:

Files

spec:
  # secret will be available in the file named "secret"
  # in the directory /var/run/secrets/my-secret/
  filesFrom:
    - secret: my-google-secret # value is the secret name in Google Secret Manager
      mountPath: /var/run/secrets/my-secret

Environment variables

spec:
  # secret will be made available as environment variables
  envFrom:
    - secret: my-google-secret # value is the secret name in Google Secret Manager

Automatic Reload

The Kubernetes secret will automatically have the reloader.stakater.com/match: "true" annotation set.

If the value of the secret is changed or updated, any application that refers to this secret will be automatically restarted to load the new values.

Examples

Example secret with single value format

This method is generally used when you need a binary file as a secret mounted to the file system of your pod. If you need environment variables, see the other example.

Secret in Google Secret Manager (click to expand)

Google Secret Manager secret with single value

Imported Secret in Kubernetes (click to expand)
apiVersion: v1
data:
  secret: c29tZS1zZWNyZXQtdmFsdWU= 
  # key="secret"
  # value="some-secret-value", base64 encoded
kind: Secret
metadata:
  annotations:
    hunter2.nais.io/last-modified: "2021-03-25T08:04:19Z"
    hunter2.nais.io/last-modified-by: user@nav.no
    hunter2.nais.io/secret-version: "1"
    reloader.stakater.com/match: "true"
  creationTimestamp: "2021-03-25T08:04:25Z"
  labels:
    nais.io/created-by: hunter2
  name: my-google-secret
  namespace: my-team
type: Opaque
Secret values when mounted to application (click to expand)
spec:
  # secret will be available in the file named "secret" in the directory /var/run/secrets/my-google-secret/
  # e.g. /var/run/secrets/my-google-secret/secret
  # note that the name "secret" is hard-coded and not configurable; the key used in the example below _must_ be "secret".
  filesFrom:
    - secret: my-google-secret # value is the secret name in Google Secret Manager
      mountPath: /var/run/secrets/my-google-secret

Example with environment variable format

Secret in Google Secret Manager (click to expand)

Google Secret Manager secret with environment variables

Imported Secret in Kubernetes (click to expand)
apiVersion: v1
data:
  SOME_ENV: c29tZS1zZWNyZXQtdmFsdWU=
  # key="SOME_ENV"
  # value="some-secret-value", base64 encoded
  SOME_OTHER_ENV: c29tZS1vdGhlci1zZWNyZXQ=
  # key="SOME_OTHER_ENV"
  # value="some-other-secret", base64 encoded
kind: Secret
metadata:
  annotations:
    hunter2.nais.io/last-modified: "2021-03-25T08:24:58Z"
    hunter2.nais.io/last-modified-by: user@nav.no
    hunter2.nais.io/secret-version: "2"
    reloader.stakater.com/match: "true"
  creationTimestamp: "2021-03-25T08:04:25Z"
  labels:
    nais.io/created-by: hunter2
  name: my-google-secret
  namespace: my-team
type: Opaque
Secret values when mounted to application (click to expand)
spec:
  # secret will be available as files in the directory /var/run/secrets/my-google-secret/
  # e.g. /var/run/secrets/my-google-secret/SOME_ENV and /var/run/secrets/my-google-secret/SOME_OTHER_ENV
  filesFrom:
    - secret: my-google-secret # value is the secret name in Google Secret Manager
      mountPath: /var/run/secrets/my-google-secret

  # secret will be made available as environment variables
  # SOME_ENV=some-secret-value
  # SOME_OTHER_ENV=some-other-secret
  envFrom:
    - secret: my-google-secret # value is the secret name in Google Secret Manager