Skip to content

feat: harden secret command UX#141

Merged
pquerna merged 4 commits into
mainfrom
paul.querna/pr-140/secret-command-ux-followup
Jun 26, 2026
Merged

feat: harden secret command UX#141
pquerna merged 4 commits into
mainfrom
paul.querna/pr-140/secret-command-ux-followup

Conversation

@c1-squire-dev

@c1-squire-dev c1-squire-dev Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Credit

This builds directly on #140 from @paul-doordash (Paul Ganea). His branch introduced the cone secret command, the secrets API client plumbing, the SDK/vendor update, the initial create, get, and view workflows, plus FILE secret and external-recipient create support. This PR keeps that structure and layers the review/QA follow-up changes on top.

What changed

  • Align CLI terminology with the C1 Web App secrets flow: label/content type/--external-emails/view limit, one-week default expiry, and share code/share URL references.
  • Expand workflows with secret list, FILE-only secret download, secret revoke, and secret audit; get, view, revoke, and audit accept vault IDs, share codes, or C1 share URLs, and download does the same for FILE secrets.
  • Harden secret create validation and input handling: exactly one content source, JSON validation, format aliases, external email validation, recipient limits, expiry/max-view bounds, --content-file - stdin, and --user resolution by ID, exact email, or search query.
  • Stream file encryption/upload/download for large files without buffering the secret body in memory; downloads decrypt into a destination-directory temp file before atomically publishing the plaintext output.
  • Add client methods for search, revoke, audit, and user search, plus unit coverage around parsing, validation, temp-file download behavior, and file encryption.

Notes

External secret opening uses a separate web opener flow that is not present in the vendored SDK. Cone now returns a direct error for view/download of external secrets instead of surfacing the API 400; external metadata/create/revoke still work.

QA

  • go test ./cmd/cone ./pkg/client
  • go test ./...
  • make lint
  • make build
  • go mod verify
  • git diff --check
  • go mod vendor -o /tmp/cone-secret-vendor-check && diff -qr vendor /tmp/cone-secret-vendor-check
  • c1dev-okta bidirectional pass:
    • Cone-created internal text, JSON, and file secrets were opened in the C1 Web App as an allowed AgentBrowser user.
    • Cone viewed/downloaded Cone-created internal text/file secrets by vault ID/share URL; file download plaintext matched the source.
    • Cone listed, audited, and revoked QA secrets.
    • Web-created internal text secret was created in the C1 Web App for user1@conductorone.dev; a personal API credential was then created from that user's Web profile and used with Cone, and Cone successfully revealed the secret by share code.
    • Web-created external secret was created through the C1 Web App and confirmed to require the external opener flow; the current SDK path cannot reveal it through Cone.

P3GLEG and others added 3 commits June 25, 2026 12:47
Add `cone secret` with create, get, and view subcommands for managing
internal TEXT secrets. Content is encrypted client-side with Age to the
recipient returned by the API before upload; secrets support allowed-user
restrictions, expiry, and max-view burning.

Bumps conductorone-sdk-go (and re-vendors) to pull in the secrets API
support, and adds the corresponding client methods in pkg/client.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Previously `secret create` only created internal (team/SSO) TEXT secrets,
covering 4 of the 10 combinations the web UI exposes. Add the two missing
axes:

- FILE secrets via --file <path>: sets SecretType=FILE with the file's
  derived content type, size (original/pre-encryption), and name, then
  Age-encrypts the bytes and PUTs them to the upload URL from the create
  response (rather than SetTextContent).
- External recipients via --allowed-emails: routes to CreateExternal for
  email-verified recipients, mutually exclusive with --allowed-user-ids.

--content and --file are mutually exclusive. Adds CreateExternalSecret and
UploadSecretFile client methods plus tests for the new helpers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Extract input validation into validateSecretCreateInput and narrow
createSecret to a secretCreator interface so request building is testable
without a live API. Add tests for:

- validation: recipient xor, required expiry, content/file conflict
- request building: internal/external x text/file, including secret type,
  input-format presence, file metadata, and display-name/max-views

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@c1-squire-dev c1-squire-dev Bot force-pushed the paul.querna/pr-140/secret-command-ux-followup branch from 017a8cf to 68ae68e Compare June 26, 2026 05:07
Builds on the secret command introduced by Paul Ganea in PR #140.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@c1-squire-dev c1-squire-dev Bot force-pushed the paul.querna/pr-140/secret-command-ux-followup branch from 68ae68e to 2c16fb2 Compare June 26, 2026 05:12
@pquerna pquerna merged commit 004d55b into main Jun 26, 2026
2 checks passed
@pquerna pquerna deleted the paul.querna/pr-140/secret-command-ux-followup branch June 26, 2026 05:17
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.

2 participants