×

Understanding secrets

The Secret object type provides a mechanism to hold sensitive information such as passwords, OpenShift Container Platform client configuration files, private source repository credentials, and so on. Secrets decouple sensitive content from the pods. You can mount secrets into containers using a volume plug-in or the system can use secrets to perform actions on behalf of a pod.

Key properties include:

  • Secret data can be referenced independently from its definition.

  • Secret data volumes are backed by temporary file-storage facilities (tmpfs) and never come to rest on a node.

  • Secret data can be shared within a namespace.

YAML Secret object definition
apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: my-namespace
type: Opaque (1)
data: (2)
  username: dmFsdWUtMQ0K (3)
  password: dmFsdWUtMg0KDQo=
stringData: (4)
  hostname: myapp.mydomain.com (5)
1 Indicates the structure of the secret’s key names and values.
2 The allowable format for the keys in the data field must meet the guidelines in the DNS_SUBDOMAIN value in the Kubernetes identifiers glossary.
3 The value associated with keys in the data map must be base64 encoded.
4 Entries in the stringData map are converted to base64 and the entry will then be moved to the data map automatically. This field is write-only; the value will only be returned via the data field.
5 The value associated with keys in the stringData map is made up of plain text strings.

You must create a secret before creating the pods that depend on that secret.

When creating secrets:

  • Create a secret object with secret data.

  • Update the pod’s service account to allow the reference to the secret.

  • Create a pod, which consumes the secret as an environment variable or as a file (using a secret volume).

Types of secrets

The value in the type field indicates the structure of the secret’s key names and values. The type can be used to enforce the presence of user names and keys in the secret object. If you do not want validation, use the opaque type, which is the default.

Specify one of the following types to trigger minimal server-side validation to ensure the presence of specific key names in the secret data:

  • kubernetes.io/service-account-token. Uses a service account token.

  • kubernetes.io/basic-auth. Use with Basic Authentication.

  • kubernetes.io/ssh-auth. Use with SSH Key Authentication.

  • kubernetes.io/tls. Use with TLS certificate authorities.

Specify type: Opaque if you do not want validation, which means the secret does not claim to conform to any convention for key names or values. An opaque secret, allows for unstructured key:value pairs that can contain arbitrary values.

You can specify other arbitrary types, such as example.com/my-secret-type. These types are not enforced server-side, but indicate that the creator of the secret intended to conform to the key/value requirements of that type.

For examples of different secret types, see the code samples in Using Secrets.

Secret data keys

Secret keys must be in a DNS subdomain.

About automatically-generated service account token secrets

In 4.11, OpenShift Container Platform is adopting an enhancement from upstream Kubernetes, which enables the LegacyServiceAccountTokenNoAutoGeneration feature by default. As a result, when creating new service accounts (SA), a service account token secret is no longer automatically generated. Previously, OpenShift Container Platform automatically added a service account token to a secret for each new SA.

However, some features and workloads need service account token secrets to communicate with the Kubernetes API server, for example, the OpenShift Controller Manager. While this requirement will be changed in a future release, it remains in OpenShift Container Platform 4.11. As a result, if you need a service account token secret, you must manually use the TokenRequest API to request bound service account tokens or create a service account token secret.

After upgrading to 4.11, existing service account token secrets are not deleted and continue to function as expected.

In 4.11, service account token secrets still appear to have been automatically generated. Although, instead creating two secrets per service account, OpenShift Container Platform now creates one token, which does not work. In a future release, the number will be further reduced to zero. Note that dockercfg secrets are still generated and no secrets are deleted during upgrades.

Additional resources

Understanding how to create secrets

As an administrator you must create a secret before developers can create the pods that depend on that secret.

When creating secrets:

  1. Create a secret object that contains the data you want to keep secret. The specific data required for each secret type is descibed in the following sections.

    Example YAML object that creates an opaque secret
    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    type: Opaque (1)
    data: (2)
      username: dmFsdWUtMQ0K
      password: dmFsdWUtMQ0KDQo=
    stringData: (3)
      hostname: myapp.mydomain.com
      secret.properties: |
        property1=valueA
        property2=valueB
    1 Specifies the type of secret.
    2 Specifies encoded string and data.
    3 Specifies decoded string and data.

    Use either the data or stringdata fields, not both.

  2. Update the pod’s service account to reference the secret:

    YAML of a service account that uses a secret
    apiVersion: v1
    kind: ServiceAccount
     ...
    secrets:
    - name: test-secret
  3. Create a pod, which consumes the secret as an environment variable or as a file (using a secret volume):

    YAML of a pod populating files in a volume with secret data
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ]
          volumeMounts: (1)
              - name: secret-volume
                mountPath: /etc/secret-volume (2)
                readOnly: true (3)
      volumes:
        - name: secret-volume
          secret:
            secretName: test-secret (4)
      restartPolicy: Never
    1 Add a volumeMounts field to each container that needs the secret.
    2 Specifies an unused directory name where you would like the secret to appear. Each key in the secret data map becomes the filename under mountPath.
    3 Set to true. If true, this instructs the driver to provide a read-only volume.
    4 Specifies the name of the secret.
    YAML of a pod populating environment variables with secret data
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "export" ]
          env:
            - name: TEST_SECRET_USERNAME_ENV_VAR
              valueFrom:
                secretKeyRef: (1)
                  name: test-secret
                  key: username
      restartPolicy: Never
    1 Specifies the environment variable that consumes the secret key.
    YAML of a build config populating environment variables with secret data
    apiVersion: build.openshift.io/v1
    kind: BuildConfig
    metadata:
      name: secret-example-bc
    spec:
      strategy:
        sourceStrategy:
          env:
          - name: TEST_SECRET_USERNAME_ENV_VAR
            valueFrom:
              secretKeyRef: (1)
                name: test-secret
                key: username
    1 Specifies the environment variable that consumes the secret key.

Secret creation restrictions

To use a secret, a pod needs to reference the secret. A secret can be used with a pod in three ways:

  • To populate environment variables for containers.

  • As files in a volume mounted on one or more of its containers.

  • By kubelet when pulling images for the pod.

Volume type secrets write data into the container as a file using the volume mechanism. Image pull secrets use service accounts for the automatic injection of the secret into all pods in a namespace.

When a template contains a secret definition, the only way for the template to use the provided secret is to ensure that the secret volume sources are validated and that the specified object reference actually points to a Secret object. Therefore, a secret needs to be created before any pods that depend on it. The most effective way to ensure this is to have it get injected automatically through the use of a service account.

Secret API objects reside in a namespace. They can only be referenced by pods in that same namespace.

Individual secrets are limited to 1MB in size. This is to discourage the creation of large secrets that could exhaust apiserver and kubelet memory. However, creation of a number of smaller secrets could also exhaust memory.

Creating an opaque secret

As an administrator, you can create an opaque secret, which allows you to store unstructured key:value pairs that can contain arbitrary values.

Procedure
  1. Create a Secret object in a YAML file on a control plane node.

    For example:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque (1)
    data:
      username: dXNlci1uYW1l
      password: cGFzc3dvcmQ=
    1 Specifies an opaque secret.
  2. Use the following command to create a Secret object:

    $ oc create -f <filename>.yaml
  3. To use the secret in a pod:

    1. Update the pod’s service account to reference the secret, as shown in the "Understanding how to create secrets" section.

    2. Create the pod, which consumes the secret as an environment variable or as a file (using a secret volume), as shown in the "Understanding how to create secrets" section.

Additional resources

Creating a service account token secret

As an administrator, you can create a service account token secret, which allows you to distribute a service account token to applications that must authenticate to the API.

It is recommended to obtain bound service account tokens using the TokenRequest API instead of using service account token secrets. The tokens obtained from the TokenRequest API are more secure than the tokens stored in secrets, because they have a bounded lifetime and are not readable by other API clients.

You should create a service account token secret only if you cannot use the TokenRequest API and if the security exposure of a non-expiring token in a readable API object is acceptable to you.

See the Additional resources section that follows for information on creating bound service account tokens.

Procedure
  1. Create a Secret object in a YAML file on a control plane node:

    Example secret object:
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-sa-sample
      annotations:
        kubernetes.io/service-account.name: "sa-name" (1)
    type: kubernetes.io/service-account-token (2)
    1 Specifies an existing service account name. If you are creating both the ServiceAccount and the Secret objects, create the ServiceAccount object first.
    2 Specifies a service account token secret.
  2. Use the following command to create the Secret object:

    $ oc create -f <filename>.yaml
  3. To use the secret in a pod:

    1. Update the pod’s service account to reference the secret, as shown in the "Understanding how to create secrets" section.

    2. Create the pod, which consumes the secret as an environment variable or as a file (using a secret volume), as shown in the "Understanding how to create secrets" section.

Additional resources

Creating a basic authentication secret

As an administrator, you can create a basic authentication secret, which allows you to store the credentials needed for basic authentication. When using this secret type, the data parameter of the Secret object must contain the following keys encoded in the base64 format:

  • username: the user name for authentication

  • password: the password or token for authentication

You can use the stringData parameter to use clear text content.

Procedure
  1. Create a Secret object in a YAML file on a control plane node:

    Example secret object
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-basic-auth
    type: kubernetes.io/basic-auth (1)
    data:
    stringData: (2)
      username: admin
      password: t0p-Secret
    1 Specifies a basic authentication secret.
    2 Specifies the basic authentication values to use.
  2. Use the following command to create the Secret object:

    $ oc create -f <filename>.yaml
  3. To use the secret in a pod:

    1. Update the pod’s service account to reference the secret, as shown in the "Understanding how to create secrets" section.

    2. Create the pod, which consumes the secret as an environment variable or as a file (using a secret volume), as shown in the "Understanding how to create secrets" section.

Additional resources

Creating an SSH authentication secret

As an administrator, you can create an SSH authentication secret, which allows you to store data used for SSH authentication. When using this secret type, the data parameter of the Secret object must contain the SSH credential to use.

Procedure
  1. Create a Secret object in a YAML file on a control plane node:

    Example secret object:
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-ssh-auth
    type: kubernetes.io/ssh-auth (1)
    data:
      ssh-privatekey: | (2)
              MIIEpQIBAAKCAQEAulqb/Y ...
    1 Specifies an SSH authentication secret.
    2 Specifies the SSH key/value pair as the SSH credentials to use.
  2. Use the following command to create the Secret object:

    $ oc create -f <filename>.yaml
  3. To use the secret in a pod:

    1. Update the pod’s service account to reference the secret, as shown in the "Understanding how to create secrets" section.

    2. Create the pod, which consumes the secret as an environment variable or as a file (using a secret volume), as shown in the "Understanding how to create secrets" section.

Additional resources

Creating a Docker configuration secret

As an administrator, you can create a Docker configuration secret, which allows you to store the credentials for accessing a container image registry.

  • kubernetes.io/dockercfg. Use this secret type to store your local Docker configuration file. The data parameter of the secret object must contain the contents of a .dockercfg file encoded in the base64 format.

  • kubernetes.io/dockerconfigjson. Use this secret type to store your local Docker configuration JSON file. The data parameter of the secret object must contain the contents of a .docker/config.json file encoded in the base64 format.

Procedure
  1. Create a Secret object in a YAML file on a control plane node.

    Example Docker configuration secret object
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-cfg
      namespace: my-project
    type: kubernetes.io/dockerconfig (1)
    data:
      .dockerconfig:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 Specifies that the secret is using a Docker configuration file.
    2 The output of a base64-encoded Docker configuration file
    Example Docker configuration JSON secret object
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-json
      namespace: my-project
    type: kubernetes.io/dockerconfig (1)
    data:
      .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 Specifies that the secret is using a Docker configuration JSONfile.
    2 The output of a base64-encoded Docker configuration JSON file
  2. Use the following command to create the Secret object

    $ oc create -f <filename>.