diff --git a/docs/admin/security/secrets.md b/docs/admin/security/secrets.md index ed658b0475..98d90fd9d8 100644 --- a/docs/admin/security/secrets.md +++ b/docs/admin/security/secrets.md @@ -5,9 +5,11 @@ more information about how to use secrets and other security tips, visit our guide to [security best practices](../../tutorials/best-practices/security-best-practices.md#secrets). -This article explains how to use secrets in a workspace. To authenticate the -workspace provisioner, see the +Use this guide to configure how templates make secrets available to Coder +workspaces. To authenticate workspace provisioners with Coder, see the provisioners documentation. +For secret values that developers manage themselves, see +[User secrets](../../user-guides/user-secrets.md). ## Before you begin @@ -42,51 +44,12 @@ Users can view their public key in their account settings: > SSH keys are never stored in Coder workspaces, and are fetched only when > SSH is invoked. The keys are held in-memory and never written to disk. -## User Secrets +## User secrets (Early Access) -User secrets let each user store their own secret values in Coder and make -them available in workspaces without adding those values to template code. -They are a good fit for per-user credentials such as API keys, cloud -credentials, or other values that should follow a user across workspaces. - -Use the CLI to create and manage user secrets: - -```sh -# Create a secret from stdin and inject it into workspaces as an environment -# variable. -printf %s "$API_KEY" | coder secret create api-key \ - --description "API key for workspace tools" \ - --env API_KEY - -# Create a secret from stdin and inject it into a file in your workspace. -printf %s "$TOOL_CONFIG_CONTENTS" | coder secret create tool-config \ - --description "Tool configuration" \ - --file ~/.config/tool/config.json - -# List all of your secrets. -coder secret list - -# Show a single secret by name. -coder secret list api-key - -# Delete a secret you no longer need. -coder secret delete api-key -``` - -Use `--env` to inject a secret into your workspaces as an environment -variable. Use `--file` to inject it as a file in the workspace. File -paths must start with `~/` or `/`. Provide a secret value with `--value`, -or non-interactive stdin (pipe or redirect). Stdin is read verbatim. This -means `echo "$API_KEY" | ...` usually adds a trailing newline to the stored -value. Prefer `printf %s "$API_KEY" | ...` or `echo -n "$API_KEY" | ...` -when you do not want that newline. - -You can update a secret later with `coder secret update`, including rotating -the value or clearing an injection target by passing an empty string. Use -`coder secret delete` to remove a secret entirely. The secret value itself is -never returned by the API or CLI list output. For full command details, see -[`coder secret`](../../reference/cli/secret.md) and the -[Secrets API reference](../../reference/api/secrets.md). +User secrets are developer-managed values that Coder injects at workspace start. +If a user secret targets the same environment variable name or file path as a +template-provided variable or file, Coder injects the user secret into that +workspace. See the [User secrets guide](../../user-guides/user-secrets.md). ## Dynamic Secrets diff --git a/docs/manifest.json b/docs/manifest.json index 32d777824d..2042be727d 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -366,6 +366,13 @@ "description": "Personalize your environment with dotfiles", "path": "./user-guides/workspace-dotfiles.md", "icon_path": "./images/icons/art-pad.svg" + }, + { + "title": "User secrets", + "description": "Store secret values in Coder and automatically inject them into workspaces", + "path": "./user-guides/user-secrets.md", + "icon_path": "./images/icons/secrets.svg", + "state": ["early access"] } ] }, diff --git a/docs/user-guides/user-secrets.md b/docs/user-guides/user-secrets.md new file mode 100644 index 0000000000..1eb3b225ba --- /dev/null +++ b/docs/user-guides/user-secrets.md @@ -0,0 +1,146 @@ +# User secrets (Early Access) + +User secrets let you store secret values in Coder and make them available in +every workspace you own. + +> [!NOTE] +> User secrets are in Early Access and may change. For more information, see +> [feature stages](../install/releases/feature-stages.md#early-access-features). + +## How user secrets work + +Each user secret has: + +- A name, used to manage the secret with the CLI or REST API. +- A value, which contains the sensitive content. +- An optional description. +- An optional environment variable target, file target, or both. + +A secret without an environment variable target or file target is stored, but is +not injected into workspaces. + +User secrets apply to all workspaces that you own. Coder injects user secrets +when a workspace starts. If you create, update, or delete a secret while a +workspace is running, restart the workspace before relying on that change. + +Environment variable secrets are available to startup scripts and workspace +sessions. File secrets are written before startup scripts run. + +Secret values are omitted from CLI output and REST API responses after you +create or update them. + +> [!WARNING] +> Anyone with shell or file access to a workspace can read secrets injected into +> that workspace. Do not share a workspace that has injected secrets with users +> who should not access those values. + +## Create a secret + +Use `coder secret create ` to create a user secret. For sensitive values, +provide the value through non-interactive stdin with a pipe or redirect. This +keeps the value out of your shell history and process arguments. + +### Create an environment variable secret + +Use `--env` to inject a secret into your workspaces as an environment variable. +The secret is available under the environment variable name you provide. User +secret environment variables take precedence over template-defined environment +variables with the same name, including variables set with `coder_env`. + +```sh +echo -n "$API_KEY" | coder secret create api-key \ + --description "API key for workspace tools" \ + --env API_KEY +``` + +### Create a file secret + +Use `--file` to inject a secret as a file in your workspaces. File paths must +start with `~/` or `/`. + +```sh +coder secret create tool-config \ + --description "Tool configuration" \ + --file ~/.config/tool/config.json \ + < ./tool-config.json +``` + +Coder creates parent directories as needed. If the file already exists, including +a file created by a template or image, Coder updates the contents and preserves +the existing permissions. + +### Create a secret with environment variable and file targets + +You can inject the same secret as both an environment variable and a file: + +```sh +echo -n "$TOKEN" | coder secret create service-token \ + --description "Service token for workspace tools" \ + --env SERVICE_TOKEN \ + --file ~/.config/service/token +``` + +### Use `--value` + +You can also provide a secret value with `--value`: + +```sh +coder secret create api-key \ + --value "$API_KEY" \ + --description "API key for workspace tools" \ + --env API_KEY +``` + +For sensitive values, prefer stdin because `--value` can expose the secret in +shell history or process arguments. + +Stdin is read verbatim. If the source file ends with a trailing newline, Coder +stores that newline as part of the secret value. Use `echo -n` when you do not +want to store a trailing newline: + +```sh +echo -n "$API_KEY" | coder secret create api-key --env API_KEY +``` + +## Update a secret + +Use `coder secret update` to update a secret value, description, environment +variable target, or file target. At least one of `--value`, `--description`, +`--env`, or `--file` must be specified. + +```sh +# Update a secret value. +echo -n "$NEW_API_KEY" | coder secret update api-key + +# Change the environment variable target. +coder secret update api-key --env NEW_API_KEY + +# Clear the file injection target while keeping the secret. +coder secret update api-key --file "" +``` + +## List and delete secrets + +List, show, and delete your secrets with the `coder secret` CLI: + +```sh +# List all of your secrets. +coder secret list + +# Show a single secret by name. +coder secret list api-key + +# Delete a secret you no longer need. +coder secret delete api-key +``` + +Deleting a secret removes it from Coder and stops Coder from injecting it during +future workspace starts. Deleting a secret does not remove the value from +running processes or delete files that were already written in existing +workspaces. + +The list and show commands return secret metadata only. They never return the +secret value. + +For full command details, see [`coder secret`](../reference/cli/secret.md) and +the [Secrets API reference](../reference/api/secrets.md).