Navigation Menu

Skip to content

Commit

Permalink
docs: improve secrets documentation (#3565)
Browse files Browse the repository at this point in the history
Improve documentation around secrets.
  • Loading branch information
james-d-elliott committed Jun 21, 2022
1 parent 143c838 commit b102ebb
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 337 deletions.
10 changes: 8 additions & 2 deletions docs/content/en/configuration/first-factor/ldap.md
Expand Up @@ -209,8 +209,14 @@ The distinguished name of the user paired with the password to bind with for loo

{{< confkey type="string" required="yes" >}}

The password of the user paired with the user to bind with for lookup and password change operations.
Can also be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments.
*__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__
especially for containerized deployments.*

The password paired with the [user](#user) used to bind to the LDAP server for lookup and password change operations.

It's __strongly recommended__ this is a
[Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) with 64 or more
characters and the user password is changed to this value.

## Refresh Interval

Expand Down
Expand Up @@ -85,22 +85,27 @@ identity_providers:

{{< confkey type="string" required="yes" >}}

*__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__
especially for containerized deployments.*

The HMAC secret used to sign the [JWT]'s. The provided string is hashed to a SHA256 ([RFC6234]) byte string for the
purpose of meeting the required format. This secret must be generated by the administrator and can be done by following
the [Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) guide.
purpose of meeting the required format.

Should be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments.
It's __strongly recommended__ this is a
[Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) with 64 or more
characters.

### issuer_private_key

{{< confkey type="string" required="yes" >}}

*__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__
especially for containerized deployments.*

The private key in DER base64 ([RFC4648]) encoded PEM format used to encrypt the [OpenID Connect] [JWT]'s. The key must
be generated by the administrator and can be done by following the
[Generating an RSA Keypair](../miscellaneous/guides.md#generating-an-rsa-keypair) guide.

Should be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments.

### access_token_lifespan

{{< confkey type="duration" default="1h" required="no" >}}
Expand Down
325 changes: 33 additions & 292 deletions docs/content/en/configuration/methods/secrets.md
Expand Up @@ -52,21 +52,36 @@ Here is the list of the environment variables which are considered secrets and c
secrets can be loaded into the configuration if they end with one of the suffixes above, you can set the value of any
other configuration using the environment but instead of loading a file the value of the environment variable is used.

| Configuration Key | Environment Variable |
|:-------------------------------------------------:|:--------------------------------------------------------:|
| tls_key | AUTHELIA_TLS_KEY_FILE |
| jwt_secret | AUTHELIA_JWT_SECRET_FILE |
| duo_api.secret_key | AUTHELIA_DUO_API_SECRET_KEY_FILE |
| session.secret | AUTHELIA_SESSION_SECRET_FILE |
| session.redis.password | AUTHELIA_SESSION_REDIS_PASSWORD_FILE |
| session.redis.high_availability.sentinel_password | AUTHELIA_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE |
| storage.encryption_key | AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE |
| storage.mysql.password | AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE |
| storage.postgres.password | AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE |
| notifier.smtp.password | AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE |
| authentication_backend.ldap.password | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE |
| identity_providers.oidc.issuer_private_key | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE |
| identity_providers.oidc.hmac_secret | AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE |
| Configuration Key | Environment Variable |
|:---------------------------------------------------:|:--------------------------------------------------------:|
| [server.tls.key] | AUTHELIA_SERVER_TLS_KEY_FILE |
| [jwt_secret] | AUTHELIA_JWT_SECRET_FILE |
| [duo_api.secret_key] | AUTHELIA_DUO_API_SECRET_KEY_FILE |
| [session.secret] | AUTHELIA_SESSION_SECRET_FILE |
| [session.redis.password] | AUTHELIA_SESSION_REDIS_PASSWORD_FILE |
| [session.redis.high_availability.sentinel_password] | AUTHELIA_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE |
| [storage.encryption_key] | AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE |
| [storage.mysql.password] | AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE |
| [storage.postgres.password] | AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE |
| [notifier.smtp.password] | AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE |
| [authentication_backend.ldap.password] | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE |
| [identity_providers.oidc.issuer_private_key] | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE |
| [identity_providers.oidc.hmac_secret] | AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE |

[server.tls.key]: ../miscellaneous/server.md#key
[jwt_secret]: ../miscellaneous/introduction.md#jwt_secret
[duo_api.secret_key]: ../second-factor/duo.md#secret_key
[session.secret]: ../session/introduction.md#secret
[session.redis.password]: ../session/redis.md#password
[session.redis.high_availability.sentinel_password]: ../session/redis.md#sentinel_password
[storage.encryption_key]: ../storage/introduction.md#encryption_key
[storage.mysql.password]: ../storage/mysql.md#password
[storage.postgres.password]: ../storage/postgres.md#password
[notifier.smtp.password]: ../notifications/smtp.md#password
[authentication_backend.ldap.password]: ../first-factor/ldap.md#password
[identity_providers.oidc.issuer_private_key]: ../identity-providers/open-id-connect.md#issuer_private_key
[identity_providers.oidc.hmac_secret]: ../identity-providers/open-id-connect.md#hmac_secret


## Secrets in configuration file

Expand All @@ -86,281 +101,7 @@ via environment variables in plain text.
See [this article](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/) for reasons
why setting them via the file counterparts is highly encouraged.

## Docker

Secrets can be provided in a `docker-compose.yml` either with Docker secrets or
bind mounted secret files, examples of these are provided below.

### Compose with Docker secrets

This example assumes secrets are stored in `/path/to/authelia/secrets/{secretname}`
on the host and are exposed with Docker secrets in a `docker-compose.yml` file:

```yaml
version: '3.8'

networks:
net:
driver: bridge

secrets:
jwt:
file: /path/to/authelia/secrets/jwt
duo:
file: /path/to/authelia/secrets/duo
session:
file: /path/to/authelia/secrets/session
redis:
file: /path/to/authelia/secrets/redis
mysql:
file: /path/to/authelia/secrets/mysql
smtp:
file: /path/to/authelia/secrets/smtp
ldap:
file: /path/to/authelia/secrets/ldap

services:
authelia:
image: authelia/authelia
container_name: authelia
secrets:
- jwt
- duo
- session
- redis
- mysql
- smtp
- ldap
volumes:
- /path/to/authelia:/config
networks:
- net
expose:
- 9091
restart: unless-stopped
environment:
- AUTHELIA_JWT_SECRET_FILE=/run/secrets/jwt
- AUTHELIA_DUO_API_SECRET_KEY_FILE=/run/secrets/duo
- AUTHELIA_SESSION_SECRET_FILE=/run/secrets/session
- AUTHELIA_SESSION_REDIS_PASSWORD_FILE=/run/secrets/redis
- AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE=/run/secrets/mysql
- AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/run/secrets/smtp
- AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE=/run/secrets/ldap
- TZ=Australia/Melbourne
```

### Compose with bind mounted secret files

This example assumes secrets are stored in `/path/to/authelia/secrets/{secretname}`
on the host and are exposed with bind mounted secret files in a `docker-compose.yml` file
at `/config/secrets/`:

```yaml
version: '3.8'

networks:
net:
driver: bridge

services:
authelia:
image: authelia/authelia
container_name: authelia
volumes:
- /path/to/authelia:/config
networks:
- net
expose:
- 9091
restart: unless-stopped
environment:
- AUTHELIA_JWT_SECRET_FILE=/config/secrets/jwt
- AUTHELIA_DUO_API_SECRET_KEY_FILE=/config/secrets/duo
- AUTHELIA_SESSION_SECRET_FILE=/config/secrets/session
- AUTHELIA_SESSION_REDIS_PASSWORD_FILE=/config/secrets/redis
- AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE=/config/secrets/mysql
- AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/config/secrets/smtp
- AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE=/config/secrets/ldap
- TZ=Australia/Melbourne
```

## Kubernetes

Secrets can be mounted as files using the following sample manifests.

To create a secret, the following manifest can be used

```yaml
---
kind: Secret
apiVersion: v1

metadata:
name: a-nice-name
namespace: your-authelia-namespace

data:
duo_key: >-
UXE1WmM4S0pldnl6eHRwQ3psTGpDbFplOXFueUVyWEZhYjE0Z01IRHN0RT0K
jwt_secret: >-
anotherBase64EncodedSecret
...
```

where `UXE1WmM4S0pldnl6eHRwQ3psTGpDbFplOXFueUVyWEZhYjE0Z01IRHN0RT0K` is Base64 encoded for
`Qq5Zc8KJevyzxtpCzlLjClZe9qnyErXFab14gMHDstE`, the actual content of the secret. You can generate these contents with

```console
LENGTH=64
tr -cd '[:alnum:]' < /dev/urandom \
| fold -w "${LENGTH}" \
| head -n 1 \
| tr -d '\n' \
| tee actualSecretContent.txt \
| base64 --wrap 0 \
; echo
```

which writes the secret's content to the `actualSecretContent.txt` file and print the Base64 encoded version on `stdout`. `${LENGTH}` is the length in characters of the secret content generated by this pipe. If you don't want the contents to be written to `actualSecretContent.txt`, just delete the line with the `tee` command.

### Kustomization

* __Filename:__ ./kustomization.yaml
* __Command:__ kubectl apply -k
* __Notes:__ this kustomization expects the Authelia configuration.yml in the same directory. You will need to edit the
kustomization.yaml with your desired secrets after the equal signs. If you change the value before the equal sign
you'll have to adjust the volumes section of the daemonset template (or deployment template if you're using it).

```yaml
#filename: ./kustomization.yaml
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
app: authelia
configMapGenerator:
- name: authelia
files:
- configuration.yml
secretGenerator:
- name: authelia
literals:
- jwt_secret=myverysecuresecret
- session_secret=mysessionsecret
- redis_password=myredispassword
- sql_password=mysqlpassword
- ldap_password=myldappassword
- duo_secret=myduosecretkey
- smtp_password=mysmtppassword
```

### DaemonSet

* __Filename:__ ./daemonset.yaml
* __Command:__ kubectl apply -f ./daemonset.yaml
* __Notes:__ assumes Kubernetes API 1.16 or greater
## Examples

```yaml
#filename: daemonset.yaml
#command: kubectl apply -f daemonset.yaml
#notes: assumes kubernetes api 1.16+
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: authelia
namespace: authelia
labels:
app: authelia
spec:
selector:
matchLabels:
app: authelia
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: authelia
spec:
containers:
- name: authelia
image: authelia/authelia:latest
imagePullPolicy: IfNotPresent
env:
- name: AUTHELIA_JWT_SECRET_FILE
value: /app/secrets/jwt
- name: AUTHELIA_DUO_API_SECRET_KEY_FILE
value: /app/secrets/duo
- name: AUTHELIA_SESSION_SECRET_FILE
value: /app/secrets/session
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
value: /app/secrets/ldap_password
- name: AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
value: /app/secrets/smtp_password
- name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE
value: /app/secrets/sql_password
- name: AUTHELIA_SESSION_REDIS_PASSWORD_FILE
value: /app/secrets/redis_password
- name: TZ
value: America/Toronto
ports:
- name: authelia-port
containerPort: 9091
startupProbe:
httpGet:
path: /api/state
port: authelia-port
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 5
failureThreshold: 4
livenessProbe:
httpGet:
path: /api/state
port: authelia-port
initialDelaySeconds: 60
timeoutSeconds: 5
periodSeconds: 30
failureThreshold: 2
readinessProbe:
httpGet:
path: /api/state
port: authelia-port
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 5
failureThreshold: 5
volumeMounts:
- mountPath: /config
name: config-volume
- mountPath: /app/secrets
name: secrets
readOnly: true
volumes:
- name: config-volume
configMap:
name: authelia
items:
- key: configuration.yml
path: configuration.yml
- name: secrets
secret:
secretName: authelia
items:
- key: jwt_secret
path: jwt
- key: duo_secret
path: duo
- key: session_secret
path: session
- key: redis_password
path: redis_password
- key: sql_password
path: sql_password
- key: ldap_password
path: ldap_password
- key: smtp_password
path: smtp_password
```
See the [Docker Integration](../../integration/deployment/docker.md) and
[Kubernetes Integration](../../integration/kubernetes/introduction/index.md) guides for examples of secrets.

0 comments on commit b102ebb

Please sign in to comment.