# Account secret setup guide

Use the hosted **`/account/secrets/new`** page whenever the user needs to enter
a secret value such as an API key or personal access token. The agent must never
see the secret value.

If the secret will power a downstream playbook or playbook app, open
`search({ entity: "integration_bootstrap:guide" })` before building that
playbook. For the common non-OAuth path after bootstrap, open
`search({ entity: "secret_backed_integration:guide" })`. This guide covers the
secret-collection step only.

## When to use `/account/secrets/new`

Use it when:

- the user must provide a sensitive value
- a named secret needed for `fetch` placeholders or a named lookup (for example
  `secretJwtSign`) is missing
- the user needs to rotate a stored secret value

Do **not** ask the user to paste secrets into chat.

## URL format

Provide the user a URL like:

`https://<your-kody-origin>/account/secrets/new?name=exampleApiKey&description=Example%20API%20key&expiresAt=2026-12-01T00:00:00.000Z&allowedHosts=api.example.com&scope=user&allowedPlaybooks=pkg_123`

When `name` is present, the page focuses and scrolls to the secret value input
so the user can paste immediately.

## Query params

| Param              | Required | Description                                                                                                                                                  |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`             | yes      | Secret name (for example `exampleApiKey`).                                                                                                                   |
| `description`      | no       | Human-readable description shown in the UI.                                                                                                                  |
| `expiresAt`        | no       | Optional UTC ISO expiry (`2026-12-01T00:00:00.000Z`) or a `YYYY-MM-DD` date stored as midnight UTC. Prefills the Expires field. Leave omitted for no expiry. |
| `allowedHosts`     | no       | Comma-separated hosts to review for approval.                                                                                                                |
| `allowedPlaybooks` | no       | Comma-separated saved playbook ids to review for approval.                                                                                                   |
| `scope`            | no       | `user` (default) or `playbook`.                                                                                                                              |
| `playbookId`       | no       | Required when `scope=playbook`. Use the saved playbook id that owns the secret.                                                                              |

## Approval policy reminders

- Saving a secret does **not** approve outbound hosts.
- The account form prefills the requested hosts and playbooks for review.
- Host approval uses the dedicated **`/connect/secrets`** page (`name` / `names`
  and `hosts`). Playbook grants use `/account/secrets/approve`.

## Playbook approval URLs (after a playbook exists)

Self-authored personal playbooks can read and use the user's secrets without an
`allowed_playbooks` grant; updating or deleting a user secret from playbook code
still requires that grant. Agents can add a playbook to that grant with
`secretLock`; removing a grant is website-only. When a playbook operation
requires an additional grant on an existing secret, send the returned approval
link; do not ask the user to recreate the secret. Source edits do not widen
grants.

- Single secret:
  `/account/secrets/user/{secretName}?playbook_id={savedPlaybookId}&playbook={kodyId}`
- Multiple secrets for one playbook (preferred):
  `/account/secrets/approve?playbook_id={savedPlaybookId}&playbook={kodyId}&names={secret1},{secret2}`

Prefer the bulk `/account/secrets/approve?...&names=...` URL whenever two or
more secrets still need playbook approval. The account UI shows every listed
secret and lets the user approve them in one click.

## Agent instructions

1. Generate the URL with the required `name` and any optional params.
   - When using `scope=playbook`, include the saved playbook id in `playbookId`.
2. Ask the user to open the URL in their browser.
3. Wait until they confirm the secret is saved.
4. If the secret will back a playbook or playbook app, run the authenticated
   smoke test described in `guide: "integration_bootstrap"` before saving the
   downstream playbook.
5. For common non-OAuth integrations, continue with
   `guide: "secret_backed_integration"` after the secret exists.
6. Proceed using `{{secret:name}}` fetch placeholders or a named secret lookup
   such as `secretJwtSign`.
