Keep API keys and settings out of chat: global secrets reach every session, session secrets reach one.
A secret is a named value, such as STRIPE_SECRET_KEY, that Alpha hands to your session’s machine as an environment variable. The agent’s commands, the apps it starts and the Shell read it, and the value never passes through the transcript. If the service has a ready connector, such as Gmail or Notion, sign in under Integrations instead.
Never paste a key into the composer. Anything you send lands in the transcript and in the agent’s context. When your draft holds something shaped like a credential, a warning appears above the composer: “That looks like a Stripe secret key. Keys typed here land in the transcript — add it under Secrets instead, and the agent gets it as an environment variable.” It doesn’t block sending.
For global secrets, click your name at the bottom of the sidebar and choose Global secrets. For a session, click + at the end of the workspace’s tab strip and choose Secrets, or click the Secrets tab if it is already open. Viewers of a shared session don’t get this tab.
2
Click Add secret
The Add secret form opens: “An environment variable for the commands the agent runs, from its next command on.”
3
Fill in Name and Value
Type the name your code reads, such as STRIPE_SECRET_KEY, and paste the value. Value is a single-line field, so a service-account JSON goes in as one line.
4
Choose Available in
From a session’s tab, pick This session (“Only here; beats a global of the same name”) or Global (“Every session you own”). The account menu skips this choice and always saves globally.
From a session, Available in asks where the secret goes, and This session is picked first.
5
Save the secret
Click Add secret. The new row appears in the list. If the name already exists there, the form says “STRIPE_SECRET_KEY is already set there — saving replaces its value.” and the button reads Save.
New commands see the secret right away, even in running sessions. Anything already running, such as a dev server, keeps its old environment until it restarts. Ask the agent to restart it, or click Restart shell in the Shell.
In the Add secret form, click Paste a .env instead. The title changes to Paste a .env.
Paste the file into .env contents. Each line holds one NAME=value. Blank lines and # comments are ignored, export NAME=value lines work, and quotes around a value are removed.
Tick Replace values that are already set if the paste should overwrite names you already have. Left unticked, those names are skipped as “already set”.
Choose Available in if you are in a session, then click Import.
Names you already have are skipped unless you tick Replace values that are already set.
If anything is skipped, the paste stays on screen so you can fix it and import again. Add one instead switches back to the single form.
The eye for Reveal is always on a row. The other actions appear when you hover it.
Action
What it does
Reveal / Hide (eye)
Shows the full value in place. Closing the dialog or the tab, or switching sessions, hides it again.
Copy value
Copies the value to your clipboard without showing it.
Replace value (pencil)
Opens Replace STRIPE_SECRET_KEY with a New value field. The name can’t change; to rename, add a new secret and delete the old one.
Delete (bin)
Asks “Delete STRIPE_SECRET_KEY? Sandboxes already running keep it until they restart.” There is no undo.
Values of 12 or more characters show their last four, so you can tell two keys apart without revealing either. Deleting a session secret that shadowed a global one brings the global value back for that session.
The agent is told never to ask for keys in a message. When its work needs a key you haven’t added and no connector covers the service, it posts a card, then carries on with whatever doesn’t need the key and finishes its turn.
Click Add STRIPE_SECRET_KEY on the card. The Add secret form opens with the name filled in and locked, because the agent’s code depends on that exact name.
Paste the value and click Add secret. It saves to this session.
The card changes to “STRIPE_SECRET_KEY is added”, with “It is in the agent’s environment from its next command.”
Click Tell the agent to continue. Alpha sends “I added STRIPE_SECRET_KEY under Secrets — it is in your environment now. Continue.” and the button reads Told the agent.
The request also waits in a tray above the composer, “Add STRIPE_SECRET_KEY · the agent asked for it”, with Add and then Continue, so it never scrolls away. While that tray row is showing, adding the key from either place tells the agent on its own, so you don’t need step 4. The agent is told once, whichever button you use. Viewers of a shared session see the card without its buttons.The agent’s own reach is deliberately narrow:
The agent can
The agent can’t
List the names of this session’s secrets and of your global ones
Read a value through Alpha. Its commands return names only.
Ask you for a key with a card, once per name every two minutes
Add or change a global secret
Save a value it generated itself, such as a random SESSION_SECRET, as a new session secret
Replace a session secret that is already set
Read secrets from its environment, like your app does
Delete a secret. Only you can, from the list.
A session secret the agent saves wins over a global one of the same name in that session, as one of yours would.
Alpha replaces any secret value of 8 or more characters with [redacted] wherever it appears verbatim. That covers the transcript, publish and setup logs, session search, and files that viewers of a shared session open. Your GitHub token and your sessions’ tools keys are masked the same way.A few values are left visible because masking them would only hide ordinary text: the words production, development, localhost, postgres and postgresql, an email address, and a plain web address with no credentials in it. So https://api.openai.com/v1 shows, while a webhook URL or a database URL with a password stays masked.
Masking works only on exact matches. Output that transforms a value, such as base64-encoding it, printing part of it or reversing it, can still expose it. Values under 8 characters are never masked.
Published apps don’t receive your secrets automatically. When you publish, you pick which ones production gets under Environment. See Publish your app.
If a save is refused, the form shows one of these messages.
Rule
Message you see
Names start with a letter or _, then letters, digits and _, up to 64 characters
”name must start with a letter or _ and contain only letters, digits and _ (max 64 chars)“
Names the machine’s shell depends on are reserved
”PATH is reserved — setting it would break the sandbox shell”
A value can’t be empty
”value must not be empty”
One value is at most 8 KB (default)
“value must be at most 8192 bytes”
At most 256 secrets in one place
”at most 256 secrets“
Values in one place: at most 32 KB in total (default)
“secrets total would exceed …”, followed by the cap in bytes
The reserved names are PATH, HOME, PWD, OLDPWD, USER, LOGNAME, SHELL, SHLVL, PS1 to PS4, IFS, ENV, BASH_ENV, SHELLOPTS, BASHOPTS, NODE_OPTIONS, PYTHONPATH, PYTHONSTARTUP, PERL5OPT, TMPDIR, TERM, LANG and CODEX_HOME, plus any name starting with LD_ or FORGE_. Case doesn’t matter.Your global secrets and each session’s own secrets are counted separately. A trailing newline from copy and paste is dropped when the value is saved. Every limit is also listed in Limits.