---
title: Secrets
description: The encrypted organization secrets manager. Values are write-only, encrypted at rest, and injected into every sandbox as environment variables.
sidebar:
  order: 11
---

`/secrets` is where an organization stores the credentials its runs need, such as
an API key a task has to call. The design goal is simple: a value goes in, is used
inside sandboxes, and never comes back out.

## Write-only by design

<CardGroup cols={2}>
  <Card title="You can set and delete" icon="key-round">
    `PUT /api/secrets/:name` upserts a value; `DELETE /api/secrets/:name` removes
    it.
  </Card>
  <Card title="You cannot read a value back" icon="eye-off">
    `GET /api/secrets` returns metadata only. The plaintext value is never
    returned over the API.
  </Card>
</CardGroup>

## Encryption

Secrets are encrypted at rest with authenticated encryption:

| Property | Detail |
| --- | --- |
| Cipher | AES-256-GCM, with a random 12-byte IV per encryption. |
| Key derivation | HKDF-SHA256 from a dedicated encryption key (a development fallback derives from the auth secret). |
| Integrity | The GCM authentication tag validates integrity; tampering fails the decrypt. |
| At rest | Stored as base64 of the ciphertext, IV, and tag. |

## Injection into sandboxes

A run's secrets are injected into its sandbox as environment variables. Names
follow an environment-variable shape (uppercase, digits, and underscores), so a
secret named the way an SDK expects is available to the process without any code
handling the value. The value lives only inside the sandbox for the run; it is
never returned to the UI and never stored in a run's event log.

:::warning
Secrets are the one place where the write-only rule is absolute. Even an agent
inside a run reads the injected environment variable, not the secrets API. The
API surface cannot hand back a stored value to anyone.
:::
