diff --git a/.agents/skills/agent-secret/SKILL.md b/.agents/skills/agent-secret/SKILL.md index 925ad41..5430c0e 100644 --- a/.agents/skills/agent-secret/SKILL.md +++ b/.agents/skills/agent-secret/SKILL.md @@ -1,13 +1,13 @@ --- name: agent-secret -description: Use Agent Secret safely in a project, including general command execution, project profiles, env-file use, 1Password migration, and verification without exposing secret values. +description: Use Agent Secret safely in a project, including 1Password and Bitwarden Secrets Manager refs, project profiles, env-file use, migration, and verification without exposing secret values. --- # Agent Secret Use this skill when a project needs secrets through Agent Secret, when an agent needs to understand how to run `agent-secret`, or when migrating direct -1Password CLI usage to Agent Secret. +1Password or Bitwarden Secrets Manager CLI usage to Agent Secret. ## Goals @@ -15,17 +15,19 @@ needs to understand how to run `agent-secret`, or when migrating direct - Keep secret refs in command flags, env files, or `agent-secret.yml`; never store resolved values. - Use project-local profiles for repeated multi-secret workflows. -- Migrate direct `op` usage to `agent-secret exec` while preserving command - behavior. +- Migrate direct provider CLI usage to `agent-secret exec` while preserving + command behavior. - Inspect 1Password item metadata when field names are unknown, without revealing secret values. - Verify real behavior with safe checks that do not leak secrets. ## Safety Rules -- Do not run `op` unless the user explicitly asks for a diagnostic that requires - it. +- Do not run `op` or `bws` unless the user explicitly asks for a diagnostic + that requires the provider CLI. - Never echo, log, diff, commit, or write resolved secret values. +- Never ask the user to paste a Bitwarden access token into chat, an issue, or + a pull request. Use interactive token install instead. - Avoid `env`, `printenv`, `set`, shell tracing (`set -x`), and debug logs in secret-backed runs. - Do not add long-lived plaintext `.env` files as a shortcut. @@ -55,6 +57,15 @@ agent-secret exec \ -- terraform plan ``` +Run a command with a Bitwarden Secrets Manager secret: + +```bash +agent-secret exec \ + --reason "Deploy with Bitwarden-managed API token" \ + --secret API_TOKEN=bws://work/ \ + -- deploy-tool +``` + Run a command with a project profile: ```bash @@ -100,6 +111,30 @@ shell strings. Normal `exec` does not have JSON output because child stdin/stdout/stderr pass through unchanged; only `exec --dry-run --json` returns JSON. +## Provider Setup + +For 1Password refs, make sure the 1Password desktop app is signed in, unlocked, +and has Developer Tools SDK integration enabled. `agent-secret doctor` reports +non-secret diagnostic state. + +For Bitwarden Secrets Manager refs, install the official Bitwarden-signed `bws` +CLI, then install a local token alias in Agent Secret: + +```bash +agent-secret bitwarden secrets-manager token status --alias work +agent-secret bitwarden secrets-manager token install --alias work +``` + +The install command prompts with hidden terminal input. For non-interactive +setup scripts, pipe the token to the stdin-only install form: + +```bash +agent-secret bitwarden secrets-manager token install --alias work --from-stdin +``` + +Do not echo the token or put it in shell history. The approved child command +receives only the resolved secret value, never the Bitwarden access token. + ## Project Profiles Create `agent-secret.yml` or `.agent-secret.yml` at the project root when a @@ -111,6 +146,11 @@ version: 1 account: my.1password.com default_profile: terraform +sources: + bitwarden: + work-secrets: + token_alias: work + profiles: cloudflare: reason: Terraform DNS management @@ -131,6 +171,14 @@ profiles: ttl: 10m secrets: CADDY_TOKEN: op://Example/Caddy/token + + deploy: + reason: Deploy with Bitwarden-managed API token + ttl: 10m + secrets: + API_TOKEN: + ref: bws:// + source: work-secrets ``` Use nested profiles to avoid duplicated secret lists. Use `--only` when a @@ -149,6 +197,19 @@ shell environment when a project needs a specific 1Password account. Use `--account` for one-off wrappers or env-file migrations that should not require a project config yet. +`account` is only for 1Password account selection. For Bitwarden Secrets +Manager, use a `sources.bitwarden` entry and refer to it with `source` or with a +source-qualified ref such as `bws://work-secrets/`. `source` is +Agent Secret terminology for a configured place to resolve a secret ref; it is +not a Bitwarden UI object. + +Bare `bws://` refs are valid only when there is a single +unambiguous Bitwarden Secrets Manager source. If a profile config has multiple +Bitwarden sources, set `source` on the secret or use +`bws:///`. If no project source is configured, a bare +Bitwarden ref can use the single locally installed token alias; multiple local +token aliases require the source-qualified form. + ## Env Files Use `--env-file` as the migration path for commands that currently use @@ -159,9 +220,9 @@ agent-secret exec --reason "Deploy application" --env-file .env.deploy -- \ npm run deploy ``` -Entries whose values start with `op://` become approved secret refs. Other -entries are passed only to the child command as plain environment variables. -Later `--env-file` values override earlier files. +Entries whose values start with `op://` or `bws://` become approved secret refs. +Other entries are passed only to the child command as plain environment +variables. Later `--env-file` values override earlier files. Use `--only` when one env file contains refs for multiple command surfaces: @@ -175,8 +236,9 @@ agent-secret exec \ ``` `--only` filters profile and env-file secret refs. It does not filter deliberate -one-off `--secret` flags. If an env file has no `op://` refs, skip Agent Secret -and run the command directly instead of using it as a generic dotenv runner. +one-off `--secret` flags. If an env file has no `op://` or `bws://` refs, skip +Agent Secret and run the command directly instead of using it as a generic +dotenv runner. ## Text File Secrets @@ -197,6 +259,9 @@ the existing script expects a file path, prefer passing contents to its env-first path and let the approved child process create any temp file it already owns. +Bitwarden Secrets Manager v1 resolves secret values only. It does not provide +an Agent Secret file-attachment mode. + ## Item Metadata Inspection Use `agent-secret item describe` when you know the 1Password item but need a @@ -231,13 +296,19 @@ does not already define the intended account or when an explicit one-off override is needed. Do not fall back to `op item get` unless the user explicitly asks for that diagnostic. -## Migrating From 1Password CLI +There is no equivalent Agent Secret metadata inspection command for Bitwarden +Secrets Manager in v1. Use the Bitwarden UI or existing non-secret project docs +to identify the secret UUID; do not call `bws secret get` just to discover or +verify a value. -Inventory direct 1Password usage: +## Migrating From Provider CLIs + +Inventory direct provider CLI usage: ```bash rg -n '\bop\b|op://|1Password' . rg -n 'ONEPASSWORD|OP_ACCOUNT|OP_SERVICE_ACCOUNT|OP_CONNECT' . +rg -n '\bbws\b|bws://|BWS_ACCESS_TOKEN|BITWARDEN' . ``` Classify each call site: @@ -254,6 +325,12 @@ Classify each call site: remove them when a profile can express the same secret set. - Static `op://` catalogs: keep them as references only if they are useful documentation; they are not instructions to call `op`. +- `bws secret get` value loaders: replace with an env alias delivered by + `agent-secret exec`. +- Scripts that export `BWS_ACCESS_TOKEN`: replace token handling with a local + Agent Secret token alias and keep the Bitwarden token out of child commands. +- Static `bws://` catalogs: keep them as references only if they are useful + documentation; they are not instructions to call `bws`. Pick the smallest useful migration surface first: a plan, dry-run, deploy, or validation command that already expects env vars and can be verified without @@ -272,6 +349,15 @@ agent-secret exec \ -- terraform plan ``` +Replace direct Bitwarden value loading with an approved env alias: + +```bash +agent-secret exec \ + --reason "Deploy with Bitwarden-managed API token" \ + --secret API_TOKEN=bws://work/ \ + -- deploy-tool +``` + Replace `op run`: ```bash @@ -305,6 +391,9 @@ exec agent-secret exec --profile deploy -- "$@" Do not replace a direct secret read with a command that prints the value. Agent Secret intentionally has no raw `read` command for secret values. +Do not migrate Bitwarden Password Manager `bw` vault automation to `bws://`. +Agent Secret v1 supports Bitwarden Secrets Manager only. + ## Verification Before reporting success, prove the migrated path works: @@ -332,14 +421,39 @@ agent-secret exec \ -- sh -c 'test -n "${TOKEN:-}"' ``` +For smoke tests where presence is not enough, print only bounded metadata such +as length and a short hash: + +```bash +agent-secret exec \ + --reason "Check Bitwarden secret delivery" \ + --secret TOKEN=bws://work/ \ + -- /usr/bin/python3 -c ' +import hashlib, os +v = os.environ["TOKEN"].encode() +digest = hashlib.sha256(v).hexdigest()[:12] +print(f"len={len(v)} sha256={digest}") +' +``` + ## Troubleshooting - `agent-secret doctor` shows non-secret local diagnostics. - `agent-secret daemon status` confirms whether the daemon is running. - `agent-secret daemon stop` clears daemon-owned in-memory approvals and cached values. +- `agent-secret bitwarden secrets-manager token status --alias ALIAS` checks + whether a Bitwarden token alias exists without printing the token. +- `agent-secret bitwarden secrets-manager token install --alias ALIAS` + reinstalls a Bitwarden token alias with hidden input. Use it when Keychain + access requires repair. - `agent-secret skill-install` installs or repairs this skill in `~/.agents/skills/agent-secret`. +- If Bitwarden resolution says the `bws` CLI is unavailable, install the + official Bitwarden-signed `bws` CLI or fix the system-owned helper path. +- If a bare `bws://` ref is ambiguous, add a project + `sources.bitwarden` entry and set `source`, or use + `bws:///`. - If the approval UI shows the wrong command or reason, fix the wrapper before approving. - If a command has no safe way to prove consumption without printing a value, @@ -351,6 +465,6 @@ When done, report: - Files changed. - Commands migrated. -- Secret aliases and `op://` refs involved, never resolved values. +- Secret aliases and `op://` or `bws://` refs involved, never resolved values. - Verification commands and outcomes. -- Any call sites intentionally left on direct 1Password access and why. +- Any call sites intentionally left on direct provider CLI access and why. diff --git a/CHANGELOG.md b/CHANGELOG.md index c050282..f556c9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,11 @@ version numbers for public releases. - Added a public docs page for install, 1Password setup, Bitwarden Secrets Manager setup, project profiles, validation, troubleshooting, and FAQ. +- Updated the bundled coding-agent skill with Bitwarden Secrets Manager setup, + `bws://` reference, source-selection, verification, and troubleshooting + guidance. +- Updated the release checklist to require a bundled coding-agent skill audit + whenever app functionality changes. ## [0.0.16] - 2026-06-07 diff --git a/docs/release-process.md b/docs/release-process.md index 7f008a8..672c25f 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -42,21 +42,28 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. git status -sb ``` -2. Review `CHANGELOG.md` for the target version. The section should be +1. Review `CHANGELOG.md` for the target version. The section should be practical release-note material, not a raw commit log. -3. Replace `Pending` with the release date in `YYYY-MM-DD` form. +1. Audit user-facing docs and the bundled coding-agent skill for every app + functionality change before tagging. If CLI commands, secret reference + schemes, setup flows, diagnostics, migration paths, or safe verification + guidance changed, update `.agents/skills/agent-secret/SKILL.md` in the same + release. If no skill update is needed, record why in the release prep issue + or release PR. -4. Run the local checks: +1. Replace `Pending` with the release date in `YYYY-MM-DD` form. + +1. Run the local checks: ```bash mise run lint mise run build ``` -5. Commit and push the changelog date update. +1. Commit and push the changelog date update. -6. Create and push the release tag: +1. Create and push the release tag: ```bash version="0.0.1" @@ -68,7 +75,7 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. current `origin/main` commit before validating signing secrets or building release artifacts. -7. Watch the tag-triggered CI run until `Draft Release Artifacts` passes. +1. Watch the tag-triggered CI run until `Draft Release Artifacts` passes. The job rejects tags whose changelog section is missing, still marked `Pending`, or empty. It should create or update a draft GitHub Release with notes from the dated changelog section and these assets: @@ -78,7 +85,7 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. checksums.txt ``` -8. Download the draft release assets and verify the DMG: +1. Download the draft release assets and verify the DMG: ```bash shasum -a 256 -c checksums.txt @@ -92,7 +99,7 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. hdiutil verify "$artifact" ``` -9. Mount the DMG and verify the app inside: +1. Mount the DMG and verify the app inside: ```bash hdiutil attach -readonly -nobrowse \ @@ -117,7 +124,7 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. hdiutil detach "$mount_dir" ``` -10. Confirm the draft release notes match the dated changelog section for the +1. Confirm the draft release notes match the dated changelog section for the tag: ```bash @@ -125,16 +132,16 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. gh release view "v$version" --json body --jq .body ``` -11. Publish the draft release only after CI and local artifact verification +1. Publish the draft release only after CI and local artifact verification pass: ```bash gh release edit "v$version" --draft=false ``` -12. Confirm the published release page shows the expected notes and assets. +1. Confirm the published release page shows the expected notes and assets. -13. Update the Homebrew cask to the published release before announcing the +1. Update the Homebrew cask to the published release before announcing the release. Use the SHA-256 digest for the `Agent-Secret-vX.Y.Z-macos-arm64.dmg` asset: @@ -157,7 +164,7 @@ lives in `AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh`. git push origin main ``` -14. Verify the public Homebrew upgrade path from a fresh tap update: +1. Verify the public Homebrew upgrade path from a fresh tap update: ```bash brew update diff --git a/scripts/release/test-release-docs.sh b/scripts/release/test-release-docs.sh index 9940acd..bd3a1a1 100755 --- a/scripts/release/test-release-docs.sh +++ b/scripts/release/test-release-docs.sh @@ -103,6 +103,8 @@ require_release_process_text "scripts/release/extract-release-notes.sh" require_release_process_text "AGENT_SECRET_IN_MISE=1 scripts/release/test-release-notes.sh" require_release_process_text "scripts/release/check-release-signing-env.sh" require_release_process_text "scripts/release/prepare-bootstrap-scripts.sh" +require_release_process_text ".agents/skills/agent-secret/SKILL.md" +require_release_process_text "Audit user-facing docs and the bundled coding-agent skill" require_release_process_text "--require-production-signing" require_release_process_text "Tag-triggered GitHub releases require production" require_release_process_text "Developer ID Application: Oleksiy Kovyrin (B6L7QLWTZW)"