Secrets
Security
Please use [env.prod]
and [env.common]
sections in iterapp.toml
actively
when dealing with secrets. This adds an extra layer of security as the app will
have different secrets for production and other environments.
- Print the secret value, this will expose it in the logs.
- Move the secret file to another location. This will add the secret to the final docker-image.
Intro
This page goes through the different types of secrets supported by Iterapp.
Secrets should not be put directly into the repository, neither in
iterapp.toml
nor in any other files. Instead, we encrypt the secrets used in
iterapp, and include the encrypted secrets in iterapp.toml
. This ensures that
the secrets are not easily stolen, even if someone gains access to the repo or
containers of the application.
Encryption of secrets is done here: https://apps.iterapp.no/encrypt_secret.
- Runtime secrets are used when the app is running.
- Buildtime secrets are used when building the app in the Dockerfile.
- Direct secrets in kubernetes.
- Secret files secrets mounted in kubernetes.
Go down to the relevant chapter depending on your needs.
Runtime secrets
Runtime secrets are values your app needs when running. Such secrets can be API-keys to remote APIs (firebase, sanity ++).
How to use runtime secrets
Encrypt the runtime value and add it
to iterapp.toml
. You can either add it as an environment value which the app
can use, or as a file which will be available in the filesystem as the app.
Example: environment variable
[env.prod] ENV_VAR= { encrypted = "MBZ53sHc3dNOd9KhArzTy..." }
[env.common] ENV_VAR= { encrypted = "O1H6jkrLdPxrORgdnNa3e..." }
[env.prod]
overrides values in [env.common]
, read more on
how overrides work
Buildtime secrets
Before going into how to use your environment variables and secret files for Docker builds, you should know that using secrets with Docker can result in your image containing sensitive information. Although we store your images securely, Docker registries should be treated like code repositories: it’s best practice to not store secrets in them. You should avoid using secrets in your Docker builds to eliminate the chance of accidentally storing sensitive material.
The best way to use secrets in your Docker build is with secret files. Unlike build arguments, secret mounts aren’t persisted in your built image. Docker services can access environment variables and secret files like other kinds of services at run time. However, because of the way that Docker builds work, you won’t have access to environment variables and secret files as usual at build time.
Build secrets are used when you want to have access to a secret value in the build-process of the app. This can for instance be an access key to a repo to install extra packages, or a git token to fetch common components.
How to use build-secrets
Encrypt your secret (remember to select Build-secrets
and not
All environments
) and add it to your iterapp.toml
as shown below:
[build_secrets]
"your-build-secret-id" = { encrypted = "nb-DGpWdtc9-m0N8BMV7F-SX5Yksa53y7KRBjox1TFEPjHIV4w_Nb8KxVl4xhh3jdButhUiN7W681z5uNWngemIsibbya-8aLa8bNaf7xYppHpFDhBaVwpvPL5rufaLeddBrtt4OgDVLYUgPl6tU6IqgC3oPopIOYLDc9UERSA" }
The secret value is specific for building your app. It cannot be used for another app, or as a runtime-secret for your app.
your-build-secret-id
is an identifier to the secret that was built. You will
use this ID in the dockerfile.
You will have a command like this in your dockerfile:
RUN --mount=type=secret,id=$1,dst=/secret-file-rename \
$1=$(cat /secret-file-rename) \
&& export $1
&& $2
Replace $1
with the secret you want to be available (e.g.
your-build-secret-id
). Then replace $2
with the command you want to run with
the secret available to it (e.g. yarn build
).
So what does this command do? Good question!
The --mount flag will mount the secret-file into the docker container, so the file will be available in the Dockerfile when building the image.
id is the identifier to the secret file which we set in iterapp.toml. Docker does not use the filename of where the secret is kept outside of the Dockerfile, since this may be sensitive information.
dst specifies where to mounts the secret file. The Dockerfile RUN command will have the file available at that location.
For more information about the syntax, take a look at the buildkit docs
Making the build work locally
You still want your app to work locally when running docker build
. To make
this work, you need to
enable buildkit
and point to the secret value. If you have the secret in a file called
$HOME/.secrets/my_secret.txt
, you can build like this
DOCKER_BUILDKIT=1 docker build --secret id=your-build-secret-id,src=$HOME/.secrets/my_secret.txt .
Use kubernetes-secrets directly
There might be cases where you need to use secrets that already are in the kubernetes namespace of the app.
If so, this is how to do it:
-
Get access to your apps namespace through (https://ops.iter.at/iterapp/kubectl-access.html)
-
Make a secret in kubernetes
kubectl -n apps-myapp-test create secret generic db-keys --from-literal=password=asdf1234password
kubectl -n apps-myapp-prod create secret generic db-keys --from-literal=password=asdf1234password
- Update iterapp.toml file
[env.common]
DB_PASSWORD= { secret = "db-keys", key = "password" }
Use kubernetes-secrets as files
This is how you mount a secret file and make it available to your app in docker::
- Make a secret in kubernetes (notice how a secret can have several files!)
kubectl -n apps-myapp-test create secret generic my-secret --from-file=./my-file.json --from-file=./my-other-file.json
kubectl -n apps-myapp-prod create secret generic my-secret --from-file=./my-file.json --from-file=./my-other-file.json
- Add the following to iterapp.toml:
[[files.common]]
mount_path = "/app/secrets/"
secret = "my-secret"