Secrets in a workshop
How API keys are handled, why the agent never asks for them in chat, and what to do if one leaks.
This page is about Claude Code workshops — the ones you
clone to your machine and run in a terminal. They use the lwc
store and .env files described below. Cowork workshops run in
your Claude session and don't hold API keys on your machine; if one ever
needs a credential it asks in-flow and the same "never in chat" rule
applies.
What counts as a secret
Anything a provider treats as a bearer credential: an
ANTHROPIC_API_KEY, a third-party provider token, an OAuth
refresh token. Each workshop's spec names the secrets it needs; the
handling described on this page is the same across all of them.
Why the agent never accepts a secret in chat
Chat goes into the transcript. Transcripts can be reviewed in support tooling, exported by you, replayed in future sessions, and pasted into screenshots. A key dropped into chat is a key on disk in a file you don't fully control.
The same applies to running !export ANTHROPIC_API_KEY=…
through the bash prefix — the whole command, including the value, lands
in chat history. The agent will decline both and point you at one of the
flows below.
The three flows we support
| Flow | Where it lives | When to use it |
|---|---|---|
lwc env set | ~/.lwc/env.json, chmod 600. Picked up by
every workshop automatically.
| The default. Hidden prompt, no echo, one place to manage keys. |
| Shell export | The current shell's environment. Evaporates when the shell closes. | Power-user / one-off sessions where persistence isn't wanted. |
.env file |
Workshop root, gitignored. Loaded by
tsx --env-file-if-exists.
| Per-workshop overrides, or when a workshop needs a value the global store doesn't carry. |
If you accidentally leaked a key
- Revoke it at the provider's console — for Anthropic, that's console.anthropic.com → API Keys → Revoke.
- Rotate any downstream consumers that were using the old value.
- Don't try to scrub the transcript. Once a value lands in chat, treat it as leaked and replace it. Cleanup theatre doesn't move the threat model.
Threat model
Filesystem permission is the boundary, not encryption-at-rest. This is the
same posture as ~/.aws/credentials or a .env
file: anyone who can read the file as your user can use the key. We
don't encrypt ~/.lwc/env.json because anyone with that level
of filesystem access already has whatever the key would have protected.
The agent's job is to make sure secrets never end up somewhere weaker than that — chat history, screenshots, exported transcripts. Everything on this page is in service of that single line.