What Are the Different Kubernetes Secret Types?
Kubernetes defines several built-in Secret types: Opaque (generic key-value), kubernetes.io/tls (TLS certificates), kubernetes.io/dockerconfigjson (container registry credentials), kubernetes.io/basic-auth, kubernetes.io/ssh-auth, kubernetes.io/service-account-token, and bootstrap.kubernetes.io/token. Each type enforces specific data fields.
Detailed Answer
Kubernetes Secrets have a type field that categorizes their purpose and enforces required data fields. Using the correct type improves validation, tooling integration, and documentation.
Built-In Secret Types
| Type | Purpose | Required Keys | |---|---|---| | Opaque | Generic key-value data | None (any keys) | | kubernetes.io/tls | TLS certificates | tls.crt, tls.key | | kubernetes.io/dockerconfigjson | Container registry auth | .dockerconfigjson | | kubernetes.io/basic-auth | Basic authentication | username, password | | kubernetes.io/ssh-auth | SSH authentication | ssh-privatekey | | kubernetes.io/service-account-token | Service account token | token, ca.crt, namespace | | bootstrap.kubernetes.io/token | Bootstrap token | token-id, token-secret |
Opaque Secrets
The default type for generic sensitive data:
apiVersion: v1
kind: Secret
metadata:
name: app-credentials
type: Opaque
stringData:
DATABASE_PASSWORD: "super-secret-pass"
API_KEY: "sk-abc123def456"
ENCRYPTION_KEY: "32-byte-encryption-key-here-!!"
Use Opaque when no other type fits. There are no required fields or validation rules.
TLS Secrets
Stores a TLS certificate and private key, used by Ingress controllers:
# Create from certificate files
kubectl create secret tls app-tls \
--cert=fullchain.pem \
--key=privkey.pem
apiVersion: v1
kind: Secret
metadata:
name: app-tls
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-certificate-chain>
tls.key: <base64-encoded-private-key>
The API server validates that both tls.crt and tls.key are present. Ingress resources reference TLS Secrets by name:
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
Docker Registry Secrets
Stores credentials for pulling images from private registries:
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=pass \
--docker-email=user@example.com
apiVersion: v1
kind: Secret
metadata:
name: regcred
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-docker-config>
Reference in a Pod or ServiceAccount:
# In a Pod spec
spec:
imagePullSecrets:
- name: regcred
containers:
- name: app
image: registry.example.com/myapp:v1
# Or attach to a ServiceAccount for automatic use
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
imagePullSecrets:
- name: regcred
Basic Auth Secrets
Stores username and password pairs:
apiVersion: v1
kind: Secret
metadata:
name: basic-auth
type: kubernetes.io/basic-auth
stringData:
username: admin
password: "secure-password-here"
SSH Auth Secrets
Stores SSH private keys:
apiVersion: v1
kind: Secret
metadata:
name: ssh-key
type: kubernetes.io/ssh-auth
data:
ssh-privatekey: <base64-encoded-private-key>
Service Account Token Secrets (Legacy)
Before Kubernetes 1.24, service account tokens were automatically created as Secrets:
apiVersion: v1
kind: Secret
metadata:
name: my-sa-token
annotations:
kubernetes.io/service-account.name: my-sa
type: kubernetes.io/service-account-token
Since 1.24, tokens are projected into Pods as bound tokens with automatic expiration. Long-lived token Secrets are still supported but discouraged for security reasons.
Choosing the Right Type
Need to store database credentials? → Opaque
Need to store a TLS certificate? → kubernetes.io/tls
Need to pull from a private registry? → kubernetes.io/dockerconfigjson
Need HTTP basic auth for Ingress? → kubernetes.io/basic-auth
Need SSH access from a Pod? → kubernetes.io/ssh-auth
Custom Types
You can define your own types for organizational purposes:
apiVersion: v1
kind: Secret
metadata:
name: stripe-key
type: mycompany.com/payment-credentials
stringData:
stripe-secret-key: "sk_live_..."
stripe-webhook-secret: "whsec_..."
Custom types have no built-in validation but help with RBAC policies and auditing by making the Secret's purpose explicit.
Why Interviewers Ask This
Interviewers ask this to test whether you know the purpose-specific Secret types and can use the correct one for each scenario instead of always defaulting to Opaque.
Common Follow-Up Questions
Key Takeaways
- Opaque is the default catch-all type for generic secrets.
- Use purpose-specific types (tls, dockerconfigjson) for built-in validation and tooling integration.
- Service account token Secrets are largely replaced by projected bound tokens since Kubernetes 1.24.