Podman is an awesome tool to build, manage and share container workloads. Sometimes you also need to store a password for your container or manage secret tokens. With Podman 3.1.0 a feature was released that helps to manage container secrets with Podman.
Let's see how you can manage your container secrets. If you are completely new to Podman, I recommend having a look at the "Getting Started" article first.
If you are running a couple of containers, you will face situations, where you provide passwords. You may want to set a database password for your MariaDB container or inject the root password to your GitLab instance.
Storing this kind of credentials as plain text in your code or even in the container as a file can lead to security issues. In a world, where everything should be stored in a repository and manual interaction should be avoided as much as possible, we need a way to store secrets, but actually ignore them for container exports or git commits.
Podman 3.1.0 provides a way to do this with a new set of commands, that will allow creating, using and managing secrets for containers.
In the below example, I will show how you can use Podman secrets to store sensitive information and ignore them from being pushed to your repository.
podman secret command is pretty easy. I will demonstrate the usage with a simple example container project, which presents the secret data on the command line.
First, we will need a new project directory, which can be used to store our code. At this point, we will use Git for source code management. If you don't know anything about Git, please have a look here. For an introduction of building container images or Podman in general, you can find some articles in the blog, too.
# Create project directory
$ mkdir podman-secret
$ cd podman-secret
# Create files
$ touch Containerfile
$ touch .gitignore
$ touch .secretfile
$ touch .secretfile.sample
$ touch README.md
# Initialize the git repository
$ git init
In the next sessions, we will fill the files with content and I will explain what's happening.
The first thing we should do is adding our ".secretfile" to ".gitignore". This ensures it is not pushed to a remote repository. Providing an example file is also a good idea.
# Add .secretfile to .gitignore
echo ".secretfile" >> .gitignore
Now you can add, commit and push your code without pushing the content of the ".secretfile". Another option may be to locate it somewhere else, but I prefer this way.
# Add files and commit to Git
$ git add .
$ git commit -m "Initial commit"
You can list all files of your commits with the below command.
# Show files of commit
$ git show --name-only
commit 7b9350c376b8c5eb24039d63f1d54b7831323c22 (HEAD -> main)
Author: dschier <firstname.lastname@example.org>
Date: Fri Jun 18 08:15:14 2021 +0200
As you can see, the ".secretfile" is ignored, and you can store whatever you want in it. To learn more about gitignore, please have a look here.
Now let's add some secrets to our secretfiles. We will use them later on.
# Add some secrets to the secretfile
echo "password = SuperSecretPassword" >> .secretfile
# Also provide some example code for users
echo "password = PleaseProvidePassword" >> .secretfile.sample
Managing these secrets in Podman is easy. You can create a secret from this file.
# Create secret from file
$ podman secret create SecureData .secretfile
# List secrets
$ podman secret ls
ID NAME DRIVER CREATED UPDATED
8d0b3ba1a7718c2bfb9a2480d SecureData file 53 seconds ago 53 seconds ago
As you can see, a new secret was created with the name "SecureData". Let's inspect this secret.
# Inspect secrets
$ podman secret inspect SecureData
No secret information is visible here. You can also remove a secret again, if you want.
# Remove a secret
$ podman secret rm SecureData
In the next steps, we will use of the new secret.
The last thing, we will need is a container image, that makes use of the secret and output the data. Let's prepare a small image first.
You need to know if you start a container and provide a secretfile, this file will be available in the started container at the location "/run/secrets/NAMEOFSECRET". Before building an image, lets check with just a container.
# Run container and output the secret
$ podman run --rm --secret SecureData docker.io/library/fedora cat /run/secrets/SecureData
password = SuperSecretPassword
Most likely, you don't want to give your users something like this and also you want to have a prepared image, that is aware of the proper location for secrets. We can create a simple image for the same.
You need to edit the Containerfile like described below.
Building this image is easy, too.
# Build the image
$ podman build -t localhost/secretreader .
# List images
$ podman image ls
[dschier@nb01 podman-secret]$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/secretreader latest 51870b3ece0e 19 seconds ago 184 MB
Now, a user can simply start the container with the below commands.
# Start the container
$ podman run --rm --secret SecureData localhost/secretreader
Not providing the secret will lead to an error.
# Run without secret
$ podman run --rm localhost/secretreader
cat: /run/secrets/SecureData: No such file or directory
This also means, that you can securely push your code and the built image, without exposing your secret data. These secretfiles can be used for all kinds of data. You can also write complete configuration files in a secretfile and use it in your prepared image. With just a bit of BASH, you can also parametrize the SECRETNAME.
Be aware, that this feature is brand new and is quite limited. Future improvements will allow using different secret sources and maybe allow encrypted secret files.
Secret environment variables is also on the "nice-to-have" agenda.
Docs & Links
The documentation and the initial issue for this feature provide some additional help. You can also find some blog articles on the web.
With Podman secrets, you are now able to publish code and images without exposing your secrets. I am looking forward to future improvements and updates.