As we close out 2023, we at Cloud Native Now wanted to highlight the most popular articles of the year. Following is the latest in our series of the Best of 2023.
Kubernetes secrets are objects in the Kubernetes ecosystem designed to store and manage sensitive information, such as passwords, API tokens, SSH keys or other credentials. They provide a secure and convenient way to handle sensitive data in a containerized environment, ensuring that this information is not exposed in plain text or hard-coded in application code or configuration files.
Secrets are different from ConfigMaps, which are used to store non-sensitive configuration data. While ConfigMaps are intended for general-purpose configuration settings, secrets are specifically designed to handle sensitive data with additional security measures.
Why Use a Kubernetes Secret?
Using Kubernetes secrets provides several advantages when managing sensitive information in a containerized environment. Some of the primary reasons to use Kubernetes secrets include:
Access Control
Kubernetes secrets allow you to define granular access permissions for sensitive data, ensuring that only authorized services, applications or users can access the information. This is done by associating secrets with specific namespaces and service accounts, helping to enforce the principle of least privilege.
Decoupling
Secrets enable you to separate sensitive data from application code and configuration, which makes it easier to manage and update your applications without modifying the code itself. This separation also simplifies the process of deploying applications across different environments (e.g., development, staging and production) by allowing you to use environment-specific secrets.
Centralized Management
Kubernetes secrets provide a central location for managing sensitive information, making it easier to update, revoke or rotate credentials without affecting the entire application or infrastructure.
Versioning and History
Secrets, like other Kubernetes objects, support versioning, allowing you to track and roll back changes to sensitive data. This can be useful for audit purposes or for reverting to a previous version in case of an error.
Temporal Access
By mounting secrets as volumes or exposing them as environment variables, you can ensure that sensitive data is only accessible to the containers that require it and only for the duration of the container’s life. This minimizes the risk of data exposure through misconfigurations or vulnerabilities in other parts of the system.
Why is Secrets Management Critical in a DevSecOps Environment?
In a DevSecOps environment, which integrates development, security, and operations practices, secret management is critical for several reasons:
- Protect sensitive data: Applications and infrastructure often require access to sensitive information to function properly. Securely managing secrets helps prevent unauthorized access, data breaches and other security incidents that could lead to financial, reputational or legal consequences.
- Minimize attack surface: In a DevSecOps environment, multiple teams and tools interact with sensitive data throughout the development, deployment and management processes. Proper secrets management reduces the attack surface by limiting access to secrets only to those entities that require it, minimizing the risk of accidental exposure or leakage.
- Ensure compliance: Many organizations must adhere to various regulatory and industry standards, such as GDPR, HIPAA or PCI-DSS, which mandate specific security measures for handling sensitive data. Effective secrets management helps organizations meet these requirements and demonstrate compliance during audits.
- Enable automation: DevSecOps environments often rely on automation to accelerate development and deployment processes. Securely managing secrets enables automation tools to access sensitive information without compromising security, allowing for more efficient and secure workflows.
Managing Secrets Using kubectl
A secret is an object that stores sensitive information, such as the credentials that pods use to access services. For instance, a secret might be necessary for storing the username and password used to access a database. To create a secret, you can pass the raw data in a kubectl command (see this kubectl cheat sheet) or store the credentials in a file that you pass in a command.
Using raw data
Here is an example of how to create a secret to store the username “user11” and the password “F!C\*g#xDrv”:
kubectl create secret generic db-user-pass1 \
–from-literal=username=user11 \
–from-literal=password=’F!C\*g#xDrv’
The single quotes are necessary for escaping special characters like #, *, \, and ! in the strings. Without the quotation marks, the shell will interpret the characters as part of the code.
Using source files
In this example, there are two source files storing the username and password:
echo -n ‘user1’ > ./username.txt
echo -n ‘F!C\*g#xDrv’ > ./password.txt
The -n flag will prevent the files that are generated from having an additional newline character in the text. Without it, kubectl would read the files and encode their content into base64, including the additional newline character. There is no need to escape the special characters included in a file’s string.
The next step is to pass the file paths using the following command:
kubectl create secret generic db-user-pass2 \
–from-file=./username.txt \
–from-file=./password.txt
Verifying the secret
You can check if the secret was successfully created by using the kubectl get secrets command. The output should like this:
Note: The 2> /dev/null command suppresses any warnings
You can then view the secret’s details using the kubectl describe secret db-user-pass command.
By default, the kubectl get and kubectl describe commands do not reveal the contents of secrets to prevent their accidental exposure.
Decoding the secret
Use the following command to view the contents of a secret:
kubectl get secret db-user-pass -o jsonpath='{.data}’
The output should look like this:
{“password”:”RiFDXCpnI3hEcnY=”,”username”:”dXNlcjE=”}
You can decode this data using the command:
echo ‘RiFDXCpnI3hEcnY=’ | base64 –decode
kubectl should return the following output:
Editing the secret
As long as your secret is not an immutable object, you can edit it using the kubectl edit secrets command (specifying the secret’s name). You should then be able to open the default editor to adjust the values of your base64-encoded secret. For example, you might enter the following in the data field:
# Edit the following object. Ignore lines beginning with ‘#’.
# In the event of an error while saving the file, it should be
# reopened with the necessary failures.
#
apiVersion: v1
data:
password: GyVCTCpqJRpEz2L8
username: ZCRvbW5=
kind: Secret
metadata:
creationTimestamp: “2023-03-28T18:43:12Z”
name: db-user-pass
namespace: default
resourceVersion: “13809502”
uid: 81cebd67-83fb-4×82-413l-6c14238262vc
type: Opaque
Deleting a secret
You can delete secrets using the kubectl delete secret db-user-pass command.
Conclusion
Creating and managing Kubernetes secrets is an essential part of securing containerized applications. With the help of the kubectl get secret command, developers can easily create, manage and retrieve secrets needed by their applications. Using secrets, developers can ensure that sensitive data such as passwords, access tokens and API keys are kept secure and are not easily accessible to unauthorized parties.
However, it is important to adopt best practices to ensure that sensitive data is protected throughout the software development life cycle. With the increasing adoption of containerization and microservices, it is imperative for organizations to prioritize secrets management in their DevSecOps approach to secure their applications and maintain compliance.