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:
Zach
2026-07-28 09:58:33 -06:00
committed by GitHub
parent 3c61a9a939
commit 85984ff142
56 changed files with 1391 additions and 186 deletions
+11 -1
View File
@@ -2103,6 +2103,10 @@ func TestUserSecretsTelemetry(t *testing.T) {
}, func(p *database.CreateUserSecretParams) {
p.EnvName = ""
p.FilePath = ""
// A target-less secret must be disabled to satisfy the
// user_secrets_enabled_requires_target constraint. Disabled
// secrets are still counted in the telemetry breakdown.
p.Enabled = false
})
_, snap := collectSnapshot(ctx, t, db, nil)
@@ -2149,9 +2153,12 @@ func TestUserSecretsTelemetry(t *testing.T) {
// Clear EnvName and FilePath so the unique
// (user_id, env_name) and (user_id, file_path)
// indexes don't collide across multiple secrets
// for the same user.
// for the same user. Target-less secrets must be
// disabled to satisfy the
// user_secrets_enabled_requires_target constraint.
p.EnvName = ""
p.FilePath = ""
p.Enabled = false
})
}
}
@@ -2261,6 +2268,9 @@ func TestUserSecretsTelemetry(t *testing.T) {
}, func(p *database.CreateUserSecretParams) {
p.EnvName = ""
p.FilePath = ""
// Target-less secrets must be disabled to satisfy the
// user_secrets_enabled_requires_target constraint.
p.Enabled = false
})
clock := quartz.NewMock(t)