---
title: Secrets
---

Secrets are used to provide data that is considered sensitive like passwords, keys, and other sensitive information. Acorn provides multiple secret types, and makes it easy to create closed loop systems where information can be kept within the defined Acorn.

To learn how to use secrets while deploying an Acorn image see [Args and Secrets](50-running/01-args-and-secrets.md)

## Using secrets in an Acornfile

Secrets must be defined in the Acornfile. The values can be generated by Acorn or provided by an existing secret in the cluster. Secrets should not be assigned values from user arguments. Secrets can be consumed in containers by referencing them by the `secret://<secret_name>/<key>` URI syntax.

It is possible to define the behavior when the secret is updated to a new value. The default is to redeploy the containers one at a time. If that operation is unsafe, or requires more user intervention, you can add the `?onchange=no-action` to the end of the secret reference URI.

### Consume secret in an environment variable

Some containers use environment variables for secret bits of data. The MariaDB container for instance uses an environment variable to set the root password.

```acorn
containers: {
    db: {
        image: "mysql"
        // ...
        env: {
            "MYSQL_ROOT_PASSWORD": "secret://db-root-password/token"
        }
    }
}
// ...
secrets: {
    "db-root-password": {
        type: "token"
    }
}
```

The example shows the secret `db-root-password` being consumed as an environment variable in the db container. The secret is of type token and will automatically be generated at runtime by Acorn. The user can then use the Acorn CLI to get the credential if needed.

### Consuming secrets in templates

Secrets in templates are wrapped in `${}`. It is possible to pass secret configuration data to a container in a pre-rendered form. This next example shows how you can add a configuration file with sensitive data.

```acorn
containers: {
    web: {
        image: "nginx"
        // ...
        files: {
            "/etc/nginx/conf.d/website.conf": "secret://website-conf/template"
        }
    }
}
// ...
secrets: {
    "proxy-auth": {
        type: "opaque"
        data: {
            "basic-auth-string": "credentialsgohere"
        }
    }
    "website-conf": {
        type: "template"
        data: {
            template: """
            server {
                listen 80;
                // ...
                location / {
                    // ...
                    proxy_set_header Authorization "Basic ${secret://proxy-auth/basic-auth-string}"
                }
            }
            """
        }
    }
}
```

The above example has a container that will use the `website-conf` secret to create a config file. Before rendering the config file, Acorn will substitute the `basic-auth-string` into the template. This technique makes it possible for the user to pass in the sensitive `basic-auth-string` at runtime by [binding a pre-existing secret](50-running/01-args-and-secrets.md#binding-a-secret-at-runtime).

### Populating a directory with files

You can populate a directory with sensitive data using a secret. The example below shows populating the `~/.ssh` directory with private keys from a secret.

```acorn
containers: {
    git: {
        image: "my-git"
        dirs: {
            "/home/user/.ssh": "secret://user-provided-ssh-keys"
        }
    }
}
secrets: {
    "user-provided-ssh-keys": {
        type: "opaque"
        data: {
            //Example content from bound secret.
            //id_rsa: "-----BEGIN OPENSSH PRIVATE KEY-----...."
            //id_rsa_aws: "-----BEGIN OPENSSH PRIVATE KEY-----..."
            //Do not put private keys in Acornfile
        }
    }
}
```

The above will populate the `/home/user/.ssh` directory with the content of each item in files named after the key.

```shell
# inside the git container
ls /home/user/.ssh
id_rsa id_rsa_aws
```

## Types of secrets

Acorn makes multiple types of secrets available to the Acorn author.

 1. **Basic:** Used to generate and/or store usernames and passwords.
 1. **Template:** Used to store configuration files that contain sensitive information.
 1. **Token:** Used to generate and/or store long secret strings.
 1. **Generated:** Used to take the output of a `job` and pass along as a secret bit of info.
 1. **Opaque:** A generic secret that can store defaults in the Acorn, or is meant to be overridden by the user to pass unknown/unstructured sensitive data.

### Basic secrets

Basic secrets are defined in the secrets block with the type "basic".

```acorn
// ...
secrets: {
    "my-creds": {
        type: "basic" // required
        data: {  
            username: "" // optional
            password: "" // optional
        }
    }
}
```

The basic secret type is used for username / password pairs. The key names must be username and password. If one or both of the fields are defined with a non-empty string, those values will be used. If the empty string, the default value, is used Acorn will generate random values for one or both.

### Template secrets

The template secret can be used to render and store multiple secret values into a single output. It has the following format:

```acorn
// ...
secrets: {
    "password-file": {
        type: "template" // required
        data: {
            "password.txt": """
            password=${secret://token/token}
            """
        }
    }
    "token": {
        type: "token"
    }
}
```

In the above example the secret renders a template secret with one key call "password.txt" the token from the secret named "token." See [advanced topics](30-advanced.md) for other uses for the template secret type.

### Token secrets

Token secrets are useful for generating a password or secure string used for passwords when the user is already known or not required.

```acorn
secrets: {
    "my-token": {
        type: "token" // required
        params: {
            length: 32 // optional
            characters: "abcdedfhifj01234567890" // optional
        }
    }
    data: {
        token: "" // optional
    }
}
```

The token secret type must be defined. The params allow customization of the generated token. By default tokens are 54 characters in length. By defining the `length` param the token can be customized to be within 0-256 characters long. The `characters` param allows the user to define the allowed character values within the token.

The `token` field in the data object is optional and needs to be left the default empty string if Acorn should generate the token. If the `token` is defined that value will always be used.

### Generated secrets

Generated secrets allow storing sensitive data output from a [job](06-jobs.md).

```acorn
containers: {
    "frontend-proxy": {
        // ...
        files: {
            "/etc/htpasswd": "secret://htpasswd-file/content"
        }
        // ...
    }
}
jobs: {
    "htpasswd-create": {
        env: {
            "USER": "secret://user-creds/username"
            "PASS": "secret://user-creds/password"
        }
        entrypoint: "/bin/sh -c"
        image:      "httpd:2"
        // Output of a generated secret needs to be placed in the file /run/secrets/output.
        cmd: ["htpasswd -Bbc /run/secrets/output $USER $PASS"]
    }
}
secrets: {
    "user-creds": {
        type: "basic"
    }
    "htpasswd-file": {
        type: "generated" // required
        params: {
            job: "htpasswd-create" // required
            format: "text" // optional
        }
    }
}
```

In the above example, there is a basic secret that Acorn will generate a username and password for. The job will run with the basic secret data passed in as environment variables. When the job runs it will generate an htpasswd file and write the content out to the required `/run/secrets/output` target. The contents of the `/run/secrets/output` file will be placed into the secret `htpasswd-file` and consumed by the `frontend-proxy` container. The key `content` must be used when referencing the value.

The `job` parameter is always required, and is the name of the job that will generate the output. The `format` parameter is optional and defaults to text.

### Opaque secrets

Opaque secrets have no defined structure and can have arbitrary key value pairs. These types of secrets are best used for allowing a user to input sensitive data at runtime. In some cases an unstructured secret can be used if the user will be passing data that will be used in user defined templates. Expected keys should be predefined with reasonable defaults to provide the user some context.

```acorn
secrets: {
    "user-secret-data": {
        type: "opaque"
    }
}
```
