# Vault Overview

> Secrets and credentials for connecting external services, organized in vaults.

**URL:** https://inference.sh/docs/secrets/overview
**Last updated:** 2026-10-15

---

Secrets and credentials for connecting external services, organized in vaults.

---

## Overview

inference shell provides two ways to give your agents access to external services:

| Method | Description | Best For |
|--------|-------------|----------|
| **[Environment Secrets](/docs/secrets/environment)** | Encrypted key-value pairs | API keys you already have |
| **[Credentials](/docs/secrets/credentials)** | Managed OAuth/service connections and MCP authorizations | Google, Atlassian, Slack, model providers |

Both live in your workspace's **[vault](https://app.inference.sh/vaults)**. Every workspace has a default vault, and workspaces can create more to organize connections by project or environment.

---

## Concepts

Four things work together. Each one answers a different question.

| Concept | Answers | Example |
|---------|---------|---------|
| **Provider** | Which service is this? Name, logo, docs. | Acme CRM, OpenAI, Google |
| **Credential** | What auth material do we hold for that provider, and who may use it? | Your workspace's Acme API key |
| **Secret** | What is the stored value? | `ACME_API_KEY = sk-…` |
| **Vault** | Which credentials and secrets are grouped together? | The workspace's default vault |

### Provider

A provider is the external service. Each has a slug (`acme`, `openai`, `google`) that everything else points to. The platform lists the common ones with their logo and docs.

A provider the platform doesn't list works too. The first time a key is saved for it, it becomes your workspace's own provider. It takes the name you give it and the logo from its website. Only your workspace sees it. The shared list grows through platform admins, including when a platform app declares a new provider.

### Credential

A credential is your connection to one provider. It always belongs to a provider, and it has:

- a **type**: `api_key` for keys you paste, `oauth` for a sign-in, `service_account`, `mcp`
- a **scope**: who can use it (`user`, `team`, `org`)
- a **status**: `connected` once it holds what it needs, `pending` before that

The platform keeps OAuth credentials fresh by refreshing their tokens. An API key credential holds its keys as secrets linked to it.

### Secret

A secret is one encrypted key-value pair, such as `ACME_API_KEY`. It is either:

- **linked to a credential**: the key belongs to that provider, and apps that ask for the provider receive it
- **plain**: an environment variable that belongs to no provider, such as a webhook signing token

A plain secret can be attached to a provider later. It then becomes that provider's credential under the same key name, so apps still read it the same way.

### Vault

A vault groups credentials and secrets. Every workspace has a default vault, and new workspace credentials and secrets are added to it automatically. Extra vaults let you organize connections by project or environment.

### Which one should I use?

- **The key belongs to a service** (an API key for Acme, OpenAI, fal): add it as an **API key credential** for that provider. It gets a logo, a scope and a status, and apps that ask for the provider find it.
- **The value belongs to no service** (a webhook token, a feature flag): add a **plain secret**.
- **The service uses a sign-in** (Google, Slack, Notion): **connect** it as an OAuth credential.

---

## Security

Both secrets and credentials are:

- **Encrypted at rest** using AES-256-GCM
- **Never logged** or exposed in task outputs
- **Scoped to your workspace**: other workspaces cannot access them
- **Injected only at runtime** — only to apps that require them and only to apps that are verified or user-owned

---

## How they work with apps

Apps declare what they need in `inf.yml`. Keys that belong to a provider go under `credentials:`. Values that belong to no provider go under `secrets:`.

```yaml
# inf.yml
credentials:
  acme:                           # the credential slug whose credential supplies the keys
    secrets: [ACME_API_KEY]       # the keys the app reads
    provider:                     # shown if the platform doesn't list acme
      name: Acme CRM
      website: acme.com           # where its logo comes from

  google:
    capabilities: [google.sheets] # OAuth: the capability the app needs
    description: Read sales data

secrets:
  - key: WEBHOOK_SECRET
    description: Signs outgoing webhooks
    optional: true
```

When you run the app:

1. We check your credentials and secrets against the list.
2. If something is missing, the run stops and shows what to add. You can paste an API key right there, and it is saved as that provider's credential.
3. Once everything is there, the keys are passed to the app as environment variables.

→ [Declaring credentials in inf.yml](/docs/extend/credentials)

---

## Vault in the web app

Secrets and credentials are managed from **Vaults** in the web app sidebar ([`/vaults`](https://app.inference.sh/vaults)).

### Vault list

[`/vaults`](https://app.inference.sh/vaults) lists the workspace's vaults with their credential and secret counts. **new vault** creates a named vault. Row actions rename or delete a vault. The **default** vault is created automatically on first access and cannot be renamed or deleted in the web app.

### Vault detail

A vault opens at `/vaults/{id}` with two tabs:

| Tab | Purpose |
|-----|---------|
| **credentials** | OAuth, BYOK, and service-account connections |
| **secrets** | Workspace environment secrets with masked values |

On the default vault's **credentials** tab, workspace admins see **add credential** with four options:

| Option | What it does |
|--------|--------------|
| **connect an account** | Pick an OAuth provider and authorize. Type a name the picker does not list and choose **not listed — add as your own provider** to register your own OAuth app for it (see [Auth Providers API](/docs/api/rest/auth-providers)) |
| **API key** | Pick a provider, or type the name of one we don't list and add its website. Choose **who can use it** and save the key. It becomes that provider's credential. |
| **MCP server** | Opens the MCP add dialog on [`/my/mcps?add=1`](https://app.inference.sh/my/mcps?add=1) |
| **environment variable** | Add a custom key-value pair, the same as **add secret** on the secrets tab |

The **scope** column shows who can use each connection (**only you**, **workspace**, **org**, or **everyone**). Change it from the scope menu when your role allows. See [Credential scope](/docs/credentials/overview#credential-scope).

On the **secrets** tab, workspace admins can reveal a value (audit-logged), update or delete a secret, and **add secret**. The link icon on a plain secret **attaches** it to a provider, making it that provider's credential. The broken-link icon detaches it. Other members see the list without those controls.

Workspace- and user-scoped credentials and workspace-scoped secrets are linked to the default vault when they are created. Platform- and org-scoped credentials are not vault members. Workspaces reach them through scope inheritance. A custom vault holds links to credentials and secrets that already exist in the workspace (see the [Vaults API](/docs/api/rest/vaults)). Deleting a custom vault removes the links and keeps the underlying records.

Legacy deep links such as [`/vaults?tab=secrets`](https://app.inference.sh/vaults?tab=secrets) redirect to the default vault's secrets tab, preserving other query parameters. `add` opens the add-secret dialog prefilled on that key. Optional `return` must resolve to a path on the app origin (the same rules as post-logout redirects — `https://…`, `//host`, and similar values are ignored). After you save the key named in `add`, the workspace navigates to `return` when it is valid. The secrets tab reads `add` and `return` once on load and removes them from the address bar so a reload does not reopen the dialog.

### Credential detail pages

Each provider has a connect and manage page at `/credentials/{slug}`, for example [`/credentials/google`](https://app.inference.sh/credentials/google). Legacy `/settings/integrations/{slug}` paths redirect there.

→ [Credentials overview](/docs/credentials/overview#credential-detail-page)

---

## Managing Secrets

You can manage secrets via the web UI, CLI, or REST API:

→ [Secrets API](/docs/api/rest/secrets) — `GET/POST /secrets`, create, update, reveal, delete

→ [Vaults API](/docs/api/rest/vaults) — group secrets and credentials into named vaults

```bash
# List all secrets
belt secrets list

# Set a secret (prompts for the value without echo; or pipe it on stdin)
belt secrets set OPENAI_API_KEY

# Save as a provider credential, or attach an existing key
belt secrets set GRAFANA_API_KEY --provider grafana
belt secrets attach GRAFANA_URL grafana

# Delete a secret
belt secrets delete OPENAI_API_KEY
```

---

## Quick Links

### Secrets

Store your own API keys and credentials:

→ [Environment Secrets](/docs/secrets/environment)

### Credentials

Managed connections, their scopes, and how apps receive them:

→ [Credentials](/docs/secrets/credentials)

### Provider guides

Connect to external services with managed OAuth:

→ [Credentials overview](/docs/credentials/overview)

**Available providers:**
- [Google Service Account](/docs/credentials/google-service-account) — Sheets, Docs, Drive
- [Google OAuth](/docs/credentials/google-oauth) — Gmail, Calendar, personal Drive
- [X.com](/docs/credentials/x) — Twitter API

---

## Next

→ [Environment Secrets](/docs/secrets/environment)

