> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runtools.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets & Credentials

> Manage user-private and org-shared encrypted secrets

Secrets are encrypted values — API keys, provider credentials, anything a tool or agent needs — stored once and referenced by name. They're user-private by default; an org admin can share one across the whole organization. The platform decrypts them server-side at use time, and list responses only ever return metadata, never the value.

Manage them from the dashboard, CLI, SDK, or the REST API at `https://tools.runtools.ai/v1/secrets`.

## Create Or Rotate

<CodeGroup>
  ```bash CLI theme={null}
  runtools secret set ANTHROPIC_API_KEY "sk-ant-xxx" --category provider

  runtools secret set GITHUB_TOKEN "ghp_xxx" \
    --category tool \
    --description "GitHub fallback token"

  runtools secret set SHARED_CRM_KEY "crm_xxx" \
    --category tool \
    --org-wide

  echo "new-secret-value" | runtools secret rotate ANTHROPIC_API_KEY
  ```

  ```typescript SDK theme={null}
  await rt.secrets.set('ANTHROPIC_API_KEY', process.env.ANTHROPIC_API_KEY!, {
    category: 'provider',
    scope: 'all',
  });

  await rt.secrets.set('SHARED_CRM_KEY', process.env.CRM_KEY!, {
    category: 'tool',
    orgWide: true,
  });

  // Rotate = set a new value behind the same name (callers keep using the name).
  await rt.secrets.rotate('ANTHROPIC_API_KEY', process.env.NEW_ANTHROPIC_KEY!);
  ```

  ```bash cURL theme={null}
  curl -X POST https://tools.runtools.ai/v1/secrets \
    -H "X-API-Key: $RUNTOOLS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "ANTHROPIC_API_KEY",
      "value": "sk-ant-xxx",
      "category": "provider",
      "scope": "agents",
      "description": "Claude API key"
    }'
  ```
</CodeGroup>

## List Metadata

List responses never include secret values.

<CodeGroup>
  ```bash CLI theme={null}
  runtools secret list
  runtools secret list --user-only
  runtools secret list --org-only
  runtools secret list --all-org
  ```

  ```typescript SDK theme={null}
  const mine = await rt.secrets.list();
  const orgShared = await rt.secrets.list({ scope: 'org' });
  const providerKeys = await rt.secrets.list({ category: 'provider' });
  ```

  ```bash cURL theme={null}
  curl "https://tools.runtools.ai/v1/secrets?secretScope=user" \
    -H "X-API-Key: $RUNTOOLS_API_KEY"
  ```
</CodeGroup>

## Reveal When Allowed

```bash theme={null}
runtools secret get ANTHROPIC_API_KEY --reveal
runtools secret get SHARED_CRM_KEY --org-wide --reveal
```

```typescript theme={null}
const revealed = await rt.secrets.get('ANTHROPIC_API_KEY', {
  reveal: true,
});
```

Reveal policy is enforced by the API. User-private values can only be revealed by their owner. Org-shared values require org admin access. Admins can manage org-shared secrets, but cannot reveal another member's user-private secret.

## Delete

```bash theme={null}
runtools secret delete ANTHROPIC_API_KEY
runtools secret delete SHARED_CRM_KEY --org-wide
```

```typescript theme={null}
await rt.secrets.delete('ANTHROPIC_API_KEY');
await rt.secrets.delete('SHARED_CRM_KEY', { orgWide: true });
```

## Tool Credential Overrides

Use `credentialOverrides` to point a tool credential field at a named secret without sending the secret value in the request:

```typescript theme={null}
await rt.tools.execute('custom-crm', {
  action: 'lookup_customer',
  params: { email: 'person@example.com' },
  credentialOverrides: {
    apiKey: 'SHARED_CRM_KEY',
  },
});
```

Installed API-key tools can also store tool-local credentials:

```bash theme={null}
runtools tool credentials customer-db --json '{"apiKey":"crm_xxx"}'
```

When a tool credential field falls back to secrets, RunTools normalizes the required field name into a secret name. For example, `apiKey` becomes `APIKEY`. Use `credentialOverrides` when you want a clearer secret name such as `SHARED_CRM_KEY`.

## API Reference

| Method   | Path                        | Description               |
| -------- | --------------------------- | ------------------------- |
| `GET`    | `/v1/secrets`               | List metadata             |
| `POST`   | `/v1/secrets`               | Create or rotate a secret |
| `GET`    | `/v1/secrets/{name}`        | Get metadata              |
| `POST`   | `/v1/secrets/{name}/reveal` | Reveal when policy allows |
| `DELETE` | `/v1/secrets/{name}`        | Delete a secret           |

Query options include `category`, `secretScope=user|org`, `all=true`, `orgWide=true`, and admin-targeted `user_id`.

Secret names are normalized to uppercase letters, numbers, and underscores. Keep names stable and rotate the value behind the name.

## Best Practices

<AccordionGroup>
  <Accordion title="Prefer connected apps for OAuth providers">
    GitHub, Google, Slack, and similar providers are better handled through OAuth when the tool supports it.
  </Accordion>

  <Accordion title="Use org-shared secrets intentionally">
    Use `--org-wide` only for credentials meant to be shared by the organization.
  </Accordion>

  <Accordion title="Keep names stable">
    Rotate by updating the value behind a stable name, such as `ANTHROPIC_API_KEY`.
  </Accordion>

  <Accordion title="Avoid logging revealed values">
    Treat revealed values as sensitive and avoid printing them in CI logs.
  </Accordion>
</AccordionGroup>
