# Storing your secrets in the keyring

The IBM® Paver keyring is an encrypted storage system for the secrets your workflows need, such as API keys, tokens, and passwords. Store a secret once, export it to your conversation, and Paver makes it available as an environment variable in the sandbox, without exposing it in your chat history.

In a typical workflow you often need API keys for third-party services like GitHub, Slack, and service credentials. The problem is that if you paste a secret directly into the chat or write it into a script in your workspace, that value becomes part of your conversation history or a plain-text file.

The keyring solves this. You store the secret in the keyring one time and export it to the conversation. After it is exported, Paver injects it as an environment variable into the sandbox every time your agent runs a command. Your scripts can reference `MY_API_KEY`, for example, by name, but the actual value never appears in the chat. A stored secret is not injected until you export it. For more information, see [Exporting to the sandbox shell](#exporting-to-the-sandbox-shell).

Secrets that are stored in the keyring are:

- **Encrypted at rest on the server**: Values are never stored as plain text.
- **Injected at run time**: When Paver runs a command in the sandbox, it injects the exported values as environment variables so your scripts can use them.
- **Automatically redacted from output**: Any stored value that is eight or more characters long is replaced with `[redacted]` if it accidentally appears in a command's output.
- **Time-limited**: Entries expire automatically to prevent secrets from accumulating indefinitely.

## Adding a secret

Use `paver keyring add` to store a new secret. You can provide the value from an environment variable, a file, or an interactive prompt. Passing a raw value as a positional argument is not supported, which keeps the value out of your shell history.

```text
paver keyring add <name> env://VAR_NAME                  # Read from an environment variable
paver keyring add <name> file://relative/path.txt        # Read from a relative file path
paver keyring add <name> file:///absolute/path.txt       # Read from an absolute file path
paver keyring add <name>                                 # Interactive prompt (TTY only)
paver keyring add <name> env://VAR_NAME --ttl 7d         # Set a custom expiry
```

In `paver chat`, use `/keyring add` with a source reference such as `env://` or `file://`.

### Name rules

Entry names must follow these rules:

- Alphanumeric characters and underscores only: `A–Z`, `a–z`, `0–9`, `_`
- Maximum 64 characters
- For example: `ibmcloud_api_key`, `MY_SERVICE_KEY`, `github_token`

### Time-to-live (TTL)

Entries expire automatically. The default TTL is 24 hours and the maximum is 30 days.

| Format | Example     | Duration  |
| ------ | ----------- | --------- |
| Hours  | `1h`, `24h` | 1–N hours |
| Days   | `7d`, `30d` | 1–30 days |

Review the following examples for adding a secret to the keyring:

```text
# Add an IBM Cloud API key from the environment, valid for 7 days
paver keyring add ibmcloud_api_key env://IBMCLOUD_API_KEY --ttl 7d

# Add a GitHub token from a file, using the default 24-hour TTL
paver keyring add github_token file:///Users/you/.config/gh-token.txt

# Interactive prompt in CLI only — Paver asks for the value with masked input
paver keyring add my_service_key
```

To renew an expiring entry, run `keyring add` again with the same name. The existing entry is replaced.

### Secret length and output redaction

Paver automatically redacts any stored secret value that is eight or more characters long. If that value appears in a command's output, Paver replaces it with `[redacted]` before it displays it in chat.

Values shorter than eight characters are not redaction-eligible. Paver warns you when you add a short value. After that, if a command prints the value, it appears unredacted in the chat. Use API keys and tokens of at least eight characters to ensure automatic redaction coverage.

> **Verbose flags can bypass redaction**
>
> Some CLI tools have `--debug` or `--verbose` flags
> that print environment variables or raw request bodies in ways that can
> bypass simple value matching. Use these flags sparingly when working with
> credentials.

## Exporting to the sandbox shell

Storing a secret in the keyring does not make it available to your commands. The secret becomes an environment variable in the sandbox only when it is exported. You can export two ways: manually for a conversation or automatically with the `keyring.autoExport` setting in the CLI.

### Manually export from `paver chat`

To export a specific entry to the current conversation's shell on demand, use `/keyring export` inside `paver chat`:

```text
/keyring export ibmcloud_api_key                     # Export using keyring name as env var name
/keyring export ibmcloud_api_key as IBMCLOUD_API_KEY # Export with a custom env var name
/keyring export ibmcloud_*                           # Export all entries matching a prefix
```

After you export, the variable is available immediately to bash commands Paver runs. If you have an open `/shell` session, reopen it to pick up the new variable.

The following rules apply to exporting:

- Environment variable names must start with a letter or underscore and contain only `A–Z`, `a–z`, `0–9`, `_`.
- System-reserved names such as `PATH`, `HOME`, `SHELL`, and similar are blocked.
- The `as` option is not available with prefix wildcard exports.

Keep in mind the following:

- Expired entries can't be exported. Re-add them with `paver keyring add` first.
- Exports are saved with the conversation and looked up again on every command, so they persist if the conversation container is re-created.

> **Exported values are ambient plain text in the shell**
>
> After exported, a secret is readable by any command in the conversation by using&#x20;
> `env` or `printenv`. Export only what a tool
> genuinely needs, and prefer short-lived values.

### Auto-export

To avoid running `/keyring export` yourself, configure `keyring.autoExport` in `~/.paver/config.json`. This is a local CLI setting. Paver exports these entries automatically before each `paver chat` command and when `/shell` opens. It has no effect in the web UI.

```text
{
"keyring": {
  "autoExport": [
    "ibmcloud_api_key",
    { "key": "github_token", "as": "GITHUB_TOKEN" }
  ]
}
}
```

The `"as"` field maps a keyring entry name to the specific environment variable name that your tools expect.

## Listing, removing, and clearing secrets

Use the following commands to manage the entries in your keyring:

```text
paver keyring list             # Show entry names, status, and expiry (never values)
paver keyring remove <name>    # Remove a single entry
paver keyring clear            # Remove all entries (asks for confirmation)
paver keyring clear -y         # Remove all entries without a confirmation prompt
```

`paver keyring clear` prompts for confirmation. Add `-y` (or `-f`) to skip the prompt. Inside `paver chat`, use `/keyring list` and `/keyring remove <name>`.

## Troubleshooting storing secrets and the keyring

### Why is the environment variable not set or empty?

If you see `Error: Environment variable <VAR_NAME> is not set or empty`, the variable referenced by `env://<VAR_NAME>` does not exist in your current shell session. Export it first:

```text
export IBM_CLOUD_API_KEY=<your-api-key>
paver keyring add ibmcloud_api_key env://IBM_CLOUD_API_KEY
```

### Why is Paver still asking for credentials after adding to the keyring?

Run `paver keyring list` to confirm the entry exists and has not expired. If the entry is missing or expired, re-add it with `paver keyring add`. Also, verify that the entry name exactly matches the environment variable name your workflow expects.

### What does secret value is too short for output redaction mean?

If you see `Warning: Secret value is shorter than 8 characters. Output redaction will not apply.`, the value is too short for automatic redaction. The entry is still stored and injected, but if the value appears in output in a chat it is not replaced. Use longer API keys or tokens where possible.

### What if the keyring entry expires before the session does?

Run `paver keyring add` again with a longer `--ttl` to refresh the entry before you start a session.

### Why does the tool fail with an authentication error even though the secret was exported?

The keyring entry for the exported secret might have expired. When an entry expires, its environment variable is removed from the sandbox, and any tool that depends on it fails with an authentication error, such as `401` or `not logged in`.

The effect of an expired entry depends on where you're working:

- Agent commands no longer have the variable.
- An open `/shell` session keeps the variable until you exit. Tools that already logged in might keep working for a while.
- You can't export new entries in that conversation until you re-add the expired entry.

To recover, run `paver keyring add` again with the same name. You don't need to export it again. Reopen `/shell` to pick up the variable.

To avoid this problem, run `paver keyring list` before you start a long task to check expiry dates. Set a `--ttl` that covers the entire task.
