The split
Setup handles supplied and materialized credential values in memory and
attempts persistence through installed Phantom. Dedicated secrets in
.stack.toml record the slot name; manual fields and
freeform metadata can contain user data and must be reviewed before sharing.
- ● Drives provider OAuth / API flows
- ● Creates or attaches resources according to the adapter
- ● Tracks which secrets each service needs (slot names)
- ● Exports empty-key
.env.exampleskeletons separately; writes available.mcp.jsondescriptors - ○ Handles credential values during setup
- ● Provides the installed credential-persistence interface
- ● Owns supported execution;
phm_*strings are not generally resolved by Stack - ● Requires separately qualified sync and CI configuration
- ● Controls credential access through its installed interface
- ○ Has no opinion on what the keys mean
Why Stack refuses to run without Phantom
When you run stack add, stack import, or stack doctor, Stack calls phantom via its CLI. If
Phantom setup is missing or its project metadata is unavailable, the
credential-writing path refuses before provider contact. Illustrative refusal:
$ stack add supabase
Phantom Secrets isn't installed.
Blank stack init can write split config without provider setup.
Selected template init attempts setup by default; use --noProvision
for config only. Other read-only commands have their own requirements.
The flow of a single secret
Take SUPABASE_SERVICE_ROLE_KEY as an example:
-
You run
stack add supabase. -
Where the OAuth branch is configured, Stack opens Supabase authorization and listens on
http://127.0.0.1:8787/callback— register that exact URI as the allowed redirect in your OAuth app so no wildcard matching is needed. -
The adapter can create a project through the Management API or attach an
existing resource; access and outcomes must be checked (example ref:
abcdefghijklmnop). -
The adapter attempts to fetch the
service_rolekey. Setup processes credential values in memory. -
Stack submits
SUPABASE_SERVICE_ROLE_KEYthrough the supported create-only Phantom stdin interface. Existing names, missing setup or refused persistence can stop the operation. -
Stack writes
secrets = ["SUPABASE_SERVICE_ROLE_KEY"]into.stack.toml. Earlier credential and MCP writes can remain if later writes fail. -
Run
stack env export --exampleseparately for an emptySUPABASE_SERVICE_ROLE_KEY=skeleton; Stack does not regenerate populated env files.
phm_ strings before sharing. Stack does
not establish their safety or general substitution behavior.
phantom exec is an installed-product interface that
stack exec forwards to; follow its supported configuration
and verify the actual consumer.
Runtime injection — stack exec
Configure the application inputs required by process.env
using the installed Phantom guidance. The Stack wrapper alone does not
establish that they are supplied:
# Ordinary app startup; configure required inputs first
bun dev
# Forward through installed Phantom exec; verify the app receives its inputs
stack exec -- bun dev stack exec forwards everything after -- to
phantom exec. Use it for dev servers, test runners, migrations —
only after the app and installed execution path are configured and verified.
Syncing the vault
Sync and CI bootstrap belong to the installed Phantom product. Check its current capabilities and configuration before transferring any credentials:
# Inspect the installed interface before planning sync
phantom --version
phantom --help stack ci init (see CI integration)
now refuses workflow generation with exit 1 before creating a workflow directory or writing a file. Its config and existing-file guards remain; stack ci init --force also refuses without overwriting. Phantom Secrets 0.7.9 requires a trusted terminal for Cloud pull; --force does not bypass it, and PHANTOM_CLOUD_TOKEN is not a supported bearer-token input. The local vault passphrase is separate from the Cloud encryption key. No unattended Cloud bootstrap is provided.
Which Stack commands talk to Phantom
| Command | Needs Phantom? | What it does with the vault |
|---|---|---|
stack init | Config-only: no; service setup: required | Blank/config-only init writes split config; selected templates attempt setup. |
stack add | Yes | Writes provisioned secrets into the vault. |
stack import | Yes | Attempts nonempty parsed values; existing vault names are skipped and writes can fail. |
stack remove | Yes | Attempts named-secret cleanup; headless or refused cleanup can keep keys. |
stack env show / diff | Yes | Reads the vault's key list (never the values). |
stack doctor | Yes | Runs available adapter checks; some are absent or limited. |
stack exec | Yes | Forwards to phantom exec — verify installed execution and the app separately. |
stack list, stack info | Command-dependent requirements | List reads config; info checks slot presence and may run an adapter health check. |
stack providers, stack templates list, stack projects list | No | Static catalog / registry data. |
Installing Phantom
Follow the Phantom Secrets setup guidance for your platform and verify its credential and execution interfaces. Stack source and this example do not establish an installed version or completed vault setup.
# Inspect the installed product before configuring Stack
phantom --version
phantom --help For the full Phantom story, see Phantom phm.dev ↗ .