Skip to main content
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.

Global or session: where should a secret live?

The Harbor bookings session with the Secrets tab open in the workspace, whose tab strip reads Plan, Preview, Shell, Database, Secrets with its ×, README.md and server.js, followed by +, the GitHub and Share icons, Publish and the files button. The chat on the left shows an answered The agent has questions card and a Proposed plan card titled Automatic class waitlist, above the composer's placeholder Describe what to plan…. In the Secrets tab, a section headed This session holds the card This session's key, with FORGE_TOOLS_URL reading https://alpha.new/api/tools/v1, FORGE_TOOLS_API_KEY masked as dots, and the buttons Reveal, Copy .env lines and Rotate. Below it, a section headed Secrets, with the caption environment variables for this session and an Add secret button at the right, holds a panel with two empty groups: GLOBAL reads None — global secrets reach every session you own., and THIS SESSION reads None — a secret here reaches only this session. Under the panel, a grey note reads Anything the agent runs can read them — only add what you'd hand the agent directly. Values of 8+ characters are replaced with [redacted] in the transcript when they appear verbatim; output that transforms a value can still expose it.

One list shows what this session gets: your global secrets above, its own below.

Anything the agent runs can read your secrets, and so can the app it builds. Only add what you’d hand the agent directly.

Add a secret

1

Open a list of secrets

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.
The Add secret dialog, with a close button at its top right. The description reads: An environment variable for the commands the agent runs, from its next command on. The Name field shows the placeholder STRIPE_KEY in monospace. The Value field is empty, with an eye button at its right edge. Under the heading Available in, two option cards sit side by side: This session, selected with a check mark, with a key icon and the line Only here; beats a global of the same name, and Global, with a globe icon and the line Every session you own. The footer holds Paste a .env instead on the left, then Cancel and a dimmed Add secret on the right.

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.

Import a .env file

  1. In the Add secret form, click Paste a .env instead. The title changes to Paste a .env.
  2. 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.
  3. 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”.
  4. Choose Available in if you are in a session, then click Import.
The Paste a .env dialog, with a close button at its top right. The description reads: An environment variable for the commands the agent runs, from its next command on. The empty .env contents box shows two placeholder lines in monospace, STRIPE_KEY=sk_live_… and GITHUB_TOKEN=ghp_…. Below the box, the checkbox Replace values that are already set is unticked. Under the heading Available in, the cards show This session selected with a check mark, Only here; beats a global of the same name, and Global, Every session you own. The footer holds Add one instead on the left, then Cancel and a dimmed 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.

Copy, replace or delete a secret

The eye for Reveal is always on a row. The other actions appear when you hover it. 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.

What happens when the agent needs a key?

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.
  1. 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.
  2. Paste the value and click Add secret. It saves to this session.
  3. The card changes to “STRIPE_SECRET_KEY is added”, with “It is in the agent’s environment from its next command.”
  4. 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: A session secret the agent saves wins over a global one of the same name in that session, as one of yours would.

How are values hidden in the transcript?

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.

Name rules and limits

If a save is refused, the form shows one of these messages. 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.

Next steps

Connect an app

Sign in to Gmail, Slack or Notion once, so the agent gets tools rather than a raw key.

Use integrations in your app

What “This session’s key” is for, and the two lines an exported app needs in its .env.

Publish your app

Choose which secrets production gets, at build time and at runtime.

The Shell

Check a variable with printenv, and restart the shell to load a secret you added since it opened.