454 lines
57 KiB
Markdown
454 lines
57 KiB
Markdown
---
|
|
title: Integrating Secrets
|
|
description: Discover how to leverage the incredibly useful but optional integrations that Install Doctor supports by integrating variables in the form of environment variables and encrypted secrets into your own custom fork.
|
|
sidebar_label: Secrets
|
|
slug: /customization/secrets
|
|
---
|
|
|
|
Install Doctor implements many optional features that rely on user-specific variables. Most of these user-specific variables are API keys. To augment that capabilities of your device, Install Doctor can leverage API keys to many free and popular cloud services. These API keys, as well as other user-specific variables, can be utilized by defining them as environment variables prior to running the start script. It is also possible to encrypt and bundle some of these secrets into your own fork of the Install Doctor repository.
|
|
|
|
## Environment Variables
|
|
|
|
The easiest way to get started with automating the Install Doctor provisioning process and leveraging optional features is to define user-specific variables as environment variables.
|
|
|
|
For instance, if you want to automate the provisioning process the first time you run the Install Doctor quick start script (without deep diving into all the variables yet), you can run the following (depending on your operating system):
|
|
|
|
**Linux / macOS:**
|
|
|
|
```shell
|
|
export HEADLESS_INSTALL=true
|
|
export SOFTWARE_GROUP=Standard-Desktop
|
|
export FULL_NAME="Joe Shmoe"
|
|
export PRIMARY_EMAIL="help@megabyte.space"
|
|
export PUBLIC_SERVICES_DOMAIN="megabyte.space"
|
|
export START_REPO=my-gh-user/my-fork-name
|
|
bash <(curl -sSL https://install.doctor/start)
|
|
```
|
|
|
|
**Windows:**
|
|
|
|
```shell
|
|
$env:HEADLESS_INSTALL = true
|
|
$env:SOFTWARE_GROUP = Standard-Desktop
|
|
$env:FULL_NAME = 'Joe Shmoe'
|
|
$env:PRIMARY_EMAIL = 'help@megabyte.space'
|
|
$env:PUBLIC_SERVICES_DOMAIN = 'megabyte.space'
|
|
$env:START_REPO = 'my-gh-user/my-fork-name'
|
|
iex ((New-Object System.Net.WebClient).DownloadString('https://install.doctor/windows'))
|
|
```
|
|
|
|
**Qubes:**
|
|
|
|
```shell
|
|
export HEADLESS_INSTALL=true
|
|
export SOFTWARE_GROUP=Standard-Desktop
|
|
export FULL_NAME="Joe Shmoe"
|
|
export PRIMARY_EMAIL="help@megabyte.space"
|
|
export PUBLIC_SERVICES_DOMAIN="megabyte.space"
|
|
export START_REPO=my-gh-user/my-fork-name
|
|
qvm-run --pass-io sys-firewall "curl -sSL https://install.doctor/qubes" > ~/setup.sh
|
|
bash ~/setup.sh
|
|
```
|
|
|
|
Running the blocks of code listed above will bypass the Install Doctor TUI prompt system, allowing a completely headless setup process for your device.
|
|
|
|
There are many other variables you can make use of which are detailed in one of the following sections below.
|
|
|
|
## Encrypted Secrets
|
|
|
|
For added security and convienience, Install Doctor supports embedding your secret variables into your own fork of Install Doctor by encrypting them with the [Chezmoi](https://www.chezmoi.io/) default encryption provider called [Age](https://github.com/FiloSottile/age). By using this method, you will no longer have to manage a long set of environment variables and you will be able to store your encrypted secrets in a public git that you can use to provision any of your devices.
|
|
|
|
**The first thing you should do when leveraging your own Age encryption key in your own fork of Install Doctor is to delete all the keys stored in the `home/.chezmoitemplates/secrets/` folder.** If you do not do this, then Install Doctor will try unencrypting the test secrets using your key.
|
|
|
|
### Creating an Age Key (Password Protected)
|
|
|
|
Install Doctor's default recommended encryption method involves:
|
|
|
|
1. Creating a password protected Age encryption key
|
|
2. Using the encryption key to encrypt your variables which are stored in `home/.chezmoitemplates/secrets/`
|
|
|
|
To create an encryption key, first ensure Age is installed and available in your PATH (the quick start script will automatically install Homebrew / Age). With `age` available from your terminal, run the following:
|
|
|
|
```shell
|
|
age-keygen | age -p > key.age
|
|
```
|
|
|
|
The output should look something like the following if you decided to forego creating a custom password:
|
|
|
|
```text
|
|
Public key: age1wzpkjhk6jtgq2d3q97jdq7ptwpra7kdplnt38p5ruetcwfzahvps40l6a5
|
|
age: using autogenerated passphrase "act-client-permit-coil-clinic-cushion-wheat-beauty-ski-alarm"
|
|
```
|
|
|
|
Make note of the public key and your password. The public key should be added to the `home/.chezmoi.yaml.tmpl` file under the `age.recipient` key (just search for, "recipient" in the file). The `key.age` file that was generated should be added to `home/key.txt.age`. The quick start script that Install Doctor hosts expects the key to be stored in `home/key.txt.age`.
|
|
|
|
With all of this done, you can commit your changes. Your `key.txt.age` file is useless to anyone who does not know the password to decrypt it. The Install Doctor start script (that you can find on the homepage) will prompt you to decrypt the `key.txt.age` file using your selected password and store it in the location specified in the `home/.chezmoi.yaml.tmpl` file. For automation purposes, if you are using the default `home/.chezmoi.yaml.tmpl` file settings, the unencrypted file is temporarily stored on the disk in the `~/.config/age/chezmoi.txt` location. This makes it easier to re-run the provisioning process and add new secrets to your custom fork. **After you are done using the encryption key, you should delete the unencrypted Age key file stored at `~/.config/age/chezmoi.txt`.**
|
|
|
|
### Adding Secrets Using the Age Key
|
|
|
|
To add secrets to your custom fork, you need to ensure Chezmoi is configured to use the file stored in `~/.config/age/chezmoi.txt` that is decrypted using a password from the file stored in `home/key.txt.age` of your custom fork. The easiest way to do this for the first time is to ensure the `START_REPO` environment variable is pointing to your custom fork and run the quick start script:
|
|
|
|
**Linux / macOS:**
|
|
|
|
```shell
|
|
export START_REPO=my-gh-user/my-fork-name
|
|
bash <(curl -sSL https://install.doctor/start)
|
|
```
|
|
|
|
**Windows:**
|
|
|
|
```powershell
|
|
$env:START_REPO = 'my-gh-user/my-fork-name'
|
|
iex ((New-Object System.Net.WebClient).DownloadString('https://install.doctor/windows'))
|
|
```
|
|
|
|
**Qubes:**
|
|
|
|
```shell
|
|
export START_REPO=my-gh-user/my-fork-name
|
|
qvm-run --pass-io sys-firewall "curl -sSL https://install.doctor/qubes" > ~/setup.sh
|
|
bash ~/setup.sh
|
|
```
|
|
|
|
Early in the provisioning process, the script will prompt you for your Age encryption passphrase. After this happens, you can CTRL+C out of the script and begin adding your encrypted secrets to your git repository fork.
|
|
|
|
With Chezmoi and Age configured, you can now begin encrypting all the pieces of data that you do not want to have to pass in as environment variables. You can also encrypt other things like SSH keys, GPG keys, etc.
|
|
|
|
#### Encrypting an API Key
|
|
|
|
To encrypt an API key, you would run:
|
|
|
|
```shell
|
|
echo "apikey-xXxxXxX" | chezmoi encrypt
|
|
```
|
|
|
|
The resulting text that outputs to the terminal would look something like this:
|
|
|
|
```text
|
|
-----BEGIN AGE ENCRYPTED FILE-----
|
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCamNtb0pvOFRmYXRyNEhY
|
|
R1BpS09IYVBSSG83Rmh2MVJpdExKdjZrY2hVCmRmTTdjUDJyU2ZZK0NObmUwZ0dH
|
|
eGtFQUV6NXVPdjR1WFljNUkyczZuVjAKLS0tIDVTZDFPLytQVTJMNStUK21KYVF4
|
|
QVBhb0hIMG9tRjVuYWlHejN4cDJrQkkKTx7EQBmWL+0mXeaOOAtqo9rbJjWYx7mj
|
|
Jr4Trf/qfrmiDXX/
|
|
-----END AGE ENCRYPTED FILE-----
|
|
```
|
|
|
|
Copy the text including the lines that contain `BEGIN AGE ENCRYPTED FILE` and `END AGE ENCRYPTED FILE` and store them into the appropriate file nested inside `home/.chezmoitemplates/secrets/`. You can determine the supported key file names by referring to the Supported Variables / Secrets Table below.
|
|
|
|
#### Encrypting a File
|
|
|
|
To encrypt an entire file (named `myfile.ext` in the following example), you can run:
|
|
|
|
```shell
|
|
chezmoi encrypt myfile.ext
|
|
```
|
|
|
|
The resulting encrypted text can then be copied / pasted into the appropriate key file location. Supported targets are listed below in the Supported Variables / Secrets Table section.
|
|
|
|
### Using GPG
|
|
|
|
If you prefer to use GPG instead of Age as your encryption mechanism, you can define this option in the `home/.chezmoi.yaml.tmpl` file. For more details on this implementation, see the [GPG page in the Chezmoi docs](https://www.chezmoi.io/user-guide/encryption/gpg/).
|
|
|
|
Users may want to do this so they can protect their secrets with hardware-backed encryption via devices like a YubiKey. For details on how to setup GPG with a YubiKey, refer to [this guide](https://github.com/drduh/YubiKey-Guide).
|
|
|
|
## Supported Variables / Secrets Table
|
|
|
|
The following table details all the custom variables supported by Install Doctor. The variable column denotes the name of the environment variable that can be specified to enable the automated deployment and the description details where the variable is used along with relevant details.
|
|
|
|
Unless otherwise specified in the description column, all of the variables in this chart can be stored as secrets by saving the encrypted secret environment variable in the `home/.chezmoitemplates/secrets/` folder (with a file name equal to the environment variable name). So, if you wanted to saved your `GITHUB_TOKEN` as an encrypted secret in your fork then you would encrypt following the instructions detailed above and then saved the encrypted secret in the `home/.chezmoitemplates/secrets/GITHUB_TOKEN` location (e.g. `echo "MY_GITHUB_API_TOKEN" | chezmoi encrypt > "home/.chezmoitemplates/secrets/GITHUB_TOKEN"`).
|
|
|
|
| Variable | Description |
|
|
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
|
|
| `AGE_PASSWORD` | Automate the Chezmoi Age decryption process by passing in the passphrase for the `key.txt.age` file stored in the `home/` folder (which is used to encrypt all your secrets). _This variable can only be passed in as an environment variable._ |
|
|
| `ANSIBLE_GALAXY_TOKEN` | Ansible Galaxy API token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `ANSIBLE_VAULT_PASSWORD` | Ansible Vault password stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `APPLE_USERNAME` | Username of your Apple developer account which is assigned to the `XCODES_USERNAME` variable for automated use of the Xcodes CLI and app |
|
|
| `APPLE_PASSWORD` | Password of your Apple developer account which is assigned to the `XCODES_PASSWORD` variable for automated use of the Xcodes CLI and app |
|
|
| `ATUIN_EMAIL` | E-mail address used for registering with [Atuin](https://atuin.sh/) |
|
|
| `ATUIN_PASSWORD` | Password used for registering with [Atuin](https://atuin.sh/) |
|
|
| `ATUIN_USERNAME` | Username used for registering with [Atuin](https://atuin.sh/) |
|
|
| `AWS_ACCESS_KEY_ID` | AWS access key ID (used for storing / retrieving from AWS Secret Manager which is used for headless Xcode installations / developer account authentications) |
|
|
| `AWS_DEFAULT_REGION` | Default AWS region to use when region is not passed in via commands (e.g. `us-east-1`) |
|
|
| `AWS_SECRET_ACCESS_KEY` | AWS access key secret (used in conjunction with the `AWS_ACCESS_KEY_ID`) |
|
|
| `CELL_PHONE_NUMBER` | Cell phone number you would like to receive [Twilio notifications from via Apprise](https://github.com/caronc/apprise/wiki/Notify_twilio). The number should follow the format of `13332224444` where the 10-digit phone number is prefixed by the country code. |
|
|
| `CLOUDFLARE_API_KEY` | CloudFlare administration API key. Used by CloudFlare CLI. |
|
|
| `CLOUDFLARE_ACCOUNT_ID` | The CloudFlare account ID |
|
|
| `CLOUDFLARE_ORIGIN_CA_KEY` | The CloudFlare origin CA key (currently unused) |
|
|
| `CLOUDFLARE_R2_ID` and `CLOUDFLARE_R2_ID_USER` | The CloudFlare R2 _read / edit_ access key ID used for mounting S3-compliant buckets to various locations such as `/mnt/s3-public`, `/mnt/s3-private`, and `~/.local/mnt/s3` via [rclone](https://rclone.org/). The configuration files are located in `~/.config/rclone/` when `CLOUDFLARE_R2_SECRET` and `.user.cloudflare.r2` in `.chezmoi.yaml` are defined. The key that ends in `_USER` is used for the `~/.local/mnt` mount. |
|
|
| `CLOUDFLARE_R2_SECRET` and `CLOUDFLARE_R2_SECRET_USER` | The CloudFlare R2 _read / edit_ secret access key used for mounting S3-compliant buckets to various locations such as `/mnt/s3-public`, `/mnt/s3-private`, and `~/.local/mnt/s3` via [rclone](https://rclone.org/). The configuration files are located in `~/.config/rclone/` when `CLOUDFLARE_R2_ID` and `.user.cloudflare.r2` in `.chezmoi.yaml` are defined. The key that ends in `_USER` is used for the `~/.local/mnt` mount. |
|
|
| `CLOUDFLARE_TEAMS_CLIENT_ID` | CloudFlare Teams client ID used to automatically connect to CloudFlare Teams network via [warp-cli](https://developers.cloudflare.com/warp-client/get-started/linux/) when `CLOUDFLARE_TEAMS_CLIENT_SECRET` is also available. You can acquire the secret from a CloudFlare Teams service token. See [this article](https://developers.cloudflare.com/cloudflare-one/identity/service-tokens/). |
|
|
| `CLOUDFLARE_TEAMS_CLIENT_SECRET` | CloudFlare Teams client secret used to automatically connect to CloudFlare Teams network via [warp-cli](https://developers.cloudflare.com/warp-client/get-started/linux/) when `CLOUDFLARE_TEAMS_CLIENT_ID` is also available. You can acquire the ID from a CloudFlare Teams service token. See [this article](https://developers.cloudflare.com/cloudflare-one/identity/service-tokens/). |
|
|
| `CLOUDFLARE_TEAMS_ORG` | The organization name used to connect to CloudFlare WARP Teams Zero Trust automatically. Used to populate the `organization` value referenced on [this page](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/mdm-deployment/). _Can only be passed in as environment variable or hardcoded into `home/.chezmoi.yaml.tmpl`_ |
|
|
| `CLOUDSDK_CORE_PROJECT` | Injected into `~/.config/shell/private.sh` and saved in your Chezmoi configuration. _Can only be passed in as environment variable or hardcoded into `home/.chezmoi.yaml.tmpl`._ |
|
|
| `DIGITALOCEAN_ACCESS_TOKEN` | DigitalOcean personal access token (generated via the [Applications & API > Personal access tokens section](https://cloud.digitalocean.com/account/api/tokens)). Used to connect to DigitalOcean-hosted Kubernetes cluster. |
|
|
| `DOCKERHUB_USER` | DockerHub username which is used in combination with the `DOCKERHUB_TOKEN` to headlessly authenticate Docker Desktop with DockerHub |
|
|
| `DOCKERHUB_TOKEN` | DockerHub API token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `ELEVENLABS_API_KEY` | API key for ElevenLabs which is used by [ShortGPT](https://github.com/RayVentura/ShortGPT) |
|
|
| `FIG_TOKEN` | Fig user API token used to headlessly login / authenticate with Fig. Token can be acquired on the [token dashboard](https://app.fig.io/settings/user-tokens) after logging in. |
|
|
| `FULL_NAME` | Your full name used in things like the Git config and NPM config. This can be passed in as an environment variable or hardcoded into the `home/.chezmoi.yaml.tmpl` file. |
|
|
| `GCE_SERVICE_ACCOUNT_EMAIL` | Injected into `~/.config/shell/private.sh` and saved in your Chezmoi configuration. _Can only be passed in as environment variable or hardcoded into `home/.chezmoi.yaml.tmpl`._ |
|
|
| `GITHUB_GIST_TOKEN` | GitHub token with gist permissions. Populates `~/.local/bin/gist` so that the key does not have to be stored in the `~` directory. |
|
|
| `GITHUB_READ_TOKEN` | GitHub token with repository read permissions. Populates `~/.config/ghorg/conf.yaml` so Ghorg can backup all of your GitHub repositories locally. |
|
|
| `GITHUB_TOKEN` | GitHub personal access token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `GITLAB_READ_TOKEN` | GitLab token with repository read permissions. Populates `~/.config/ghorg/conf.yaml` so Ghorg can backup all of your GitLab repositories locally. |
|
|
| `GITLAB_TOKEN` | GitLab personal access token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `GITLAB_RUNNER_TOKEN_DARWIN` | GitLab runner token to use on macOS machines. |
|
|
| `GITLAB_RUNNER_TOKEN_LINUX` | GitLab runner token to use on Linux machines. |
|
|
| `GITLAB_RUNNER_TOKEN_WINDOWS` | GitLab runner token to use on Windows machines. |
|
|
| `GMAIL_PASSWORD` | App password for GMail which is used as an outgoing SMTP service (for `git` e-mail). |
|
|
| `GOOGLE_SEARCH_API_KEY` | API key used by `search-gpt` available [here](https://developers.google.com/custom-search/v1/introduction). |
|
|
| `GOOGLE_SEARCH_ID` | Search engine ID for custom Google search engine utilized by `search-gpt` available [here](https://programmablesearchengine.google.com/controlpanel/all). |
|
|
| `HEADLESS_INSTALL` | Set to true if you would like all prompts to be bypassed. _This variable can only be passed in as an environment variable._ |
|
|
| `HEALTHCHECKS_API_KEY` | Healthchecks global API key used to integrate Healthchecks into the `autorestic` / `restic` backup systems. |
|
|
| `HEROKU_API_KEY` | Heroku API token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `HISHTORY_USER_SECRET` | User secret for synchronizing entries cataloged by [Hishtory](https://github.com/ddworken/hishtory). |
|
|
| `HOARD_API_TOKEN` | The API token for [Hoard]https://github.com/Hyde46/hoard). |
|
|
| `HOST` | The hostname of the device. Used for a FQDN that resolves to the device when combined with the \_ `PUBLIC_SERVICES_DOMAIN`. |
|
|
| `IFTTT_WEBHOOK_ID` | Webhook ID from the [Maker webhook on IFTTT](https://ifttt.com/maker_webhooks/settings). This is used to integrate [Apprise with IFTTT integration](https://github.com/caronc/apprise/wiki/Notify_ifttt). |
|
|
| `JUMPCLOUD_CONNECT_KEY` | JumpCloud device enrollment key. |
|
|
| `KEYID` | Your GPG key ID available on the MIT or Ubuntu servers. During provisioning, the key will be imported and trusted with an elevated trust level. This can only be passed in as an environment variable or be hardcoded into the `home/.chezmoi.yaml.tmpl` file. |
|
|
| `MATRIX_PASSWORD` | Password for user account for matrix.org through [Element](https://app.element.io/). Used to integrate [Matrix chatting with Apprise](https://github.com/caronc/apprise/wiki/Notify_matrix). |
|
|
| `MATRIX_USERNAME` | Username for user account for matrix.org through [Element](https://app.element.io/). Used to integrate [Matrix chatting with Apprise](https://github.com/caronc/apprise/wiki/Notify_matrix). |
|
|
| `NETDATA_ROOM` | [Netdata](https://www.netdata.cloud/) Cloud room ID to assign the device to. Requires `NETDATA_TOKEN` to also be defined. |
|
|
| `NETDATA_TOKEN` | [Netdata](https://www.netdata.cloud/) Cloud API token to use when enrolling. Requires `NETDATA_ROOM` to also be defined. |
|
|
| `NGINX_AMPLIFY_API_KEY` | If NGINX is installed on the system, then this key will be used to join the NGINX Amplify cloud service. |
|
|
| `NGROK_AUTH_TOKEN` | Populates [Ngrok](https://ngrok.com/) token in `~/.config/ngrok/ngrok.yml` which allows you to use logged-in-only Ngrok services |
|
|
| `NO_RESTART` | Prevents computer from automatically restarting. This may interfere with system updates. |
|
|
| `NPM_TOKEN` | NPM API token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `OPENAI_API_KEY` | OpenAI API key available in the [OpenAPI account settings manager](https://platform.openai.com/account/api-keys). Used for OpenCommit (CLI that automatically generates commit messages). |
|
|
| `OVPN_PASSWORD` | The OpenVPN password to apply to VPN profiles located at `~/.config/vpn/*.ovpn` (e.g. encrypted ProtonVPN OpenVPN profiles). `OVPN_USERNAME` must also be defined. |
|
|
| `OVPN_USERNAME` | The OpenVPN username to apply to VPN profiles located at `~/.config/vpn/*.ovpn` (e.g. encrypted ProtonVPN OpenVPN profiles). `OVPN_PASSWORD` must also be defined. |
|
|
| `OPENWEATHERMAP_API_KEY` | Free API key retrieved from [OpenWeatherMap](https://openweathermap.org/) which powers the `wego` terminal weather application |
|
|
| `PORTAINER_BUSINESS_LICENSE` | Portainer business license key (free for up to 5 nodes) |
|
|
| `PRIMARY_EMAIL` | Your primary e-mail address used in things like the Git config and NPM config. You must pass this as an environment variable or hardcode it into the `home/.chezmoi.yaml.tmpl` file. |
|
|
| `PUBLIC_SERVICES_DOMAIN` | The CloudFlare domain that you would like to use for CloudFlare DNS integration features. _Can only be passed in as an environment variable._ |
|
|
| `PYPI_TOKEN` | PyPi.org API token stored in `~/.config/shell/private.sh` |
|
|
| `REDDIT_APP_ID` | Application ID for Reddit app created according to the [Apprise integration documentation](https://github.com/caronc/apprise/wiki/Notify_reddit). |
|
|
| `REDDIT_APP_SECRET` | Application secret for Reddit app created according to the [Apprise integration documentation](https://github.com/caronc/apprise/wiki/Notify_reddit). |
|
|
| `REDDIT_PASSWORD` | Password for the Reddit developer account linked to the Reddit app created according to the [Apprise integration documentation](https://github.com/caronc/apprise/wiki/Notify_reddit). |
|
|
| `REDDIT_USERNAME` | Username for the Reddit developer account linked to the Reddit app created according to the [Apprise integration documentation](https://github.com/caronc/apprise/wiki/Notify_reddit). |
|
|
| `REPLICATE_API_KEY` | [Replicate API key](https://replicate.com/account/api-tokens) (used for [AgentGPT](https://github.com/reworkd/AgentGPT)) |
|
|
| `RESTIC_PASSWORD` | Password used to encrypt user-level Restic backups (leveraged by `autorestic`). This includes `$HOME` directory backups and application data backups. |
|
|
| `RESTIC_SYSTEM_PASSWORD` | Password used to encrypt system-level Restic backups (leveraged by `autorestic`). This includes Docker volume backups and any other types of backups that might require sudo privileges. |
|
|
| `RESTRICTED_ENVIRONMENT` | Set to `true` if you are setting up a device that should not use sudo / administrator privileges. _This can only be specified as an environment variable._ **This feature is a WIP.** Pull requests welcome. |
|
|
| `SAMBA_NETBIOS_NAME` | NetBIOS name to use with Samba. Default value is the same value as the `HOSTNAME` variable. _Can only be specified as an environment variable._ |
|
|
| `SAMBA_WORKGROUP` | Samba workgroup name. Default value is `BETELGEUSE`. _Can only be specified as an environment variable._ |
|
|
| `SENDGRID_API_KEY` | SendGrid API token with the "Mail" permission. Used for sending mail with Postfix. |
|
|
| `SERP_API_KEY` | API key for [Serper.dev](https://serper.dev/api-key) (used by [AgentGPT](https://github.com/reworkd/AgentGPT)) |
|
|
| `SFTPGO_DEFAULT_ADMIN_PASSWORD` | Password for default admin user that can login to the [SFTPGo](https://github.com/drakkan/sftpgo) web interface. |
|
|
| `SFTPGO_DEFAULT_ADMIN_USERNAME` | Username for default admin user that can login to the [SFTPGo](https://github.com/drakkan/sftpgo) web interface. |
|
|
| `SLACK_API_TOKEN` | Slack API personal access token that populates `~/.config/slack-term/config` so that you can use Slack from your terminal with [slack-term](https://github.com/jpbruinsslot/slack-term). |
|
|
| `SLACK_BOT_USER_OAUTH_TOKEN` | Slack bot OAuth token. Used by Apprise Slack integration so that user can post to Slack (with support for attachments) from the CLI. |
|
|
| `SNAPCRAFT_EMAIL` | Snapcraft.io e-mail address associated with the `SNAPCRAFT_MACAROON` and `SNAPCRAFT_UNBOUND_DISCHARGE` (detailed below). Stored in `~/.config/shell/private.sh` so developer API credentials can be loaded by running `source "~/.config/shell/private.sh"`. \*Can only be included as an environment variable or hardcoded into `home/.chezmoi.yaml.tmpl`. | |
|
|
| `SNAPCRAFT_MACAROON` | Snapcraft.io authentication variable stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `SNAPCRAFT_UNBOUND_DISCHARGE` | Snapcraft.io authentication variable stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `SOFTWARE_GROUP` | Should be equal to only of the software lists defined in `home/.chezmoidata.yaml` (see the [Customization](/docs/customization) page for more details). |
|
|
| `START_REPO` | Set to your GitHub username (if your fork is named `install.doctor`) to be able to provision your device with the one-liner outlined on the homepage. You can also specify any GitHub project by setting this equal to `GITHUB_USERNAME/PROJECT_NAME` or a full git address (e.g. `git@gitlab.com:megabyte-labs/install.doctor`). _This can only be passed in as an environment variable._ |
|
|
| `SUDO_PASSWORD` | Provide the sudo / administrator password to completely automate sudo password input. This is required on for automated deployments where the user running the script has a sudo password. |
|
|
| `SURGE_LOGIN` | The e-mail address associated with your [surge.sh](https://surge.sh/) account. |
|
|
| `SURGE_TOKEN` | The [surge.sh](https://surge.sh/) authentication token acquired by logging in and running `surge token`. |
|
|
| `TIMEZONE` | Your timezone in the `America/New_York` format. It should be available in the TZ database. If not passed in as an environment variable, then the device's current timezone will be assumed to be correct. |
|
|
| `TWILIO_ACCOUNT_SID` | The account SID for Twilio which can be acquired on the bottom of the homepage of the [Twilio console](https://console.twilio.com/). Used for [Apprise integration of Twilio](https://github.com/caronc/apprise/wiki/Notify_twilio). |
|
|
| `TWILIO_AUTH_TOKEN` | The Twilio auth token found on the bottom of the homepage of the [Twilio console](https://console.twilio.com/). Used for [Apprise integration of Twilio](https://github.com/caronc/apprise/wiki/Notify_twilio). |
|
|
| `TWILIO_FROM_NUMBER` | The number to send out Twilio messages from. Should be registered in your Twilio account and be in the form `13332224444` with the country code included (e.g. `1` for the US in the sample phone number). |
|
|
| `TWITTER_ACCESS_TOKEN`, `TWITTER_ACCESS_TOKEN_SECRET`, `TWITTER_API_KEY`, `TWITTER_API_KEY_SECRET` | Various secrets you can generate using the Twitter Developer portal. Integrated into Apprise to allow tweeting from the command-line. Apprise provides [details](https://github.com/caronc/apprise/wiki/Notify_twitter). |
|
|
| `VAGRANT_CLOUD_TOKEN` | VagrantUp API token stored in `~/.config/shell/private.sh` so developer API keys can be loaded by running `source "~/.config/shell/private.sh"`. |
|
|
| `VMWARE_WORKSTATION_LICENSE_KEY` | License key used for pre-registering VMWare Pro or VMWare Fusion |
|
|
| `VNC_PASSWORD` | VNC password used by macOS VNC system utility or TigerVNC on Linux. Default if not passed in is `vncpass`. |
|
|
| `VNC_READ_PASSWORD` | VNC password used for a read-only session. Default if not passed in is `readonly`. |
|
|
| `WAKATIME_API_KEY` | API key for the Wakatime VSCode time tracking plugin which gets injected into `~/.config/wakatime/.wakatime.cfg` |
|
|
| `WAZUH_MANAGER` | Address of the Wazuh server to configure the Wazuh client to send data to. Defaults to `wazuh.{{ PUBLIC_SERVICES_DOMAIN }}` |
|
|
| `WINDOWS_11_PRO_KEY` | Activation key for Windows 11 Professional |
|
|
| `WORK_ENVIRONMENT` | Set to `true` if you are setting up a corporate device. When `true`, the provisioning process will avoid installing / configuring things like Tor, which are likely to be banned by corporate networks. _This can only be specified as an environment variable._ **This feature is a WIP.** Pull requests welcome. |
|
|
|
|
\*Note: When creating a pull request that introduces new variables, please also open a pull request updating this table to reflect those changes. Include a short description of where and how the variable / secret is used in the description column.
|
|
|
|
### SSH Keys
|
|
|
|
SSH keys can be saved into your fork by encrypting your files and storing them into the `home/.chezmoitemplates/ssh/` folder. During the provisioning process, all of the files in the `home/.chezmoitemplates/ssh/` folder are decrypted and placed into your `~/.ssh` folder. For example, if you wanted to encrypt your current `id_rsa` file into your fork of Install Doctor, you would run:
|
|
|
|
```shell
|
|
chezmoi encrypt "$HOME/id_rsa" > "${XDG_DATA_HOME:-$HOME/.local/share}/chezmoi/home/.chezmoitemplates/ssh/id_rsa"
|
|
```
|
|
|
|
After that, your `id_rsa` file will be encrypted in your fork and you can safely `git commit` / `git push` your encrypted `id_rsa` file to your public GitHub fork.
|
|
|
|
### VPN Profiles
|
|
|
|
VPN profiles can be stored in encrypted format into your fork by placing `*.ovpn`, `*.conf` (WireGuard for macOS), and `*.nmconnection` (WireGuard for Linux) files into the `home/dot_config/vpn/` folder. Before committing the encrypted configurations into your source, you should encrypt the files with `chezmoi encrypt` and then add the following Go template logic to make sure that the files are only decrypted when the decryption key is present:
|
|
|
|
```text
|
|
{{- if (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) -}}
|
|
-----BEGIN AGE ENCRYPTED FILE-----
|
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAraUZ1dkFITlJMbmdhbXUx
|
|
ekQ2SjRhaE5uT3J1czh0V09hSkZuanYvUTJvCklTcHZ6RFBrUGx0VlhqQytEb01a
|
|
...
|
|
-----END AGE ENCRYPTED FILE-----
|
|
{{- end -}}
|
|
```
|
|
|
|
You also have to make sure that the file names are named exactly how you want the profiles to show up in the operating system UI and also:
|
|
|
|
1. Add `private_` to the beginning of the file name so that only your user can read the configurations
|
|
2. Add `.tmpl` to the end of the file name so that the Go template bindings referenced above are handled properly
|
|
|
|
#### OVPN Example
|
|
|
|
The following is an example of the original `.ovpn` file that is encrypted and stored in `home/dot_config/vpn/`:
|
|
|
|
```
|
|
client
|
|
dev tun
|
|
proto tcp
|
|
|
|
remote 1xx.1xx.1xx.1xx 8443
|
|
remote 1xx.1xx.1xx.1xx 7770
|
|
remote 1xx.1xx.1xx.1xx 443
|
|
|
|
remote-random
|
|
resolv-retry infinite
|
|
nobind
|
|
|
|
# The following setting is only needed for old OpenVPN clients compatibility. New clients
|
|
# automatically negotiate the optimal cipher.
|
|
cipher AES-256-CBC
|
|
|
|
auth SHA512
|
|
verb 3
|
|
|
|
setenv CLIENT_CERT 0
|
|
tun-mtu 1500
|
|
tun-mtu-extra 32
|
|
mssfix 1450
|
|
persist-key
|
|
persist-tun
|
|
|
|
reneg-sec 0
|
|
|
|
remote-cert-tls server
|
|
auth-user-pass
|
|
pull
|
|
fast-io
|
|
|
|
script-security 2
|
|
up /etc/openvpn/update-resolv-conf
|
|
down /etc/openvpn/update-resolv-conf
|
|
|
|
<ca>
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIFozCCA4ugAwIBAgIBATANBgkqhkiG9w0BAQ0FADBAMxxxxxxxxxxxxxxxxxxx
|
|
DK/yPwECUcPgHIeXiRjHnJt0Zcm23O2Q3RphpU+1SO3Xixxxxxxxxxxxxxxxxxxx
|
|
A1gTTlpi7A==
|
|
-----END CERTIFICATE-----
|
|
</ca>
|
|
|
|
key-direction 1
|
|
<tls-auth>
|
|
# 2048 bit OpenVPN static key
|
|
-----BEGIN OpenVPN Static key V1-----
|
|
6acef03f62675b4b1bbd0xxxxxxxxxxx
|
|
...
|
|
16672ea16c012664f8a9fxxxxxxxxxxx
|
|
-----END OpenVPN Static key V1-----
|
|
</tls-auth>
|
|
```
|
|
|
|
After the `.ovpn` file is decrypted to `~/.config/vpn/` during the provision process, if the `OVPN_PASSWORD` and `OVPN_USERNAME` are defined (as either environment variables or secrets stored at `home/.chezmoitemplates/secrets/`), then the file will be properly loaded into the NetworkManager on Linux and equivalent programs on macOS / Windows.
|
|
|
|
It is important to note that we only support passing one set of `OVPN_PASSWORD` and `OVPN_USERNAME` to the provision process so if you have OpenVPN connections from multiple providers with different usernames and passwords then you will have to extend our default logic.
|
|
|
|
#### WireGuard Example
|
|
|
|
The following is an example of a decrypted `.nmconnection` file stored in `home/dot_config/vpn/`:
|
|
|
|
```
|
|
[connection]
|
|
id=Proton WG Cambodia (UDP 51820)
|
|
uuid=2xxxxxx-30xx-xxxx-xxxx-85xxxxxxxxxx
|
|
type=vpn
|
|
autoconnect=true
|
|
permissions=user:xxx:;
|
|
|
|
[vpn]
|
|
connection-dns=10.2.0.1
|
|
local-ip4=10.2.0.2/32
|
|
local-private-key=oKHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
|
|
peer-allowed-ips=0.0.0.0/0
|
|
peer-endpoint=185.159.156.83:51820
|
|
peer-public-key=D4M0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
service-type=org.freedesktop.NetworkManager.wireguard
|
|
|
|
[ipv4]
|
|
dns-search=
|
|
method=auto
|
|
|
|
[ipv6]
|
|
addr-gen-mode=stable-privacy
|
|
dns-search=
|
|
method=auto
|
|
|
|
[proxy]
|
|
```
|
|
|
|
As you can see, the authentication keys are located directly in the file so there is no need to load a username and password like in the case of the OpenVPN profiles. The `.nmconnection` files are specific to the NetworkManager on Linux systems. You may have to craft the `.nmconnection` files by loading your configuration into the NetworkManager program and then grabbing the source from the resulting `.nmconnection` file.
|
|
|
|
On macOS / Windows, the WireGuard `.conf` file format is used. The same `.nmconnection` file above would look like this in `.conf` format:
|
|
|
|
```
|
|
[Interface]
|
|
# NetShield = 1
|
|
# Moderate NAT = off
|
|
# VPN Accelerator = on
|
|
PrivateKey = oKHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
|
|
Address = 10.2.0.2/32
|
|
DNS = 10.2.0.1
|
|
|
|
[Peer]
|
|
# SE-KH#1
|
|
PublicKey = D4M0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
AllowedIPs = 0.0.0.0/0
|
|
Endpoint = 185.159.156.83:51820
|
|
```
|
|
|
|
### Encrypted Files
|
|
|
|
There are a few cases where entire files need to be encrypted. Whenever possible, in cases like Tabby's configuration stored at `home/dot_config/tabby/config.yaml.tmpl` the optimized configuration stripped of secrets is provided as a fallback within the template. In cases like this, where no environment variable configuration parameter is made available, the encrypted file parts are stored in `home/.chezmoitemplates/files/`. The table below describes the capabilities that are offered by these files:
|
|
|
|
| File in `.chezmoitemplates/files/` | Description |
|
|
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `tabby` | The Tabby configuration file which can include several types of encryption keys in it. Used in `home/dot_config/tabby/config.yaml.tmpl`. |
|
|
| `google-assistant-client-secret` | The client secret required for the unofficial [Google Assistant](https://github.com/Melvin-Abraham/Google-Assistant-Unofficial-Desktop-Client) desktop applications. Details on how to set it can be found on the [project's wiki](https://github.com/Melvin-Abraham/Google-Assistant-Unofficial-Desktop-Client/wiki/Setup-Authentication-for-Google-Assistant-Unofficial-Desktop-Client). Used in `home/dot_config/Google Assistant/client-secret.json.tmpl`. The `google-assistant-tokens` file is also required (details below). |
|
|
| `google-assistant-tokens` | The tokens required for setting up the unofficial [Google Assistant](https://github.com/Melvin-Abraham/Google-Assistant-Unofficial-Desktop-Client). Used in `home/dot_config/Google Assistant/tokens.json.tmpl`. The `google-assistant-client-secret` is also required (details above) |
|
|
| `gphotos-sync` | The Google Photos API client secret file required for using [gphotos-sync](https://github.com/gilesknap/gphotos-sync) to backup your Google Photos content. Used in `home/dot_config/gphotos-sync/client_secret.json.tmpl`. |
|
|
|
|
If you inspect the files above, you will see that they are stored in their target location as a template that first checks if the encryption key is present. If the key is present, the files get decrypted. Ideally, if the key is not present, then a version of the file without sensitive information should be rendered. An example of this can be found in the Tabby configuration (`home/dot_config/tabby/config.yaml`). When contributing to this project, be sure to include this fallback logic whenever possible so that users who have not populated their fork with encrypted secrets can still retain functionality.
|
|
|
|
## Creating New Variables / Secrets
|
|
|
|
If you want to expand the capabilities of your fork beyond what we have provided, we recommend you follow the same approach we use when handling environment variables and secret encrypted keys.
|
|
|
|
### Combining Variables and Secrets
|
|
|
|
Ideally, whenever possible, the user should be able to pass in a variable as either an environment variable or as a secret included in the fork. In the `~/.config/shell/private.sh` file which houses private keys for cloud APIs that the user may want to source by running `. "~/.config/shell/private.sh"`, the DockerHub token is defined with:
|
|
|
|
```shell
|
|
export DOCKERHUB_TOKEN="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "key-DOCKERHUB_TOKEN")) }}{{ includeTemplate "secrets/key-DOCKERHUB_TOKEN" }}{{ else }}{{ env "DOCKERHUB_TOKEN" }}{{ end }}"
|
|
export DOCKERHUB_REGISTRY_PASSWORD="$DOCKERHUB_TOKEN"
|
|
```
|
|
|
|
This approach works well because it first checks for the presence of the `home/.chezmoitemplates/secrets/key-DOCKERHUB_TOKEN` file and then decrypts the value and injects it into the results `private.sh` file if the `key-DOCKERHUB_TOKEN` is present. Otherwise, it attempts to use the `DOCKERHUB_TOKEN` key.
|
|
|
|
_Note: Preferrably, you should store the secret as the same name as the corresponding environment variable._ That is, an environment variable named `DOCKERHUB_TOKEN` should be stored as a key stored in `home/.chezmoitemplates/secrets/key-DOCKERHUB_TOKEN`. Additionally, encrypted files that decrypt to files stored in `~/.ssh/` should be prefixed with `ssh-` instead of `key-`.
|
|
|
|
### Encrypted Files
|
|
|
|
For encrypted files, you should mark the file as a templated file by ending the file name with `.tmpl` and then you should include a check to make sure both the decryption key and the encrypted secret data location is available. For example, our `~/.ssh/id_rsa` file is generated by placing a file in `home/private_dot_ssh/private_id_rsa.tmpl` with the following content that makes these checks:
|
|
|
|
```shell
|
|
{{- if and (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "ssh-id-rsa")) -}}
|
|
{{ includeTemplate "secrets/ssh-id-rsa" | decrypt -}}
|
|
{{ end -}}
|
|
```
|
|
|
|
At provisioning time, if the necessary files are available, the encrypted secret data stored in `home/.chezmoitemplates/secrets/ssh-id-rsa` will be decrypted and added to the `~/.ssh/id_rsa` file.
|