Skip to content

feat(secrets): add optional descriptions to workspace secrets - #6796

Merged
waleedlatif1 merged 3 commits into
stagingfrom
feat/workspace-secret-descriptions
Aug 18, 2026
Merged

feat(secrets): add optional descriptions to workspace secrets#6796
waleedlatif1 merged 3 commits into
stagingfrom
feat/workspace-secret-descriptions

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Workspace secrets can now carry an optional description so teammates know what each secret is for
  • Description field on the secret detail page, matching the integrations credential page
  • Value + description now share one Save/Discard pair and one unsaved-changes guard (two guards can't coexist — each seeds its own same-URL history entry, so Back would strand one)
  • Secrets settings search matches descriptions as well as keys
  • description exposed on GET/PUT /api/v2/secrets and in the CLI (secrets list column, secrets set --description)

No migration — credential.description already existed and every workspace secret already has a backing credential row.

Workspace-only by design: env_personal rows are per-workspace mirrors of one user-global secret, so a description saved there would exist in a single workspace, and a personal secret has no teammates to inform. The API rejects a description on personal scope rather than silently dropping it. Omitting description on PUT leaves any existing one untouched, so rotating a value can't erase it.

Type of Change

  • New feature

Testing

Tested manually. bun run check:audits (29/29), type-check, and lint all pass. 1104 tests green across app/api/v2, lib/secrets, lib/credentials, lib/environment, plus 341 CLI tests. New tests cover the v2 read projection (workspace description emitted, personal nulled), description forwarding on PUT, omission leaving it untouched, and personal scope rejected — each verified to fail without its fix.

Generated artifacts regenerated via their own scripts: packages/sim-cli/src/generated/v2-api.ts, apps/docs/openapi-v2-resources.json, apps/docs/content/docs/en/cli/{reference,secrets}.mdx.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Workspace secrets already have a backing credential row with a description
column, but nothing surfaced it. Teammates had no way to record what a
secret is for.

- Add a Description field to the secret detail page, matching the
  integrations credential page, gated on workspace-secret admin
- Fold the value and description editors into one Save/Discard pair and
  one unsaved-changes guard; two guards cannot coexist, since each seeds
  its own same-URL history entry
- Match descriptions in the secrets settings search
- Expose description on GET/PUT /api/v2/secrets and in the CLI

Descriptions are workspace-only: env_personal credential rows are
per-workspace mirrors of one user-global secret, so one saved there would
exist in a single workspace, and a personal secret has no teammates to
inform. The API rejects a description on personal scope rather than
silently dropping it, and omitting it on PUT leaves any existing
description untouched so a value rotation cannot erase it.
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 18, 2026 12:32am

Request Review

@cursor

cursor Bot commented Aug 18, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches secret write paths and v2 API contracts, but changes are scoped to optional metadata with validation on personal scope and omission-on-rotate behavior; no new secret-value exposure.

Overview
Workspace secrets can now carry an optional description (up to 500 characters) so teammates know what each key is for. Personal secrets never expose or accept descriptions—the API, credential updates, and CLI reject them rather than silently ignoring the field.

API & CLI: description is on secret metadata for GET/PUT v2 secrets and in OpenAPI. On PUT, omitting description leaves an existing note unchanged when rotating values; empty string clears it. CLI adds secrets set --description and a trailing description column on list output.

UI: The secret detail page shows a Description section for workspace secrets and merges value edits with display name/description through useCredentialDetailForm’s optional section—one Save/Discard and one unsaved-changes guard. Settings search matches description text as well as keys. Credential mutation optimistically updates the detail cache so the editor isn’t stuck dirty after save.

Backend: setWorkspaceSecret persists description on the credential row; list/present nulls description for personal scope in API responses.

Reviewed by Cursor Bugbot for commit 5d35f39. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds optional descriptions to workspace secrets across the detail UI, public v2 API, CLI, search, documentation, persistence, and cache updates. The follow-up change stabilizes the secret-value section callbacks and returned object as requested in the previous review thread.

  • Adds workspace-only secret descriptions while keeping personal-secret descriptions unavailable.
  • Combines value and description editing under one save/discard lifecycle and unsaved-changes guard.
  • Exposes descriptions through API and CLI contracts and includes them in workspace-secret search.
  • Adds optimistic detail-cache updates and focused tests for API, persistence, and rollback behavior.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/settings/components/secrets/hooks/use-secret-value.ts Stabilizes save/discard callbacks and the returned section object without leaving the previously reported issue outstanding.
apps/sim/app/workspace/[workspaceId]/components/credential-detail/hooks/use-credential-detail-form.ts Integrates an optional editable section into the shared dirty, saving, save, discard, and navigation-guard lifecycle.
apps/sim/app/workspace/[workspaceId]/settings/secrets/[credentialId]/secret-detail.tsx Adds workspace-secret description editing and unifies value and metadata actions under one form.
apps/sim/lib/secrets/application/use-cases.ts Forwards workspace descriptions while explicitly rejecting descriptions for personal secrets.
apps/sim/lib/credentials/secret-values.ts Persists supplied descriptions while preserving existing descriptions when the field is omitted.
apps/sim/lib/api/contracts/v2/secrets.ts Extends public secret contracts with nullable output descriptions and optional workspace-only update input.
packages/sim-cli/src/commands/secrets.ts Adds description output and the workspace-only set flag to the CLI.

Sequence Diagram

sequenceDiagram
  participant User
  participant UI as Secret Detail UI
  participant Form as Combined Form
  participant API as Secret/Credential API
  participant DB as Credential Store
  User->>UI: Edit value and/or description
  UI->>Form: Save combined dirty state
  Form->>API: Save value when changed
  API->>DB: Update encrypted value
  Form->>API: Save description when changed
  API->>DB: Update credential description
  DB-->>UI: Refresh secret metadata
Loading

Reviews (2): Last reviewed commit: "fix(secrets): keep the API docs example ..." | Re-trigger Greptile

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c60e92e. Configure here.

- Patch the credential detail cache optimistically on update. `onMutate`
  cancelled the detail query but only patched the lists, so a detail-backed
  editor stayed dirty after a successful save until the refetch landed —
  long enough for Discard to restore the pre-save value over the committed
  one, and for Back to open the unsaved-changes guard.
- Memoize `useSecretValue`'s returned callbacks and object, per the hook
  convention, so the composed form's save/discard stop churning per render.
- Reject a description on a personal secret in the domain layer rather than
  only at the v2 boundary. The internal credential update path accepted one
  for any type, writing data every reader hides.
- Normalize an empty description to null so the API and UI agree.
- Correct the secrets documentation, which described a Display Name field
  the detail view does not have and omitted the scope rule.
- Drop the CLI's copy of the 500-character bound; it can't import the
  contract, so a copy only drifts from the message the API already returns.
- Collapse a redundant save guard and align the description write gate with
  the render gate.

Leaves the integrations credential page byte-identical to staging.
Backward-compatibility fixes for anyone who never sets a description.

- Move the blank-to-null normalization out of the contract and into the
  route. A Zod `.transform()` on any property drops the whole request
  schema's OpenAPI examples, which had silently removed the Set Secret
  request example from the published docs.
- Append the CLI `description` column instead of inserting it before
  `updated`. `--output text` is positional, so inserting would shift every
  field an existing script cuts.
- Reject a description on a personal secret with a message that says so,
  rather than dropping the field and falling through to the generic
  "no updatable fields" error.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
waleedlatif1 merged commit 0b4d341 into staging Aug 18, 2026
30 checks passed
@waleedlatif1
waleedlatif1 deleted the feat/workspace-secret-descriptions branch August 18, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant