Skip to main content
RunBook Academy

KubernetesLXV · Secrets SecuritySecrets security

Secret types — the Kubernetes Secret primitives

Advanced⏱ ~13 minkubectl

What you'll learn

  • Identify the built-in Secret types and their use cases
  • Choose the right type for each workload (image pull, TLS, basic auth, etc.)
  • Understand the encoding (base64) is not encryption
  • Recognise the production failure modes (plaintext Secrets, unencrypted etcd)

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

A Kubernetes Secret is a small object that holds sensitive data: passwords, tokens, certificates. The Secret API has multiple types for different use cases; each type enforces a different shape and enables specific validation. This lesson covers the built-in types, their use cases, and the security implications.

The built-in Secret types

TypeUse case
OpaqueGeneric key-value pairs (default)
kubernetes.io/service-account-tokenLegacy SA tokens (deprecated in 1.24+)
kubernetes.io/dockercfgDocker registry credentials (legacy)
kubernetes.io/dockerconfigjsonDocker/OCI registry credentials
kubernetes.io/tlsTLS cert and private key
kubernetes.io/basic-authUsername and password
kubernetes.io/ssh-authSSH private key
flowchart LR
    A[Secret] --> B[Opaque]
    A --> C[dockerconfigjson]
    A --> D[tls]
    A --> E[basic-auth]
    A --> F[ssh-auth]

The Opaque type is the default; it accepts arbitrary key-value pairs. The other types enforce a schema.

An Opaque Secret

The generic type for arbitrary data:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: prod
type: Opaque
stringData:
  username: app
  password: supersecret
# Or, with data (base64-encoded):
# data:
#   username: YXBw
#   password: c3VwZXJzZWNyZXQ=

The stringData field accepts plain text; the API server encodes it to base64. The data field requires pre-encoded base64. Both forms are stored as base64.

A dockerconfigjson Secret

For pulling images from a private registry:

apiVersion: v1
kind: Secret
metadata:
  name: regcred
  namespace: prod
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <base64-encoded JSON>

The .dockerconfigjson field is a JSON document with the registry URL, username, and password:

{
  "auths": {
    "registry.example.com": {
      "username": "service-account",
      "password": "supersecret",
      "auth": "<base64(username:password)>"
    }
  }
}

The Secret is referenced by Pods or ServiceAccounts via imagePullSecrets.

# Create a dockerconfigjson Secret from kubectl
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=service-account \
  --docker-password=supersecret \
  -n prod

A TLS Secret

For storing a TLS certificate and private key:

apiVersion: v1
kind: Secret
metadata:
  name: tls-cert
  namespace: prod
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded cert>
  tls.key: <base64-encoded private key>

The tls.crt is the certificate; tls.key is the private key. The Secret is consumed by an ingress controller or a workload that terminates TLS.

A basic-auth Secret

For HTTP basic authentication:

apiVersion: v1
kind: Secret
metadata:
  name: basic-auth
  namespace: prod
type: kubernetes.io/basic-auth
stringData:
  username: admin
  password: supersecret

The Secret has username and password keys. Used by ingress controllers (e.g., NGINX auth-basic) for basic-auth-protected endpoints.

A ssh-auth Secret

For SSH private keys:

apiVersion: v1
kind: Secret
metadata:
  name: ssh-key
  namespace: ci
type: kubernetes.io/ssh-auth
data:
  ssh-privatekey: <base64-encoded private key>

Used by CI runners to clone private repositories.

Production patterns

  1. Right type for the use case. tls for certificates, dockerconfigjson for registry creds, Opaque for everything else.
  2. RBAC for Secret read. A workload that needs the Secret has a RoleBinding to secrets: get for that specific Secret.
  3. External secret stores. For high-value credentials, use Vault or AWS Secrets Manager; the Kubernetes Secret is a reference, not the actual value.
  4. Etcd encryption. Enable EncryptionConfiguration to encrypt Secrets at rest in etcd.

Production failure modes

  1. Plaintext Secrets in Git. A Secret’s YAML is committed to a public repo. The fix is to use external secret stores and sealed-secrets.
  2. No etcd encryption. Secrets are stored in plaintext in etcd. The fix is EncryptionConfiguration with a KMS provider.
  3. Broad RBAC for secrets: get. Every workload in the namespace can read every Secret. The fix is per-Secret RBAC.
  4. Image pull secrets in plaintext. A dockerconfigjson Secret with registry creds is readable by anyone with secrets: get. The fix is to scope the RBAC and rotate the registry cred.

Cross-course references

  • The Linux course covers TLS and SSH key management.
  • The Observability course covers the audit log entries for Secret access.

Quiz

Knowledge check · 4 questions

  1. Q1. Is the base64 encoding of a Kubernetes Secret's data a security control?

  2. Q2. A `kubernetes.io/tls` Secret can be used for both client authentication (mTLS) and server-side TLS termination at an ingress controller.

  3. Q3. Your CI runner needs to pull images from `registry.example.com`. The registry requires a service account with username `ci-svc` and password. You create a `kubernetes.io/dockerconfigjson` Secret. Walk the configuration.

    The CI runner's SA is `ci:ci-runner`. The registry is `registry.example.com`. The username is `ci-svc`. The password is provided by an external secret store. The Secret is referenced by the SA via `imagePullSecrets`.

  4. Q4. Name three Kubernetes Secret types and the use case for each.

Passing score: 75%. Answers are checked in this browser.

Production discipline

The right Secret type for the use case is the foundation of Secret hygiene. A defensible Secret programme uses Opaque for generic data, dockerconfigjson for registry credentials, tls for certificates, and basic-auth / ssh-auth for the specific use cases. RBAC scopes which workloads can read which Secrets; etcd encryption protects Secrets at rest; external secret stores hold the high-value credentials. A cluster whose Secrets are typed correctly and whose RBAC is minimal has a Secret programme that is auditable.