App integrations

# Secrets Plugin

Server-side credential storage with explicit agent access.

## [Vaults and existing credentials](https://cadu.bot/docs/secrets#setup)

Open Settings → Secrets to manage named vaults containing logins, payment cards, and addresses. Login items can include an authenticator key. The plugin also retains a separate legacy store for existing profile-local API keys and credentials.

The audited `cadu-secrets-vault` manifest is version 2.2.4, declares Hermes ≥ 0.21.3 and `cryptography>=50,<51`. Named vaults additionally require the native `agent.vault_store.VaultStore` API; setup checks its methods rather than assuming the manifest minimum is sufficient. The compatibility error identifies v2026.9.11 as the tested runtime.

1.  Install or update Secrets through Cadu's setup flow and complete any requested dashboard and gateway restarts.
2.  Create a named vault, add an item and its website, and choose which agents may use the vault. Newly created named vaults start with no agent grants.
3.  Existing native Hermes profile vaults are discovered in place. Their owning agent retains access; Cadu can grant additional agents access without copying the store.

Named vaults are limited to 100 catalog entries, with up to 1,000 items per vault through the plugin's add operation. Secret fields are validated as strings of at most 64 KiB each. Available fields and item validation also depend on the native Hermes store.

## [Encryption and storage boundaries](https://cadu.bot/docs/secrets#encryption)

**Secrets is encrypted at rest on the Hermes server, not end-to-end encrypted against Hermes.** Cadu submits values through the configured dashboard connection. Hermes must decrypt values to fill a browser form or inject them into a program. Protection in transit depends on that connection's transport and trust configuration.

Storage models
| Store | Ciphertext and key |
| --- | --- |
| Named Cadu vault | Encrypted vault data and its key in the same private directory on the server. Native Hermes VaultStore encrypts the serialized item document with Python cryptography's Fernet. |
| Existing Hermes vault | The profile's existing encrypted vault data and key, referenced in place. |
| Legacy credentials | Profile-local encrypted credential storage. The Fernet key must be outside the Hermes data root, selected by `CADU_SECRETS_KEY_FILE` or the unmanaged-host default. |

The named-vault catalog stores names, icons, store bindings, grants, and revisions on the server; this policy metadata is not encrypted. Native ciphertext writes use an atomic write with mode `0600`; key creation also requests `0600`. Plugin storage helpers use private directories, ownership checks, and reject symlinks on guarded paths.

A copy of both a named vault and its adjacent key is sufficient for decryption. These files do not protect credentials from the Hermes runtime user, host administrators, or an agent with equivalent filesystem access. The separate legacy-key location changes backup handling, not that runtime trust boundary.

## [Agent grants and revocation](https://cadu.bot/docs/secrets#permissions)

Runtime access derives the active profile from Hermes, rather than accepting a model-selected profile. Named-vault grants bind to a marker and the profile directory's filesystem identity. Copying or recreating a profile requires fresh grants. Discovered native vaults also bind to their original store identity and key.

Catalog listing omits ungranted vaults. Credential resolution checks grants live under the catalog lock. Browser fill rechecks after page inspection and any payment approval, and holds authorization through the final fill operation. A successful revoke blocks subsequent plugin-authorized use; it cannot erase secrets already delivered to a page or process.

CLI injection releases the catalog lock before executing the program. Revocation does not terminate that program or remove its environment. Grants are plugin policy, not an operating-system sandbox around other tools or same-user shell access. An existing Hermes vault's owner access cannot be disabled through Cadu.

## [Supervised browser fill](https://cadu.bot/docs/secrets#browser)

1.  The agent calls `cadu_vaults` to get granted item metadata. This can include the login identifier, label, kind, and saved origin, but does not return the password.
2.  It opens the item's saved website and types the listed login identifier. `cadu_vault_fill` uses Hermes' supervised browser helpers and checks the page's origin against the saved origin.
3.  Payment fills require a human confirmation through the browser helper. The plugin inspects fields with a nonce, rechecks the grant and item, then resolves the secret.
4.  It registers redaction values and sends a protected fill using the expected origin and inspection nonce. The tool returns fixed status information and a field count, not raw browser output or secret values. It does not submit the form.

For login items with an authenticator key, `code=true` generates a current code server-side and fills matching code fields. If compatible browser helpers, the bound origin, or matching fields are unavailable, the operation returns an error instead of a raw-value fallback.

The filled website and browser receive the credential. Origin binding and filtered tool output reduce exposure in this path, but do not make a website trustworthy or guarantee that every other browser or terminal action cannot reveal a value. Redaction is not a general prevention of exfiltration.

## [Agent tools and runtime injection](https://cadu.bot/docs/secrets#tools)

**`cadu_vaults`**

Lists named vaults and item metadata granted to the active agent, and returns the native CLI path.

**`cadu_vault_fill`**

Fills a granted item in the supervised browser; accepts vault ID, item ID, and an optional authenticator-code flag.

**`cadu_secrets`**

Lists legacy profile-local credential names and descriptions, and returns the legacy CLI path.

**`cadu_secret_get`**

Returns a legacy credential's plaintext value in the tool result. This exposes it to the model and potentially conversation history. Its warning to avoid repeating the value is an instruction, not an enforcement boundary.

For programs, use the CLI path returned by the listing tool. Native `exec --vault <id> --item <id> --env ENV_NAME=FIELD_NAME -- command args` resolves a granted item field into a child environment. Legacy `exec --env ENV_NAME=SECRET_NAME -- command args` resolves a profile-local credential.

The wrappers avoid inserting secret values into command arguments. They do not filter child output, and the launched program can read, print, persist, or transmit its environment. Legacy CLI `get` also explicitly writes plaintext to stdout.

## [Management API and editing](https://cadu.bot/docs/secrets#api)

Management routes live under `/api/plugins/cadu-secrets-vault`. They rely on the host dashboard to authenticate access. Version-2 routes manage `/v2/vaults`, each vault's `/grants`, and its `/items`. Legacy routes retain `/setup`, `/initialize`, and `/secrets`.

These endpoints return metadata rather than saved credential values, and their response/error paths set `Cache-Control: no-store`. Input parsing caps request bodies at 400,000 bytes and avoids validation responses that echo submitted credentials. This concerns the plugin API, not arbitrary host-level logging or file access.

Named-vault grant, rename, and vault-delete operations require the catalog revision. Item edits retain omitted fields and replace the native item before removing the original. They do not use the same client revision check as catalog writes. Legacy credential edits and deletion require the stored credential revision.

A Cadu-created vault must be empty before deletion; the plugin retains its empty native files. Cadu does not delete discovered profile-owned vaults. Removing an item is not a promise of secure erasure from prior backups or filesystem history.

## [Backups and recovery](https://cadu.bot/docs/secrets#recovery)

Back up the named-vault catalog, ciphertext, and corresponding keys together, protecting the backup as credential-bearing data. For legacy stores, include the external key separately from the Hermes data backup. A ciphertext backup without its original key cannot be restored by inventing a new key.

The plugin refuses guarded cases such as a missing catalog with existing managed ciphertext, missing data for a recorded store, or missing keys for existing ciphertext. It reports unavailable or locked state rather than silently replacing those stores. A moved or recreated profile or discovered store may require explicit sharing grants again.

Container deployments using legacy credentials must configure a persistent key outside Hermes data with `CADU_SECRETS_KEY_FILE`. If setup reports a runtime update requirement, install a compatible native VaultStore and browser helper implementation. None of these checks establish hardware-backed key storage or server-blind encryption.
