feat: add cone secret command for internal text secrets#140
feat: add cone secret command for internal text secrets#140paul-doordash wants to merge 5 commits into
Conversation
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>
FILE secrets could be created but not read back via the CLI (view only handles TEXT and errors on files). Add `secret download <vault-id>`, which generates an ephemeral Age identity, has the server re-encrypt the file to it, downloads from the returned capability URL, decrypts, and writes to --out (or the secret's original filename). Adds the DownloadSecretFile client method and a decryptBytesFromAgeIdentity helper (raw bytes, no base64), with roundtrip tests. Verified end-to-end against a live tenant: upload then download returns byte-identical content. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Two UX fixes found while testing every create path against a live tenant: - normalizeExpiresIn parses human durations (1h, 30m, 3600s), enforces the API's [1h, 720h] range client-side, and emits the protobuf "<seconds>s" format the API requires — so "1h" now works instead of returning an opaque 400, and out-of-range/bad values fail fast without a round-trip. - view/download now detect externally shared secrets up-front and explain they must be opened via their share URL (printing it), rather than leaking the raw "use opener service for external secrets" 400. Adds normalizeExpiresIn tests; verified both paths live. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Thanks @paul-doordash for putting #140 together. I opened a follow-up PR at #141 that keeps your commits and structure intact and layers on the review/QA pass we discussed. The follow-up adds C1 Web App terminology alignment, stricter create validation, share-code/share-URL refs, streaming file upload/download with destination-local temp decrypt, Credit in the PR body calls out that this builds directly on your original implementation. Thanks again for building the foundation for the secrets command. |
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>
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>
* feat: add cone secret command for internal text secrets 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> * feat: support FILE secrets and external recipients in cone secret create 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> * test: cover all secret create combinations and input validation 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> * feat: harden secret command UX 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> --------- Co-authored-by: Pegleg <pegleg@linux.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Paul Querna <paul.querna@conductorone.com> Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
|
Thank you for the contribution -- commits merged via #141 which stacked a couple fixes/changes on top |
Adds
cone secretwithcreate,get, andviewsubcommands for managing internal TEXT secrets.conductorone-sdk-go(and re-vendors) for the secrets API, and adds the corresponding client methods inpkg/client.🤖 Generated with Claude Code