From 8d17034545948731a14852a4521f6c55cd0f848e Mon Sep 17 00:00:00 2001 From: Jack Spiering <46534141+jackspiering@users.noreply.github.com> Date: Wed, 7 Oct 2026 20:50:44 +0200 Subject: [PATCH] Arcane, ConvertX, Formbricks, Hemmelig, Karakeep: require your own secrets These stacks shipped public sample values for their secrets, in compose.yaml or in .env. A stack started with them unless the user replaced each one by hand. Leave the secrets empty in .env and make Compose stop with an error when one is missing, as Homarr and Docmost already do. Document the values and the upgrade steps in each README. --- services/arcane/.env | 6 ++++++ services/arcane/README.md | 9 ++++++++- services/arcane/compose.yaml | 4 ++-- services/convertx/.env | 3 +++ services/convertx/README.md | 6 +++++- services/convertx/compose.yaml | 2 +- services/formbricks/.env | 12 ++++++------ services/formbricks/README.md | 9 ++++++++- services/formbricks/compose.yaml | 6 +++--- services/hemmelig/.env | 3 +++ services/hemmelig/README.md | 10 ++++++---- services/hemmelig/compose.yaml | 2 +- services/karakeep/.env | 5 +++-- services/karakeep/README.md | 6 +++++- services/karakeep/compose.yaml | 3 +++ 15 files changed, 63 insertions(+), 23 deletions(-) diff --git a/services/arcane/.env b/services/arcane/.env index 20cc1e4a..7149fa35 100644 --- a/services/arcane/.env +++ b/services/arcane/.env @@ -21,4 +21,10 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim # for example: tail-scale TAILNET_NAME= +# Required: a 32-byte key. Generate it with: openssl rand -base64 32 +ENCRYPTION_KEY= + +# Required: generate it with: openssl rand -base64 32 +JWT_SECRET= + #EXAMPLE_VAR="Environment variable" diff --git a/services/arcane/README.md b/services/arcane/README.md index 452beec9..91fad325 100644 --- a/services/arcane/README.md +++ b/services/arcane/README.md @@ -17,7 +17,7 @@ This stack runs Arcane with a Tailscale sidecar, as described in [the standard s ## Before you start - **Set your Tailnet name.** Set `TAILNET_NAME` in `.env` to your Tailnet name, without `.ts.net`. `compose.yaml` builds the address of the application, `APP_URL`, from it. -- **Replace the secrets.** `ENCRYPTION_KEY` and `JWT_SECRET` in `compose.yaml` have a public sample value. Replace both with your own random values. +- **Set the secrets.** Set `ENCRYPTION_KEY` and `JWT_SECRET` in `.env` to two different random values. Generate each with `openssl rand -base64 32`. Compose stops with an error if one of them is empty. ## Deviations from the standard setup @@ -28,6 +28,13 @@ This stack runs Arcane with a Tailscale sidecar, as described in [the standard s Open the web interface and log in with username `arcane` and password `arcane-admin`. Arcane creates this account at the first start and asks you to change the password at the first login. +## Upgrading + +Earlier versions of this stack had sample values for `ENCRYPTION_KEY` and `JWT_SECRET` in `compose.yaml`. Both are now empty in `.env`, and you must set them. + +- If you replaced the values in `compose.yaml` before, move your values to `.env`. +- If you still used the sample values, set new ones. With a new `JWT_SECRET`, everyone has to log in again. Arcane cannot decrypt what it encrypted with the previous `ENCRYPTION_KEY`, so keep the previous value if you need that data. + ## Links - [Arcane documentation](https://getarcane.app/docs) diff --git a/services/arcane/compose.yaml b/services/arcane/compose.yaml index 655f141d..af403dac 100644 --- a/services/arcane/compose.yaml +++ b/services/arcane/compose.yaml @@ -56,8 +56,8 @@ services: - APP_URL=https://arcane.${TAILNET_NAME}.ts.net - PUID=1000 - PGID=1000 - - ENCRYPTION_KEY=verysecretkeythatshouldbereplaced # ENCRYPTION_KEY must be 32 bytes (raw/base64/hex). Use 'openssl rand -base64 32' in your CLI to generate a secure random key. - - JWT_SECRET=verysecretkeythatshouldbereplaced # JWT_SECRET should be a secure random string. Use 'openssl rand -base64 32' in your CLI to generate another secure random key. + - ENCRYPTION_KEY=${ENCRYPTION_KEY:?Set ENCRYPTION_KEY in .env} + - JWT_SECRET=${JWT_SECRET:?Set JWT_SECRET in .env} - LOG_LEVEL=info # Optional - LOG_JSON=false # Optional - OIDC_ENABLED=false # Optional diff --git a/services/convertx/.env b/services/convertx/.env index ac8418ad..8944af20 100644 --- a/services/convertx/.env +++ b/services/convertx/.env @@ -19,4 +19,7 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim # Optional Service variables # PUID=1000 +# Required: signs the login tokens. Generate it with: openssl rand -hex 32 +JWT_SECRET= + #EXAMPLE_VAR="Environment variable" diff --git a/services/convertx/README.md b/services/convertx/README.md index 4a3b2b9e..d10162cb 100644 --- a/services/convertx/README.md +++ b/services/convertx/README.md @@ -15,7 +15,7 @@ This stack runs ConvertX with a Tailscale sidecar, as described in [the standard ## Before you start -Replace the value of `JWT_SECRET` in `compose.yaml` with your own long random string. The sample value is public, and ConvertX uses it to sign the login tokens. +Set `JWT_SECRET` in `.env` to a long random value. Generate one with `openssl rand -hex 32`. ConvertX uses it to sign the login tokens, and Compose stops with an error if it is empty. ## Deviations from the standard setup @@ -25,6 +25,10 @@ None. Open the web interface. ConvertX sends you to the setup page, where you create your account. Do this right after the first start, because anyone who can reach the service can register the first account. After that, registration is closed. +## Upgrading + +Earlier versions of this stack had a sample value for `JWT_SECRET` in `compose.yaml`. It is now empty in `.env`, and you must set it. With a new value, everyone has to log in again. + ## Links - [ConvertX documentation and source code](https://github.com/C4illin/ConvertX) diff --git a/services/convertx/compose.yaml b/services/convertx/compose.yaml index 0ac1e3d6..f47796be 100644 --- a/services/convertx/compose.yaml +++ b/services/convertx/compose.yaml @@ -53,7 +53,7 @@ services: network_mode: service:tailscale # Sidecar configuration to route the service through Tailscale container_name: app-${SERVICE} # Name for local container management environment: - - JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() if unset + - JWT_SECRET=${JWT_SECRET:?Set JWT_SECRET in .env} - TZ=${TZ} volumes: - ./${SERVICE}-data:/app/data diff --git a/services/formbricks/.env b/services/formbricks/.env index e8d2ca74..acf6f59b 100644 --- a/services/formbricks/.env +++ b/services/formbricks/.env @@ -42,16 +42,16 @@ DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=pub # NextJS Auth # @see: https://next-auth.js.org/configuration/options#nextauth_secret -# You can use: `openssl rand -hex 32` to generate a new one -NEXTAUTH_SECRET="7b62c37371798cf96dc019f3d4f712a27d1b05d0755ffcf96481b8504697f532" +# Required. Generate it with: openssl rand -hex 32 +NEXTAUTH_SECRET= # Encryption Key is used for 2FA & Single use URLs for Link Surveys -# You can use: `openssl rand -hex 32` to generate a new one -ENCRYPTION_KEY="i1e284266e3f7ace4772e329e0494aa1d6110fba48db06bd9652e7a9fdd167281" +# Required. Generate it with: openssl rand -hex 32 +ENCRYPTION_KEY= # API Secret for running cron jobs. -# You can use: `openssl rand -hex 32` to generate a new one -CRON_SECRET="b5af3d39789e7730004a01bb84922914ea0b478fe67784ce3fa8e4c35096d6b4" +# Required. Generate it with: openssl rand -hex 32 +CRON_SECRET= # Redis URL for caching, rate limiting, and audit logging # To use external Redis/Valkey: remove the redis service below and update this URL diff --git a/services/formbricks/README.md b/services/formbricks/README.md index cf5bd57f..4cf584da 100644 --- a/services/formbricks/README.md +++ b/services/formbricks/README.md @@ -23,7 +23,7 @@ Set these values in `.env`: - **`TS_URL`.** The name of the device on your Tailnet, `formbricks..ts.net`. - **`WEBAPP_URL`.** The address that you use to open Formbricks. The sample value is `http://${TS_URL}:3000`, which is the direct port on the Tailnet. To use the HTTPS address of Tailscale Serve, change it to `https://${TS_URL}`. `NEXTAUTH_URL` and `PUBLIC_URL` follow this value. -- **`NEXTAUTH_SECRET`, `ENCRYPTION_KEY`, and `CRON_SECRET`.** The sample values are public. Replace each with its own random value from `openssl rand -hex 32`. +- **`NEXTAUTH_SECRET`, `ENCRYPTION_KEY`, and `CRON_SECRET`.** Three different random values. Generate each with `openssl rand -hex 32`. Compose stops with an error if one of them is empty. - **The `SMTP_*` and `MAIL_FROM` values.** The details of your mail server, if Formbricks should send email. The sample values do not work. ## Deviations from the standard setup @@ -38,6 +38,13 @@ Set these values in `.env`: The first start takes about three minutes, because Formbricks prepares its database. Then open the web interface at the address from `WEBAPP_URL` and create the first account, which becomes the owner of the organisation. +## Upgrading + +Earlier versions of this stack shipped sample values for `NEXTAUTH_SECRET`, `ENCRYPTION_KEY`, and `CRON_SECRET` in `.env`. They are now empty, and you must set them. + +- If you already replaced the sample values, keep your own. +- If your `.env` still has the sample values, set new ones. With a new `NEXTAUTH_SECRET`, everyone has to log in again. Formbricks uses `ENCRYPTION_KEY` for two-factor authentication and for single-use links of link surveys, so existing ones stop working with a new key. + ## Links - [Formbricks self-hosting documentation](https://formbricks.com/docs/self-hosting/overview) diff --git a/services/formbricks/compose.yaml b/services/formbricks/compose.yaml index efeb97b0..a287f060 100644 --- a/services/formbricks/compose.yaml +++ b/services/formbricks/compose.yaml @@ -86,9 +86,9 @@ services: - WEBAPP_URL=${WEBAPP_URL} - NEXTAUTH_URL=${NEXTAUTH_URL} - DATABASE_URL=${DATABASE_URL} - - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} - - ENCRYPTION_KEY=${ENCRYPTION_KEY} - - CRON_SECRET=${CRON_SECRET} + - NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?Set NEXTAUTH_SECRET in .env} + - ENCRYPTION_KEY=${ENCRYPTION_KEY:?Set ENCRYPTION_KEY in .env} + - CRON_SECRET=${CRON_SECRET:?Set CRON_SECRET in .env} - REDIS_URL=${REDIS_URL} - LOG_LEVEL=${LOG_LEVEL} - ENTERPRISE_LICENSE_KEY=${ENTERPRISE_LICENSE_KEY} diff --git a/services/hemmelig/.env b/services/hemmelig/.env index cc5d3977..6ffc2bd3 100644 --- a/services/hemmelig/.env +++ b/services/hemmelig/.env @@ -19,4 +19,7 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim # Optional Service variables # PUID=1000 +# Required: at least 32 characters. Generate it with: openssl rand -hex 32 +BETTER_AUTH_SECRET= + #EXAMPLE_VAR="Environment variable" diff --git a/services/hemmelig/README.md b/services/hemmelig/README.md index 662a9dd7..c883c734 100644 --- a/services/hemmelig/README.md +++ b/services/hemmelig/README.md @@ -18,10 +18,8 @@ This stack runs Hemmelig with a Tailscale sidecar, as described in [the standard ## Before you start -Change these values in `compose.yaml`: - -- **`BETTER_AUTH_URL` and `HEMMELIG_BASE_URL`.** The address of the web interface, `https://hemmelig..ts.net`. The sample value is `https://secrets.example.com`. -- **`BETTER_AUTH_SECRET`.** A random value of at least 32 characters. The sample value is public. +- **Set the addresses in `compose.yaml`.** Change `BETTER_AUTH_URL` and `HEMMELIG_BASE_URL` to the address of the web interface, `https://hemmelig..ts.net`. The sample value is `https://secrets.example.com`. +- **Set the secret in `.env`.** Set `BETTER_AUTH_SECRET` to a random value of at least 32 characters. Generate one with `openssl rand -hex 32`. Compose stops with an error if it is empty. ## Deviations from the standard setup @@ -31,6 +29,10 @@ None. Open the web interface. Hemmelig asks you to create the first account. +## Upgrading + +Earlier versions of this stack had a sample value for `BETTER_AUTH_SECRET` in `compose.yaml`. It is now empty in `.env`, and you must set it. With a new value, everyone has to log in again. + ## Links - [Hemmelig documentation and source code](https://github.com/HemmeligOrg/Hemmelig.app) diff --git a/services/hemmelig/compose.yaml b/services/hemmelig/compose.yaml index 93bd317b..7c5e6224 100644 --- a/services/hemmelig/compose.yaml +++ b/services/hemmelig/compose.yaml @@ -57,7 +57,7 @@ services: - PGID=1000 - TZ=${TZ} - DATABASE_URL=file:/app/database/hemmelig.db - - BETTER_AUTH_SECRET=change-this-to-a-secure-secret-min-32-chars + - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:?Set BETTER_AUTH_SECRET in .env} - BETTER_AUTH_URL=https://secrets.example.com - NODE_ENV=production - HEMMELIG_BASE_URL=https://secrets.example.com diff --git a/services/karakeep/.env b/services/karakeep/.env index 0255c8b7..3e10ac20 100644 --- a/services/karakeep/.env +++ b/services/karakeep/.env @@ -22,8 +22,9 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim # PUID=1000 KARAKEEP_VERSION=release -NEXTAUTH_SECRET=super_random_string -MEILI_MASTER_KEY=another_random_string +# Required: two different random values. Generate each with: openssl rand -base64 36 +NEXTAUTH_SECRET= +MEILI_MASTER_KEY= NEXTAUTH_URL=https:// MAX_ASSET_SIZE_MB=50 DISABLE_SIGNUPS=false diff --git a/services/karakeep/README.md b/services/karakeep/README.md index 2547761d..bb6d2db4 100644 --- a/services/karakeep/README.md +++ b/services/karakeep/README.md @@ -21,7 +21,7 @@ This stack runs Karakeep with a Tailscale sidecar, as described in [the standard Set these values in `.env`: - **`NEXTAUTH_URL`.** The address of the web interface, `https://karakeep..ts.net`. Karakeep does not start with the sample value. -- **`NEXTAUTH_SECRET` and `MEILI_MASTER_KEY`.** Two different random values, for example from `openssl rand -base64 36`. The sample values are public. +- **`NEXTAUTH_SECRET` and `MEILI_MASTER_KEY`.** Two different random values. Generate each with `openssl rand -base64 36`. Compose stops with an error if one of them is empty. ## Deviations from the standard setup @@ -34,6 +34,10 @@ Set these values in `.env`: Open the web interface and sign up. The first account becomes the administrator. To stop others from registering afterwards, set `DISABLE_SIGNUPS=true` in `.env` and restart the stack. +## Upgrading + +Earlier versions of this stack shipped sample values for `NEXTAUTH_SECRET` and `MEILI_MASTER_KEY` in `.env`. They are now empty, and you must set them. If you already replaced the sample values, keep your own. With a new `NEXTAUTH_SECRET`, everyone has to log in again. + ## Links - [Karakeep documentation](https://docs.karakeep.app/) diff --git a/services/karakeep/compose.yaml b/services/karakeep/compose.yaml index e5e27286..ec73e6bb 100644 --- a/services/karakeep/compose.yaml +++ b/services/karakeep/compose.yaml @@ -56,6 +56,8 @@ services: - .env environment: MEILI_ADDR: http://meilisearch:7700 + NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:?Set NEXTAUTH_SECRET in .env} + MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?Set MEILI_MASTER_KEY in .env} BROWSER_WEB_URL: http://chrome:9222 # OPENAI_API_KEY: ... @@ -105,5 +107,6 @@ services: - .env environment: MEILI_NO_ANALYTICS: "true" + MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?Set MEILI_MASTER_KEY in .env} volumes: - ./${SERVICE}-data/meilisearch:/meili_data