How To Secure Kubernetes Secrets
Kubernetes Secrets management is important for safeguarding sensitive information, such as passwords, OAuth tokens, and SSH keys. However, out-of-the-box Kubernetes Secrets are stored in base64
encoding, which is not encrypted; thus, it's imperative to add additional layers of security. This post explores various strategies to enhance the security of Kubernetes Secrets.
Creating a Kubernetes secret can be done in several ways, depending on the type of data you are handling. Below are the steps and configurations for creating a generic secret, a docker-registry secret, and a TLS secret:
Creating a Generic Secret:
- You can create a generic secret from a literal or from a file. Here's how you can do it from a literal:
kubectl create secret generic my-secret --from-literal=key1=value1 --from-literal=key2=value2
And from a file:
echo -n 'value1' > ./key1.txt
echo -n 'value2' > ./key2.txt
kubectl create secret generic my-secret --from-file=key1=./key1.txt --from-file=key2=./key2.txt
Creating a Docker-Registry Secret
- If you need to authenticate to a Docker registry, you can create a docker-registry secret:
kubectl create secret docker-registry my-reg-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
These commands will create secrets in the current namespace
. If you want to create a secret in a specific namespace
, you can add the --namespace
flag followed by the namespace
name.
In addition to the command line, you can also create secrets using a YAML configuration file. Here's an example of a generic secret configuration:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
key1: dmFsdWUx # base64 encoded value of 'value1'
key2: dmFsdWUy # base64 encoded value of 'value2'
You can then apply this configuration using kubectl apply -f ./secret.yaml
Encrypting Secrets at Rest
- Use EncryptionConfig: Create an EncryptionConfig file with the necessary encryption providers. Below is a sample configuration using the
aescbc
encryption provider:
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded AES key>
- identity: {}
- Configure the API server: Specify the
--encryption-provider-config
flag and the path to theEncryptionConfig
file when starting the Kubernetes API server:
kube-apiserver --encryption-provider-config=/path/to/encryption-config.yaml
Encrypting Secrets in Transit
- Enable TLS: Ensure that TLS is enabled for all communications between your Kubernetes components, etcd.
- Role-Based Access Control (RBAC): Define roles with the necessary permissions and bind them to users or groups. Below is an example of a Role and
RoleBinding
for managing Secrets:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: secret-manager
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: secret-manager-binding
namespace: default
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: secret-manager
apiGroup: rbac.authorization.k8s.io
Third-Party Secrets Management Solutions
Integrating third-party secret management solutions like CTO.ai secret management store, you can enable a more robust secret protection and lifecycle management.
Storing Secrets Securely
Use CTOai secrets to store and manage your secrets securely. Secrets allow you to share environment variables across multiple projects.
version: "1"
commands:
# setup aws ecs fargate infrastructure
- name: setup-aws-ecs-fargate:0.3.2
run: ./node_modules/.bin/ts-node /ops/src/setup.ts
description: "setup an environment"
# environment variables
env:
# add static env vars
static:
- STACK_TYPE=aws-ecs-fargate
- AWS_REGION=us-west-1
- JSII_DEPRECATED=quiet
# add and store aws secrets
secrets:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_ACCOUNT_NUMBER
Environment Variables
Store Kubernetes secrets as environment variables within CTO.ai. This way, they can be accessed securely within your pipeline.
version: "1"
commands:
# setup your digitalocean infrastructure and specify your configs
- name: setup-do-k8s-cdktf:0.1.2
run: ./node_modules/.bin/ts-node /ops/src/setup.ts
description: "Setup Kubernetes infrastructure on DigitalOcean"
env:
static:
- STACK_TYPE=do-k8s-cdktf
- STACK_ENTROPY=20220921
- TFC_ORG=cto-ai
- REGION=nyc3
secrets:
- DO_TOKEN
- DO_SPACES_ACCESS_KEY_ID
- DO_SPACES_SECRET_ACCESS_KEY
- TFC_TOKEN
configs:
- DEV_DO_K8S_CDKTF_STATE
- STG_DO_K8S_CDKTF_STATE
- PRD_DO_K8S_CDKTF_STATE
- DO_DEV_K8S_CONFIG
- DO_STG_K8S_CONFIG
- DO_PRD_K8S_CONFIG
- DO_DEV_REDIS_CONFIG
- DO_DEV_POSTGRES_CONFIG
- DO_DEV_MYSQL_CONFIG
Conclusion
Securing Kubernetes Secrets requires a multi-faceted approach. By encrypting secrets, enforcing strict access controls, and using CTO.ai secrets management solutions, you can significantly enhance the security posture of your Kubernetes environment.