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.

Remember not to:

  • 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" }

Note

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 .

Note

You need a relatively recent version of docker.

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:

  1. Get access to your apps namespace through (https://ops.iter.at/iterapp/kubectl-access.html)

  2. 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
  1. 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::

  1. 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
  1. Add the following to iterapp.toml:
[[files.common]]
mount_path = "/app/secrets/"
secret = "my-secret"

Warning

Everything under mount_path will be changed to whatever the content of the secret will be. Therefore, use an empty folder.