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

# Secrets

> Store credentials securely, rotate their values, and share them with projects

A **secret** stores a credential such as a model API key, machine environment value, MCP token, or integration credential. Other resources reference the secret by its `sec_…` ID instead of storing the value themselves.

Secret values are encrypted and never returned by read endpoints. Rotating a secret updates the value used by its existing references, so nothing needs to be redeployed.

## Kinds and owners

You can create three kinds:

| `kind`            | Holds                                                                    | Created by                                                  |
| ----------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------- |
| `generic`         | One value, such as an API key, token, or password                        | You                                                         |
| `oauth_token_set` | Access/refresh tokens with refresh metadata                              | The [MCP OAuth flow](/tools/mcp#connect-with-oauth), or you |
| `aws_credentials` | AWS access credentials, with an optional session token or role to assume | You                                                         |

Every secret has exactly one owner. A project can use a secret only if the project owns it or holds an explicit [grant](#grant-a-secret-to-a-project) — org and user ownership don't make a secret visible to projects on their own:

| Owner                                    | Typical use                                                                                                                                                              |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `{ "kind": "org" }`                      | Org-level resources — [model provider](/organization/model-providers) credentials, [machine pool](/machines/pools) API keys. Grant it to projects that need it directly. |
| `{ "kind": "project", "project_id": … }` | That project's agent configs and machines                                                                                                                                |
| `{ "kind": "user" }`                     | Personal credentials; grant to the projects that need them                                                                                                               |

The convention that keeps orgs tidy: own each secret at the narrowest scope that needs it. A model key the whole org shares is org-owned; one project's GitHub deploy token is project-owned.

## Create a secret

<Tabs>
  <Tab title="API">
    The examples assume the client, `$ORG`/`orgID`, and `$PROJ`/`projectID` setup from the [quickstart](/quickstart).

    <CodeGroup>
      ```bash CLI theme={null}
      npx omnara secrets create \
        --owner-kind project \
        --owner-project-id proj_7mv4qtrwz3jehcyd5n6a2bfgik \
        --name github-deploy-token \
        --metadata '{"rotates": "quarterly"}' \
        --material-kind generic \
        --material-value "ghp_..." \
        --json
      ```

      ```bash REST theme={null}
      curl "$OMNARA_API/orgs/$ORG/secrets" \
        -H "Authorization: Bearer $OMNARA_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{
          "owner": { "kind": "project", "project_id": "'"$PROJ"'" },
          "name": "github-deploy-token",
          "metadata": { "rotates": "quarterly" },
          "material": { "kind": "generic", "value": "ghp_..." }
        }'
      ```

      ```typescript SDK theme={null}
      const secret = await sdk.createSecret({
        client,
        path: { orgID },
        body: {
          owner: { kind: 'project', project_id: projectID },
          name: 'github-deploy-token',
          metadata: { rotates: 'quarterly' },
          material: { kind: 'generic', value: 'ghp_...' },
        },
      })
      ```
    </CodeGroup>

    ```json theme={null}
    {
      "id": "sec_7jehcyd5n6a2bfgik7mv4qtrwz",
      "owner": { "kind": "project", "project_id": "proj_7mv4qtrwz3jehcyd5n6a2bfgik" },
      "name": "github-deploy-token",
      "kind": "generic",
      "current_version_number": 1,
      "...": "..."
    }
    ```

    For MCP OAuth, use the built-in [OAuth flow](/tools/mcp#connect-with-oauth) — `npx omnara secrets mcp-oauth` runs it end to end from the terminal. If you need to import OAuth tokens yourself, see the [secret schema](/api-reference/endpoints/secrets/create-secret).
  </Tab>

  <Tab title="Dashboard">
    Under org, project or user secrets, click **New secret**, name it, and choose **Generic**, **OAuth token set**, **MCP OAuth secret**, or **AWS credentials**. For MCP OAuth, click **Authorize and Create Secret** to run the [OAuth flow](/tools/mcp#connect-with-oauth). You can also add **Project grants** in the same dialog.
  </Tab>
</Tabs>

On both surfaces, reads return the secret's metadata, never its value. If you lose the value, rotate the secret.

## Rotate a secret

Rotation creates a new version while keeping the same secret ID. It is **API-only for now**; the dashboard and CLI show the current version but cannot rotate it.

<CodeGroup>
  ```bash REST theme={null}
  curl "$OMNARA_API/orgs/$ORG/secrets/sec_7jehcyd5n6a2bfgik7mv4qtrwz/versions" \
    -H "Authorization: Bearer $OMNARA_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"material": {"kind": "generic", "value": "ghp_new..."}}'
  ```

  ```typescript SDK theme={null}
  const rotated = await sdk.createSecretVersion({
    client,
    path: { orgID, secretID: 'sec_7jehcyd5n6a2bfgik7mv4qtrwz' },
    body: { material: { kind: 'generic', value: 'ghp_new...' } },
  })
  ```
</CodeGroup>

The response has `current_version_number: 2`. Existing references use the new current value without changing their `sec_…` ID. Processes already running keep the environment they started with.

## Manage secrets

Use the secrets pages or API to search for secrets. **Edit** can change a secret's name and metadata, but not its value; use rotation to change the value.

You cannot delete a secret while a model provider, machine pool, or integration uses it. Replace the secret on that resource — or delete the resource — first.

## Grant a secret to a project

A grant lets a project use a secret it does not own.

<Tabs>
  <Tab title="API">
    <CodeGroup>
      ```bash CLI theme={null}
      npx omnara grant secrets add sec_7jehcyd5n6a2bfgik7mv4qtrwz \
        --target-project-id proj_4qtrwz3jehcyd5n6a2bfgik7mv \
        --json
      ```

      ```bash REST theme={null}
      curl "$OMNARA_API/orgs/$ORG/secrets/sec_7jehcyd5n6a2bfgik7mv4qtrwz/grants" \
        -H "Authorization: Bearer $OMNARA_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"target_project_id": "proj_4qtrwz3jehcyd5n6a2bfgik7mv"}'
      ```

      ```typescript SDK theme={null}
      const grant = await sdk.createSecretGrant({
        client,
        path: { orgID, secretID: 'sec_7jehcyd5n6a2bfgik7mv4qtrwz' },
        body: { target_project_id: 'proj_4qtrwz3jehcyd5n6a2bfgik7mv' },
      })
      ```
    </CodeGroup>

    ```json theme={null}
    {
      "id": "sgr_yd5n6a2bfgik7mv4qtrwz3jehc",
      "secret_id": "sec_7jehcyd5n6a2bfgik7mv4qtrwz",
      "target_project_id": "proj_4qtrwz3jehcyd5n6a2bfgik7mv",
      "...": "..."
    }
    ```

    To review a secret's project grants, use `npx omnara grant secrets list {secret-id}`, `GET /orgs/$ORG/secrets/{secret-id}/grants`, or `sdk.listSecretGrants`. To remove one, use `npx omnara grant secrets delete {secret-id} {grant-id}`, `DELETE` on the grant, or `sdk.deleteSecretGrant`.

    To list every secret a project can use (no CLI command for this yet):

    <CodeGroup>
      ```bash REST theme={null}
      curl "$OMNARA_API/orgs/$ORG/projects/$PROJ/secrets" -H "Authorization: Bearer $OMNARA_TOKEN"
      ```

      ```typescript SDK theme={null}
      const available = await sdk.listProjectAvailableSecrets({
        client,
        path: { orgID, projectID },
      })
      ```
    </CodeGroup>

    This includes secrets owned by the project and secrets explicitly granted to it. `availability.source` is `direct` for project-owned secrets and `grant` for granted secrets.
  </Tab>

  <Tab title="Dashboard">
    On the secret's row, click **Grant to project** and pick the target project (or attach **Project grants** while creating the secret). To view or revoke a project's secret grants, open its **Grants** page and select **Secrets**. Click **Remove secret grant** to remove access without deleting the secret.
  </Tab>
</Tabs>

## Where secret IDs are used

These fields reference a secret instead of storing its value directly:

| Surface                                                        | Field                                                                                                                           |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| [Model provider config](/organization/model-providers)         | `credential_secret_id`                                                                                                          |
| [Machine](/machines/connect) environment                       | `secret_env`                                                                                                                    |
| [Pool](/machines/pools) environment                            | `default_machine_secret_env`; project-specific pool grants can add or override values with `default_machine_secret_env_overlay` |
| Agent config [machine sources](/agents/configuration#machines) | `secret_env_overlay`                                                                                                            |
| Agent config [MCP auth](/tools/mcp)                            | `auth.secret_id`                                                                                                                |
| [Machine pool](/machines/pools) provider                       | `provider_auth_secret_id`                                                                                                       |

<Info>
  Full schema and playground: [Create secret](/api-reference/endpoints/secrets/create-secret) · [Create secret version](/api-reference/endpoints/secrets/create-secret-version) · [Secret grants](/api-reference/endpoints/secrets/create-secret-grant) · [Project secrets](/api-reference/endpoints/secrets/list-secrets-available-to-project).
</Info>
