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

# Manage EdgeSpark secrets

> Register, list, and delete EdgeSpark secrets from the CLI, then read them safely at runtime without sending values through LLM APIs.

Secrets are encrypted key-value pairs stored on the platform. Use them for API keys, webhook signing secrets, and other sensitive values you cannot commit to your repository.

<Warning>
  When you run `edgespark secret set`, secret values never go through your terminal, agent context, or third-party LLM APIs such as Anthropic, Google, or OpenAI. EdgeSpark opens a secure browser URL so the human owner can enter the secret value directly.
</Warning>

## Register secret keys

Use the CLI to register secret names:

```bash theme={null}
edgespark secret set STRIPE_SECRET_KEY OPENAI_API_KEY
```

The CLI returns a secure EdgeSpark project URL where a human owner enters the values in the browser. Secret values do not pass through the terminal, CLI output, agent context, or third-party LLM APIs.

This workflow exists specifically to protect secrets from accidental exposure while still allowing an AI coding agent to do the rest of the setup work.

List registered secret names with:

```bash theme={null}
edgespark secret list
```

Delete secrets by name with:

```bash theme={null}
edgespark secret delete OPENAI_API_KEY
```

## Read a secret

Declare the key in `server/src/defs/runtime.ts` first:

```typescript server/src/defs/runtime.ts theme={null}
export type VarKey = never;

export type SecretKey =
  | "STRIPE_SECRET_KEY";
```

Then read it in your route handler:

```typescript server/src/index.ts theme={null}
import { secret } from "edgespark";
import { Hono } from "hono";

const app = new Hono().post("/api/charge", async (c) => {
  const amount = (await c.req.json<{ amount: number }>()).amount;
  const stripeKey = secret.get("STRIPE_SECRET_KEY");

  const response = await fetch("https://api.stripe.com/v1/payment_intents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${stripeKey}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      amount: String(amount),
      currency: "usd",
    }),
  });

  return c.json(await response.json());
});

export default app;
```

## Environment scope

Secrets are environment-scoped. Today, new projects expose one default production environment, so you set and read secrets for that current environment.

<Warning>
  Public staging support is coming soon. When it lands, staging and production will have separate secret stores. See [platform limits](/reference/limits) for naming and quota constraints.
</Warning>

## See also

<Columns cols={2}>
  <Card title="secret reference" icon="code" href="/sdk/secrets">
    The runtime API for reading secrets by name.
  </Card>

  <Card title="Development workflow" icon="workflow" href="/guides/development-workflow">
    How secrets fit into the full repo-based workflow for schema, storage, auth config, vars, and deploys.
  </Card>
</Columns>
