mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add enable/disable support for user secrets (#27537)
Users can now disable a secret to stop it from being injected into workspaces without deleting it, and re-enable it later. Disabled secrets stay visible and editable everywhere they already appear. An enabled secret must have at least one injection target; a secret with no target can be stored only while disabled. Existing target-less secrets are migrated to disabled to preserve current behavior. Support spans the REST API, SDK, CLI, dashboard, and audit log.
This commit is contained in:
@@ -43,7 +43,7 @@ We track the following resources:
|
||||
| Template<br><i>write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>active_version_id</td><td>true</td></tr><tr><td>activity_bump</td><td>true</td></tr><tr><td>allow_user_autostart</td><td>true</td></tr><tr><td>allow_user_autostop</td><td>true</td></tr><tr><td>allow_user_cancel_workspace_jobs</td><td>true</td></tr><tr><td>autostart_block_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_weeks</td><td>true</td></tr><tr><td>cors_behavior</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>default_ttl</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deprecated</td><td>true</td></tr><tr><td>description</td><td>true</td></tr><tr><td>disable_module_cache</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>failure_ttl</td><td>true</td></tr><tr><td>group_acl</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>max_port_sharing_level</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_display_name</td><td>false</td></tr><tr><td>organization_icon</td><td>false</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>organization_name</td><td>false</td></tr><tr><td>provisioner</td><td>true</td></tr><tr><td>require_active_version</td><td>true</td></tr><tr><td>time_til_autostop_notify</td><td>true</td></tr><tr><td>time_til_dormant</td><td>true</td></tr><tr><td>time_til_dormant_autodelete</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>use_classic_parameter_flow</td><td>true</td></tr><tr><td>user_acl</td><td>true</td></tr></tbody></table> |
|
||||
| TemplateVersion<br><i>create, write</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>archived</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>external_auth_providers</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>has_external_agent</td><td>false</td></tr><tr><td>id</td><td>true</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>message</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>readme</td><td>true</td></tr><tr><td>source_example_id</td><td>false</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table> |
|
||||
| User<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>false</td></tr><tr><td>chat_spend_limit_micros</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>email</td><td>true</td></tr><tr><td>github_com_user_id</td><td>false</td></tr><tr><td>hashed_one_time_passcode</td><td>false</td></tr><tr><td>hashed_password</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>is_service_account</td><td>true</td></tr><tr><td>is_system</td><td>true</td></tr><tr><td>last_seen_at</td><td>false</td></tr><tr><td>login_type</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>one_time_passcode_expires_at</td><td>true</td></tr><tr><td>quiet_hours_schedule</td><td>true</td></tr><tr><td>rbac_roles</td><td>true</td></tr><tr><td>status</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>username</td><td>true</td></tr></tbody></table> |
|
||||
| UserSecret<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>description</td><td>true</td></tr><tr><td>env_name</td><td>true</td></tr><tr><td>file_path</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>value</td><td>true</td></tr><tr><td>value_key_id</td><td>false</td></tr></tbody></table> |
|
||||
| UserSecret<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>description</td><td>true</td></tr><tr><td>enabled</td><td>true</td></tr><tr><td>env_name</td><td>true</td></tr><tr><td>file_path</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>value</td><td>true</td></tr><tr><td>value_key_id</td><td>false</td></tr></tbody></table> |
|
||||
| UserSkill<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>content</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>description</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table> |
|
||||
| WorkspaceBuild<br><i>start, stop</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>build_number</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>daily_cost</td><td>false</td></tr><tr><td>deadline</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>has_external_agent</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>initiator_by_avatar_url</td><td>false</td></tr><tr><td>initiator_by_name</td><td>false</td></tr><tr><td>initiator_by_username</td><td>false</td></tr><tr><td>initiator_id</td><td>false</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>max_deadline</td><td>false</td></tr><tr><td>notified_autostop_deadline</td><td>false</td></tr><tr><td>reason</td><td>false</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>template_version_preset_id</td><td>false</td></tr><tr><td>transition</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>workspace_id</td><td>false</td></tr></tbody></table> |
|
||||
| WorkspaceProxy<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>derp_enabled</td><td>true</td></tr><tr><td>derp_only</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>region_id</td><td>true</td></tr><tr><td>token_hashed_secret</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>url</td><td>true</td></tr><tr><td>version</td><td>true</td></tr><tr><td>wildcard_hostname</td><td>true</td></tr></tbody></table> |
|
||||
|
||||
@@ -49,7 +49,8 @@ Users can view their public key in their account settings:
|
||||
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. User secret values are covered by
|
||||
workspace. A secret can be disabled, in which case it is stored but not injected
|
||||
until it is re-enabled. User secret values are covered by
|
||||
[Database Encryption](./database-encryption.md) when it is enabled. See the
|
||||
[User secrets guide](../../user-guides/user-secrets.md).
|
||||
|
||||
|
||||
Generated
+28
-22
@@ -5117,6 +5117,7 @@ This is required on creation to enable a user-flow of validating a template work
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"name": "string",
|
||||
@@ -5126,13 +5127,14 @@ This is required on creation to enable a user-flow of validating a template work
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|--------|----------|--------------|-------------|
|
||||
| `description` | string | false | | |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `value` | string | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|---------|----------|--------------|-------------|
|
||||
| `description` | string | false | | |
|
||||
| `enabled` | boolean | false | | |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `value` | string | false | | |
|
||||
|
||||
## codersdk.CreateUserSkillRequest
|
||||
|
||||
@@ -13833,6 +13835,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"value": "string"
|
||||
@@ -13841,12 +13844,13 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|--------|----------|--------------|-------------|
|
||||
| `description` | string | false | | |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `value` | string | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|---------|----------|--------------|-------------|
|
||||
| `description` | string | false | | |
|
||||
| `enabled` | boolean | false | | |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `value` | string | false | | |
|
||||
|
||||
## codersdk.UpdateUserSkillRequest
|
||||
|
||||
@@ -14532,6 +14536,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
@@ -14542,15 +14547,16 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|--------|----------|--------------|-------------|
|
||||
| `created_at` | string | false | | |
|
||||
| `description` | string | false | | |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `id` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `updated_at` | string | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------|---------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `created_at` | string | false | | |
|
||||
| `description` | string | false | | |
|
||||
| `enabled` | boolean | false | | Enabled controls whether the secret is injected into workspaces. Disabled secrets remain visible and editable, but are not added to the agent manifest, so they are not exposed as environment variables or written to secret files. |
|
||||
| `env_name` | string | false | | |
|
||||
| `file_path` | string | false | | |
|
||||
| `id` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `updated_at` | string | false | | |
|
||||
|
||||
## codersdk.UserSkill
|
||||
|
||||
|
||||
Generated
+29
-20
@@ -28,6 +28,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/secrets \
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
@@ -47,16 +48,17 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/secrets \
|
||||
|
||||
Status Code **200**
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|-----------------|-------------------|----------|--------------|-------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» created_at` | string(date-time) | false | | |
|
||||
| `» description` | string | false | | |
|
||||
| `» env_name` | string | false | | |
|
||||
| `» file_path` | string | false | | |
|
||||
| `» id` | string(uuid) | false | | |
|
||||
| `» name` | string | false | | |
|
||||
| `» updated_at` | string(date-time) | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|-----------------|-------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» created_at` | string(date-time) | false | | |
|
||||
| `» description` | string | false | | |
|
||||
| `» enabled` | boolean | false | | Enabled controls whether the secret is injected into workspaces. Disabled secrets remain visible and editable, but are not added to the agent manifest, so they are not exposed as environment variables or written to secret files. |
|
||||
| `» env_name` | string | false | | |
|
||||
| `» file_path` | string | false | | |
|
||||
| `» id` | string(uuid) | false | | |
|
||||
| `» name` | string | false | | |
|
||||
| `» updated_at` | string(date-time) | false | | |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
@@ -79,6 +81,7 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/secrets \
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"name": "string",
|
||||
@@ -101,6 +104,7 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/secrets \
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
@@ -156,6 +160,7 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/secrets/batch \
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
@@ -178,16 +183,17 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/secrets/batch \
|
||||
|
||||
Status Code **201**
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|-----------------|-------------------|----------|--------------|-------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» created_at` | string(date-time) | false | | |
|
||||
| `» description` | string | false | | |
|
||||
| `» env_name` | string | false | | |
|
||||
| `» file_path` | string | false | | |
|
||||
| `» id` | string(uuid) | false | | |
|
||||
| `» name` | string | false | | |
|
||||
| `» updated_at` | string(date-time) | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|-----------------|-------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» created_at` | string(date-time) | false | | |
|
||||
| `» description` | string | false | | |
|
||||
| `» enabled` | boolean | false | | Enabled controls whether the secret is injected into workspaces. Disabled secrets remain visible and editable, but are not added to the agent manifest, so they are not exposed as environment variables or written to secret files. |
|
||||
| `» env_name` | string | false | | |
|
||||
| `» file_path` | string | false | | |
|
||||
| `» id` | string(uuid) | false | | |
|
||||
| `» name` | string | false | | |
|
||||
| `» updated_at` | string(date-time) | false | | |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
@@ -219,6 +225,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
@@ -281,6 +288,7 @@ curl -X PATCH http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"value": "string"
|
||||
@@ -303,6 +311,7 @@ curl -X PATCH http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"description": "string",
|
||||
"enabled": true,
|
||||
"env_name": "string",
|
||||
"file_path": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
|
||||
Generated
+8
-6
@@ -39,9 +39,11 @@ coder secret
|
||||
|
||||
## Subcommands
|
||||
|
||||
| Name | Purpose |
|
||||
|-------------------------------------------|-----------------------------------|
|
||||
| [<code>create</code>](./secret_create.md) | Create a secret |
|
||||
| [<code>update</code>](./secret_update.md) | Update a secret |
|
||||
| [<code>list</code>](./secret_list.md) | List secrets, or show one by name |
|
||||
| [<code>delete</code>](./secret_delete.md) | Delete a secret |
|
||||
| Name | Purpose |
|
||||
|---------------------------------------------|---------------------------------------------------|
|
||||
| [<code>create</code>](./secret_create.md) | Create a secret |
|
||||
| [<code>update</code>](./secret_update.md) | Update a secret |
|
||||
| [<code>enable</code>](./secret_enable.md) | Enable a secret so it is injected into workspaces |
|
||||
| [<code>disable</code>](./secret_disable.md) | Disable a secret without removing it |
|
||||
| [<code>list</code>](./secret_list.md) | List secrets, or show one by name |
|
||||
| [<code>delete</code>](./secret_delete.md) | Delete a secret |
|
||||
|
||||
Generated
+9
@@ -48,3 +48,12 @@ Name of the workspace environment variable that this secret will set.
|
||||
| Type | <code>string</code> |
|
||||
|
||||
Workspace file path where this secret will be written. Must start with ~/ or /.
|
||||
|
||||
### --enabled
|
||||
|
||||
| | |
|
||||
|---------|-------------------|
|
||||
| Type | <code>bool</code> |
|
||||
| Default | <code>true</code> |
|
||||
|
||||
Whether the secret is injected into workspaces. An enabled secret must set --env or --file; pass --enabled=false to store a secret without injecting it.
|
||||
|
||||
Generated
+10
@@ -0,0 +1,10 @@
|
||||
<!-- DO NOT EDIT | GENERATED CONTENT -->
|
||||
# secret disable
|
||||
|
||||
Disable a secret without removing it
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
coder secret disable <name>
|
||||
```
|
||||
Generated
+10
@@ -0,0 +1,10 @@
|
||||
<!-- DO NOT EDIT | GENERATED CONTENT -->
|
||||
# secret enable
|
||||
|
||||
Enable a secret so it is injected into workspaces
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
coder secret enable <name>
|
||||
```
|
||||
Generated
+4
-4
@@ -23,10 +23,10 @@ Secret values are omitted from the output.
|
||||
|
||||
### -c, --column
|
||||
|
||||
| | |
|
||||
|---------|---------------------------------------------------------------|
|
||||
| Type | <code>[created\|name\|updated\|env\|file\|description]</code> |
|
||||
| Default | <code>name,created,updated,env,file,description</code> |
|
||||
| | |
|
||||
|---------|------------------------------------------------------------------------|
|
||||
| Type | <code>[created\|name\|updated\|env\|file\|enabled\|description]</code> |
|
||||
| Default | <code>name,created,updated,env,file,enabled,description</code> |
|
||||
|
||||
Columns to display in table output.
|
||||
|
||||
|
||||
Generated
+9
-1
@@ -12,7 +12,7 @@ coder secret update [flags] <name>
|
||||
## Description
|
||||
|
||||
```console
|
||||
At least one of --value, --description, --env, or --file must be specified. Provide the secret value by at most one of --value or non-interactive stdin (pipe or redirect).
|
||||
At least one of --value, --description, --env, --file, or --enabled must be specified. Provide the secret value by at most one of --value or non-interactive stdin (pipe or redirect).
|
||||
```
|
||||
|
||||
## Options
|
||||
@@ -48,3 +48,11 @@ Name of the workspace environment variable that this secret will set. Pass an em
|
||||
| Type | <code>string</code> |
|
||||
|
||||
Workspace file path where this secret will be written. Must start with ~/ or /. Pass an empty string to clear it.
|
||||
|
||||
### --enabled
|
||||
|
||||
| | |
|
||||
|------|-------------------|
|
||||
| Type | <code>bool</code> |
|
||||
|
||||
Whether the secret is injected into workspaces. An enabled secret must keep at least one of --env or --file; pass --enabled=false to stop injecting it without deleting it.
|
||||
|
||||
@@ -11,9 +11,19 @@ Each user secret has:
|
||||
- A value, which contains the sensitive content.
|
||||
- An optional description.
|
||||
- An optional environment variable target, file target, or both.
|
||||
- An enabled flag that controls whether Coder injects the secret into your
|
||||
workspaces.
|
||||
|
||||
A secret without an environment variable target or file target is stored, but is
|
||||
not injected into workspaces.
|
||||
An enabled secret must have at least one of an environment variable target or a
|
||||
file target. To keep a secret stored without injecting it, disable it
|
||||
(`enabled = false`) instead of clearing both targets. A create or update that
|
||||
would leave an enabled secret with no target is rejected with a 400 and
|
||||
directs you to disable the secret instead.
|
||||
|
||||
Disabled secrets stay visible and editable in the CLI, REST API, and dashboard,
|
||||
but are not injected into workspaces. Secrets that predate the enabled flag and
|
||||
had no target were migrated to disabled, so they show as disabled and need a
|
||||
target before you can enable them.
|
||||
|
||||
User secrets apply to all workspaces that you own.
|
||||
|
||||
@@ -39,6 +49,12 @@ time the workspace agent reconnects to Coder, for example after the workspace
|
||||
or the agent restarts. To pick up a change to a secret while a workspace is
|
||||
running, restart the workspace.
|
||||
|
||||
Disabling a secret (`coder secret disable`) stops it from being injected from
|
||||
the next workspace start onward. Running sessions keep values that were already
|
||||
injected until the agent manifest is refetched, which happens on workspace
|
||||
restart. Disabling does not remove a file that was already written; the same
|
||||
"Coder never deletes secret files" rule below applies.
|
||||
|
||||
### Environment variable secrets
|
||||
|
||||
Coder injects environment variable secrets into every new shell, terminal,
|
||||
@@ -46,11 +62,13 @@ app, SSH session, and startup script that you start in your workspace.
|
||||
Existing shells and processes keep the environment they were given when they
|
||||
started.
|
||||
|
||||
| If you... | ...then in your workspace |
|
||||
|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Create or update an env secret | The change applies after the next workspace start. Until then, your running workspace continues to use the secrets it had when it last started. |
|
||||
| Rename the env var (`--env NEW_NAME`) | After the next workspace start, new shells get `NEW_NAME` and the old name is no longer set. |
|
||||
| Clear the env target (`--env ""`) or delete the secret | After the next workspace start, the variable is no longer injected. |
|
||||
| If you... | ...then in your workspace |
|
||||
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Create or update an env secret | The change applies after the next workspace start. Until then, your running workspace continues to use the secrets it had when it last started. |
|
||||
| Rename the env var (`--env NEW_NAME`) | After the next workspace start, new shells get `NEW_NAME` and the old name is no longer set. |
|
||||
| Clear the env target (`--env ""`) | Only succeeds if the secret keeps its file target or is disabled in the same request; otherwise the request is rejected with a 400. After the next workspace start, the variable is no longer injected. |
|
||||
| Disable the secret (`coder secret disable`) | After the next workspace start, the variable is no longer injected. Running sessions keep the value until the agent manifest is refetched (workspace restart). |
|
||||
| Delete the secret | After the next workspace start, the variable is no longer injected. |
|
||||
|
||||
To pick up a change in a long-running shell or app started after a restart,
|
||||
restart that shell or app.
|
||||
@@ -62,11 +80,13 @@ starts, before any startup scripts run. New parent directories are created as
|
||||
needed. If the file already exists, Coder overwrites the contents and leaves
|
||||
the existing permissions alone.
|
||||
|
||||
| If you... | ...then in your workspace |
|
||||
|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Create or update a file secret | The file is written or overwritten at the next workspace start. |
|
||||
| Change the file path (`--file NEW_PATH`) | At the next workspace start, a file is written at `NEW_PATH`. **The file at the previous path stays on disk with its old value.** |
|
||||
| Clear the file target (`--file ""`) or delete the secret | **The previously-written file stays on disk with its last value.** |
|
||||
| If you... | ...then in your workspace |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Create or update a file secret | The file is written or overwritten at the next workspace start. |
|
||||
| Change the file path (`--file NEW_PATH`) | At the next workspace start, a file is written at `NEW_PATH`. **The file at the previous path stays on disk with its old value.** |
|
||||
| Clear the file target (`--file ""`) | Only succeeds if the secret keeps its env target or is disabled in the same request; otherwise the request is rejected with a 400. **The previously-written file stays on disk with its last value.** |
|
||||
| Disable the secret (`coder secret disable`) | The file is no longer written at the next workspace start. **The previously-written file stays on disk with its last value.** |
|
||||
| Delete the secret | **The previously-written file stays on disk with its last value.** |
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Coder never deletes secret files it has written for you. If you remove a
|
||||
@@ -120,7 +140,10 @@ You can create, edit, and delete user secrets from the Coder dashboard:
|
||||
|
||||
From this page you can add a new secret, update an existing secret's value,
|
||||
description, or environment variable and file targets, and delete secrets you
|
||||
no longer need.
|
||||
no longer need. Each row has an enable/disable toggle that controls whether
|
||||
Coder injects the secret. A secret with no environment variable or file target
|
||||
cannot be enabled from the dashboard; the toggle is disabled with a tooltip,
|
||||
mirroring the API invariant that an enabled secret must have a target.
|
||||
|
||||
The rest of this guide shows the equivalent CLI commands. The same behaviors,
|
||||
limits, and injection rules apply whether you manage secrets from the
|
||||
@@ -194,11 +217,21 @@ want to store a trailing newline:
|
||||
echo -n "$API_KEY" | coder secret create api-key --env API_KEY
|
||||
```
|
||||
|
||||
### Create a disabled secret
|
||||
|
||||
An enabled secret must set `--env`, `--file`, or both. To store a secret
|
||||
without injecting it, pass `--enabled=false`. You can add a target and enable
|
||||
it later with `coder secret enable`.
|
||||
|
||||
```sh
|
||||
echo -n "$API_KEY" | coder secret create api-key --enabled=false
|
||||
```
|
||||
|
||||
## 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.
|
||||
`--env`, `--file`, or `--enabled` must be specified.
|
||||
|
||||
```sh
|
||||
# Update a secret value.
|
||||
@@ -207,10 +240,26 @@ 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.
|
||||
# Clear the file injection target while keeping the secret. This only
|
||||
# succeeds because api-key still has an environment variable target; a
|
||||
# request that clears the last target of an enabled secret is rejected.
|
||||
coder secret update api-key --file ""
|
||||
```
|
||||
|
||||
### Enable and disable a secret
|
||||
|
||||
Disable a secret to stop injecting it without deleting it, then enable it again
|
||||
to resume. Enabling a secret that has no target is rejected; add a target
|
||||
first.
|
||||
|
||||
```sh
|
||||
# Stop injecting a secret without deleting it.
|
||||
coder secret disable api-key
|
||||
|
||||
# Resume injection.
|
||||
coder secret enable api-key
|
||||
```
|
||||
|
||||
## List and delete secrets
|
||||
|
||||
List, show, and delete your secrets with the `coder secret` CLI:
|
||||
@@ -227,7 +276,8 @@ coder secret delete api-key
|
||||
```
|
||||
|
||||
The list and show commands return secret metadata only. They never return the
|
||||
secret value.
|
||||
secret value. The `coder secret list` table includes an `enabled` column so you
|
||||
can see which secrets are currently injected.
|
||||
|
||||
See [How your secrets reach a workspace](#how-your-secrets-reach-a-workspace)
|
||||
for what happens to running workspaces when you delete a secret.
|
||||
|
||||
Reference in New Issue
Block a user