Model
Secrets are a vault on a claimed site. Values are encrypted at rest; only names are listed. MCP does not set secrets — claim first, then use UI, CLI, or API.
Project UI
- Claim the site (see Claim).
- Open the project → Secrets.
- Add name + value → Save.
CLI
aft login
cd your-project # aft.json / .aft/state.json present
aft env list
aft env set ANTHROPIC_API_KEY=sk-…
aft env set OTHER_KEY "value with spaces"
aft env unset ANTHROPIC_API_KEY
Requires login and ownership of the claimed site. Same vault as the dashboard.
API
# names only
curl https://api.aft.page/v1/sites/{slug}/secrets \
-H "Authorization: Bearer …" # or Cookie session
curl -X PUT https://api.aft.page/v1/sites/{slug}/secrets/ANTHROPIC_API_KEY \
-H "Content-Type: application/json" \
-H "Authorization: Bearer …" \
-d '{"value":"sk-…"}'
curl -X DELETE https://api.aft.page/v1/sites/{slug}/secrets/ANTHROPIC_API_KEY \
-H "Authorization: Bearer …"
aft.json capabilities
Declare intended names so approve-on-deploy can show them:
{
"name": "my-app",
"runtime": "next",
"capabilities": {
"secrets": ["ANTHROPIC_API_KEY"],
"egress": ["api.anthropic.com"]
}
}
Static vs runtime
Secrets are not baked into static HTML. A Vite SPA that needs a public API URL should use a public env prefix at build time. Keep private keys in the vault for worker / next runtimes that can read them at request time.