---
title: "Manage tenant secrets"
description: "Store a secret once for the tenant, then inspect the providers, plugins and connections that use it."
canonical_url: "https://docs.oz0.ai/admin/secrets"
---
# Manage tenant secrets

> Store a secret once for the tenant, then inspect the providers, plugins and connections that use it.

For: cluster and tenant administrators.

Secrets are stored per tenant, sealed with AES-GCM under the cluster's master key, or, once the cluster has a secrets key, with HPKE to a key that only the edges hold ([roles apart](https://docs.oz0.ai/fleet/separate-roles)). The value never comes back out of the admin API; only the edge unseals it, when it needs it.

In the console, open Credentials to Secrets to Add Secret. The form opens in a dialog; cancelling clears its value. A name must be unique in the tenant: delete the existing secret before adding another with that name. The server checks creation atomically, including simultaneous requests. Existing API and CLI calls can still explicitly rotate a value. Reminder settings opens a separate dialog for the days before expiry when reminders are sent; cancelling keeps the saved schedule.

Store a secret once for the tenant, then inspect the providers, plugins and connections that use it.

## Choose a task

<table>
<thead>
  <tr>
    <th>
      Task
    </th>
    
    <th>
      Guide
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Bind secrets to destination hosts
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/admin/secrets/host-bindings">
        Open guide
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Test and rotate secrets
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/admin/secrets/rotation">
        Open guide
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Use an external secret store
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/admin/secrets/external-stores">
        Open guide
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Deliver and scan plugin secrets
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/admin/secrets/plugin-secrets">
        Open guide
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Configure plugin settings
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/admin/secrets/settings">
        Open guide
      </a>
    </td>
  </tr>
</tbody>
</table>

## Set, list and delete

The value comes from stdin, an environment variable or a file, never from the command line, so it does not end up in your shell history:

```bash [Terminal]
printf %s "$ANTHROPIC_API_KEY" | oz0 secret set ANTHROPIC_API_KEY
oz0 secret set OPENAI_API_KEY --from-env OPENAI_API_KEY
oz0 secret set GITHUB_TOKEN --from-file ~/.secrets/github-token --tenant acme --host github.com --host api.github.com

oz0 secret list          # names, versions, ages, expiries and the hosts each may go to; never values
oz0 secret delete GITHUB_TOKEN
```

Every change is recorded in the audit log, without the value.

## What uses them today

<table>
<thead>
  <tr>
    <th>
      Secret
    </th>
    
    <th>
      Used by
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ANTHROPIC_API_KEY
      </code>
    </td>
    
    <td>
      The LLM gateway, for models named <code>
        anthropic/...
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OPENAI_API_KEY
      </code>
    </td>
    
    <td>
      The LLM gateway, for models named <code>
        openai/...
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      The <code>
        key_secret
      </code>
      
       of any other <a href="https://docs.oz0.ai/spend/models-and-keys#providers-are-records">
        provider
      </a>
      
      , such as <code>
        GEMINI_API_KEY
      </code>
      
       or <code>
        MISTRAL_API_KEY
      </code>
    </td>
    
    <td>
      The LLM gateway, for that provider's models
    </td>
  </tr>
  
  <tr>
    <td>
      A provider's client secret, service account key, or AWS access key ID, secret and session token, such as <code>
        AZURE_CLIENT_SECRET
      </code>
      
      , <code>
        GOOGLE_SERVICE_ACCOUNT_KEY
      </code>
      
      , <code>
        AWS_ACCESS_KEY_ID
      </code>
    </td>
    
    <td>
      The LLM gateway, which signs calls with them or trades them for a token on the edge (<a href="https://docs.oz0.ai/spend/models-and-keys/authentication#how-calls-are-signed">
        How calls are signed
      </a>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      Any name you choose
    </td>
    
    <td>
      The token for a private plugin repository or OCI registry, named with <code>
        plugin install --secret
      </code>
      
      ; see <a href="https://docs.oz0.ai/build/plugins/install/sources#a-private-repository">
        Install and update
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Any name a plugin lists in <code>
        requires.secrets
      </code>
    </td>
    
    <td>
      That plugin's tools, hooks and harnesses, as environment variables; see below
    </td>
  </tr>
  
  <tr>
    <td>
      Any name a plugin lists in <code>
        requires.optional_secrets
      </code>
    </td>
    
    <td>
      The same, when the tenant has it; an address or a switch is a <a href="https://docs.oz0.ai/admin/secrets/settings#settings-are-not-secrets">
        setting
      </a>
      
       instead
    </td>
  </tr>
  
  <tr>
    <td>
      Any name a flow's or a routine's webhook names
    </td>
    
    <td>
      The edge, to check calls to the webhook; see <a href="https://docs.oz0.ai/build/parts/flows#start-one-from-a-webhook">
        Flows
      </a>
      
       and <a href="https://docs.oz0.ai/build/parts/routines#webhooks">
        Routines
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Any name an event source names
    </td>
    
    <td>
      The edge, to check the signature of each delivery; see <a href="https://docs.oz0.ai/build/parts/event-sources#declare-a-source">
        Event sources
      </a>
    </td>
  </tr>
</tbody>
</table>

When a model call needs a key the tenant does not have, the gateway answers `412` with the command that sets it. An agent with a fallback model on another provider falls back to it; when no model has a key, the job fails at once with `MissingKey` and that command. See [Troubleshooting](https://docs.oz0.ai/fleet/troubleshooting#a-job-fails-with-a-model-error).

## Who uses each one

`oz0 secret usage`, and the Credentials page under Admin in the console, show a tenant's credentials and who acts through them, for its admins only, and never a value (management holds none). It is also where the console sets secrets and connects connections, so each is in one place:

- every secret: who set it and when, the plugins that declare it, the model providers that read it (as a key, an access key ID or a session token), the [credential bindings](https://docs.oz0.ai/admin/credential-injection) that inject it and where, and the [connection](https://docs.oz0.ai/admin/connections) whose steps saved it; a secret something reads that is not set yet, such as a built-in model provider's key, is listed under *Read, but not set yet*, and Set it puts its name in the form;
- every connection: its tools and secrets, who connected it and when, what it signs in as (the values its steps saved, such as an app or an installation), when a call last got its token, the bindings that put its token on hosts, and the plugins whose granted uses call its tools;
- credential changes that wait for another admin's decision;
- the refusals of the last 24 hours from the audit trail: secrets refused in calls, credentials or placeholders that went where no binding puts them, and egress denials of hosts a binding names.

```bash [Terminal]
oz0 secret usage --tenant acme
oz0 secret usage --json
```

A provider key that another tenant of the cluster uses too is marked there, without naming that tenant: the provider's prompt caches may be shared between the two. See [Two tenants, one key](https://docs.oz0.ai/spend/models-and-keys/authentication#two-tenants-one-key).

## Previous section links

<span id="where-a-secret-may-be-sent">

Where a secret may be sent

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/host-bindings#where-a-secret-may-be-sent).

<span id="rotate-test-and-roll-back">

Rotate, test and roll back

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/rotation#rotate-test-and-roll-back).

<span id="a-providers-key-is-tested-before-it-is-stored">

A provider's key is tested before it is stored

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/rotation#a-providers-key-is-tested-before-it-is-stored).

<span id="roll-back-within-24-hours">

Roll back within 24 hours

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/rotation#roll-back-within-24-hours).

<span id="expiry-and-reminders">

Expiry and reminders

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/rotation#expiry-and-reminders).

<span id="secrets-in-your-own-store">

Secrets in your own store

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/external-stores#secrets-in-your-own-store).

<span id="stores-run-on-the-edges">

Stores run on the edges

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/external-stores#stores-run-on-the-edges).

<span id="rotation-in-the-store">

Rotation in the store

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/external-stores#rotation-in-the-store).

<span id="taking-a-store-away">

Taking a store away

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/external-stores#taking-a-store-away).

<span id="secrets-for-plugins">

Secrets for plugins

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/plugin-secrets#secrets-for-plugins).

<span id="secrets-on-a-file-descriptor">

Secrets on a file descriptor

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/plugin-secrets#secrets-on-a-file-descriptor).

<span id="what-is-scanned">

What is scanned

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/plugin-secrets#what-is-scanned).

<span id="settings-are-not-secrets">

Settings are not secrets

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/settings#settings-are-not-secrets).

<span id="settings-kept-as-secrets-before">

Settings kept as secrets before

</span>

: [open guide](https://docs.oz0.ai/admin/secrets/settings#settings-kept-as-secrets-before).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
