---
title: "Store or replace a secret that sandboxes use without seeing it."
method: PUT
path: "/v1/egress-secrets/{name}"
tags: ["secrets"]
---

# Store or replace a secret that sandboxes use without seeing it.

`PUT /v1/egress-secrets/{name}`

## Request

- Base URL: `https://api.withruntime.com`
- URL: `https://api.withruntime.com/v1/egress-secrets/{name}`
- Auth: HTTP bearer

Every sandbox of the organization (or, with only, the sandboxes it names by label or id, and every copy of the Apps it names) gets an environment variable of this name holding a placeholder. With header set, the egress proxy sets that header on every HTTPS request to the hosts and puts the value nowhere else; without, it replaces the placeholder with the value in a credential header (Authorization, x-api-key, x-goog-api-key, api-key, xi-api-key, x-subscription-token, private-token). A placeholder in the URL or any other header goes out as it is, so a server that echoes a request back never shows the value. With rules (an account with credit), only requests whose method and path a rule allows carry it. The value is sealed to the hosts' key and never returned. Replacing a secret keeps its placeholder. Takes effect on new connections within seconds.

## Path parameters

- `name` string, required: The environment variable the placeholder is in, inside every sandbox of the organization. Upper case letters, digits and underscores.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `value` string, required: The secret. Visible ASCII and spaces, at most 8 KiB. Stored sealed and never returned.
  - `hosts` string[], required: Where the value may go. The proxy puts it only into HTTPS requests to these hosts.
  - `header` string: Optional. Set this header on every request to the hosts, replacing one the sandbox sent, so code needs no placeholder at all; the value then goes into this header and nowhere else. Without it, the placeholder is replaced only in a credential header: Authorization, x-api-key, x-goog-api-key, api-key, xi-api-key, x-subscription-token, private-token.
  - `format` string: Optional, with header. The header's value, with {value} where the secret goes. Default "{value}".
  - `rules` object[]: Optional, for an account with credit. The value goes only into requests a rule allows, by method and path. A request whose path could be read two ways (an encoded slash, a semicolon, a backslash) gets no secret that has rules. Absent: every request to the hosts. Replacing a secret without rules clears them.
    - `methods` string[]: Optional. The methods allowed; every method when absent.
    - `paths` string[], required: Exact paths, or prefixes ending in /* for every path under them. Written canonically: starting with /, no . or .. segments, no ; or \, no encoded slash. An escaped character other than a letter, digit, -, ., _ or ~ matches only the same escape: a client that sends %3A needs a rule with %3A, not :.
  - `only` object: Optional. Which sandboxes get the secret: those matching labels, those named in sandboxes, and every copy of the Apps named in apps. Any other sandbox of the organization sees no placeholder and its requests never carry the value. {} gives it back to every sandbox. Absent when replacing a secret: the scope it has stays, so a new value never widens who gets it. Absent on a new secret: every sandbox, as before.
    - `labels` object[]: Sandboxes whose labels match any one of these selectors get the secret, including ones created or labelled later.
    - `sandboxes` string[]: These sandboxes (ids of this organization's sandboxes) get the secret.
    - `apps` string[]: Every copy of these Apps or Functions (their ids) gets the secret, whatever its version: copies made by later deploys, restarts and scaling too. A deploy names the secrets its copies see as environment variables (secrets on POST /v1/apps/{id}/deploys).

## Response `200`

Success

- object
  - `name` string
  - `hosts` string[]
  - `header` string
  - `format` string
  - `rules` object[]: Optional, for an account with credit. The value goes only into requests a rule allows, by method and path. A request whose path could be read two ways (an encoded slash, a semicolon, a backslash) gets no secret that has rules. Absent: every request to the hosts. Replacing a secret without rules clears them.
    - `methods` string[]: Optional. The methods allowed; every method when absent.
    - `paths` string[], required: Exact paths, or prefixes ending in /* for every path under them. Written canonically: starting with /, no . or .. segments, no ; or \, no encoded slash. An escaped character other than a letter, digit, -, ., _ or ~ matches only the same escape: a client that sends %3A needs a rule with %3A, not :.
  - `only` object: Optional. Which sandboxes get the secret: those matching labels, those named in sandboxes, and every copy of the Apps named in apps. Any other sandbox of the organization sees no placeholder and its requests never carry the value. {} gives it back to every sandbox. Absent when replacing a secret: the scope it has stays, so a new value never widens who gets it. Absent on a new secret: every sandbox, as before.
    - `labels` object[]: Sandboxes whose labels match any one of these selectors get the secret, including ones created or labelled later.
    - `sandboxes` string[]: These sandboxes (ids of this organization's sandboxes) get the secret.
    - `apps` string[]: Every copy of these Apps or Functions (their ids) gets the secret, whatever its version: copies made by later deploys, restarts and scaling too. A deploy names the secrets its copies see as environment variables (secrets on POST /v1/apps/{id}/deploys).
  - `reaches` object: Present when only is set (in GET /v1/egress-secrets): the sandboxes that get the secret now, worked out as the servers do. A label matches only sandboxes made by a key outside every compartment. Absent: every sandbox of the organization gets it.
    - `count` integer, required: How many sandboxes get it now.
    - `sandboxes` string[], required: The first 50 of their ids.
  - `placeholder` string: What the sandbox sees in the environment variable. Without header, the proxy replaces it with the value in a credential header (Authorization, x-api-key, x-goog-api-key, api-key, xi-api-key, x-subscription-token, private-token) of HTTPS requests to the hosts; in the URL or any other header it goes out as it is.
  - `valueBytes` integer
  - `createdAt` string, date-time
  - `updatedAt` string, date-time
  - `enforced` boolean: True when every server running the organization's sandboxes, and every server still holding an earlier version, confirmed the change; a sandbox that starts or wakes later is given it before it runs. False while a server has not confirmed it yet: each server asks Runtime for changes every 15 seconds, and one that has not heard from Runtime for a minute sends no secret's value until it has.

## Other responses

- `default`: Error

---

[API](https://skmtc.dev/withruntime/apis/runtime-cloud-api.md) · [All operations](https://skmtc.dev/withruntime/apis/runtime-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/withruntime/apis/runtime-cloud-api/revisions/6f4012286988?raw)
