Secrets & Providers
SaaSyBase is env-driven by default. Most teams should use platform-native encrypted env vars on Vercel, Coolify, Render, Railway, Docker, or a VPS. If you want a centralized secret store, the app can optionally bootstrap missing values from Infisical or Doppler before build, start, and Prisma commands run.
Default recommendation
| Environment | Recommended secret source | Why |
|---|---|---|
| Local development | .env.local | Fastest setup and easiest debugging |
| Hosted platforms | Platform-native encrypted env vars | Least moving parts and no extra bootstrap credentials |
| Teams wanting a shared secret store | Infisical or Doppler bootstrap | One source of truth across multiple platforms |
Tip
Built-in provider bootstrap
The bootstrap is opt-in. Set SECRETS_PROVIDER to infisical or doppler, and SaaSyBase will load dotenv files first, keep any existing env vars, then ask the provider CLI for any missing secret values.
Tip
SECRETS_PROVIDER_SECRETS only when you want to narrow bootstrap to a specific subset.Note
SECRETS_PROVIDER_SECRETS, every required variable outside that allowlist must already exist in platform envs or dotenv files. Narrowing out something critical like DATABASE_URL or AUTH_SECRET will cause boot-time failures.Warning
SECRETS_PROVIDER="infisical"
# Optional
SECRETS_PROVIDER_COMMAND=""
# SECRETS_PROVIDER_SECRETS="DATABASE_URL,ENCRYPTION_SECRET"Tip
Infisical
Default command: infisical export --format json
Official docs: Infisical CLI overview and Infisical export command.
- Install the Infisical CLI on the machine running the app.
- Authenticate that CLI in the current shell with
infisical login. - Find your project id in Infisical and set
INFISICAL_PROJECT_ID. - Set
INFISICAL_ENVIRONMENTto the environment name that contains your secrets. - Run
npm run secrets:smokebefore relying on it fornpm run devor deploy commands. - Run
npm run secrets:doctorif you want to verify the command and output shape before boot.
Install commands by operating system:
brew install infisical/get-cli/infisicalSECRETS_PROVIDER="infisical"
INFISICAL_PROJECT_ID="your-project-id"
INFISICAL_ENVIRONMENT="prod"
# Optional full override
# SECRETS_PROVIDER_COMMAND="infisical export --format json --env prod --projectId your-project-id"Production quick path with machine identity token
Create a Machine Identity in Infisical
Go to your Infisical dashboard → Access Control → Machine Identities → Create. Choose "Universal Auth" as the auth method. This identity represents your server or deployment, not a human user.
Copy the Client ID and Client Secret
After creating the identity, Infisical shows a Client ID and Client Secret. Copy both. These are the credentials your server will use to authenticate. Never commit them to git — store them in your platform's env settings (Vercel, Coolify, systemd file, etc.).
Get an access token using the Infisical CLI
On your server, run the login command below. The CLI exchanges your Client ID and Client Secret for a short-lived access token and sets it in the current shell automatically.
infisical login --method=universal-auth \
--client-id="YOUR_CLIENT_ID" \
--client-secret="YOUR_CLIENT_SECRET"Verify the CLI can export your secrets
Run the command below to confirm authentication works and secrets are accessible.
infisical export --format json \
--projectId "$INFISICAL_PROJECT_ID" \
--env "$INFISICAL_ENVIRONMENT" | head -c 200Run SaaSyBase commands
Once the CLI is authenticated, run the standard app commands. Verify provider access first, apply existing migrations, then build and start. SaaSyBase will use the Infisical CLI to fetch any missing env vars automatically.
npm run secrets:doctor
npm run secrets:smoke
npm run prisma:deploy
npm run build
npm run startMachine identity vs token in Infisical
INFISICAL_TOKEN during infisical export, so your runtime must provide a valid token before app commands run.Tip
infisical export --format json works in the same shell context.Token lifetime behavior
infisical token renew) from the same machine identity workflow instead of assuming an old shell token will still be valid.Note
Doppler
Default command: doppler secrets download --no-file --format json
Official docs: Doppler CLI docs and Doppler secrets access docs.
- Install the Doppler CLI on the machine running the app.
- Authenticate that CLI in the current shell with
doppler login. - Set
DOPPLER_PROJECTandDOPPLER_CONFIGto the project and config that hold your secrets. - Run
npm run secrets:smokebefore relying on it fornpm run devor deploy commands. - Run
npm run secrets:doctorif you want to verify the command and output shape before boot.
Install commands by operating system:
brew install dopplerhq/cli/dopplerSECRETS_PROVIDER="doppler"
DOPPLER_PROJECT="saasybase"
DOPPLER_CONFIG="prd"
# Optional full override
# SECRETS_PROVIDER_COMMAND="doppler secrets download --no-file --format json --project saasybase --config prd"Service token vs service account
DOPPLER_TOKEN (starts with dp.st.) and run commands with that token. A service account is the identity container in Doppler that owns permissions and can mint service tokens. The app/server uses the service token, not a service-account id.Production quick path with service token
Create a Service Token in Doppler
Go to your Doppler dashboard → select your project and config (e.g. "prd") → Access → Service Tokens → Generate. Copy the token (it starts with dp.st.). This token gives your server read access to secrets without needing a browser login.
Add the token to your server environment
Store the token in your platform's env settings (Vercel, Coolify, systemd file, etc.). Never commit it to git.
export DOPPLER_TOKEN="dp.st...."Optional: set explicit project and config scope
Recommended when your Doppler account has many projects or configs. This ensures the CLI reads from the correct one.
export DOPPLER_PROJECT="saasybase"
export DOPPLER_CONFIG="prd"Verify the token can read secrets
Run the command below to confirm the token works and can fetch your secrets.
doppler secrets download --no-file --format json | head -c 200Run SaaSyBase commands with Doppler-provided env
Prefix your app commands with doppler run -- so Doppler injects secrets into the process environment. Verify provider access first, apply existing migrations, then build and start.
doppler run -- npm run secrets:doctor
doppler run -- npm run secrets:smoke
doppler run -- npm run prisma:deploy
doppler run -- npm run build
doppler run -- npm run startDo not expose tokens
DOPPLER_TOKEN like a password with read access to your secret inventory. Do not commit it to git, do not paste real values into docs/screenshots, and rotate it immediately if it was ever exposed.Tip
Common production confusion
doppler run -- npm run build works but direct npm run build fails, your CLI auth is shell-scoped and not present in the runtime process manager. Add DOPPLER_TOKEN to the actual service environment (systemd, platform env settings, or CI secrets), then rerun.Note
Production runbook (recommended order)
- Install provider CLI on the host image or runtime user account.
- Create machine identity credentials in the provider (service token for Doppler, machine token for Infisical).
- Inject that credential into the real runtime environment, not only your interactive shell.
- Run
npm run secrets:doctorandnpm run secrets:smokein that same runtime context. - Run deploy commands in order:
npm run prisma:deploy,npm run build, thennpm run start. - If auth expires or provider access breaks, SaaSyBase now fails fast when critical vars like
DATABASE_URLare missing.
Platform-native envs still work
| Platform | Recommended default | When bootstrap helps |
|---|---|---|
| Vercel | Encrypted project env vars | If you want one shared secret source across multiple deployment targets |
| Coolify | Application secrets/env vars | If your team already standardized on Infisical or Doppler |
| Linux VPS | systemd env file or docker compose envs | If you want centralized rotation outside the host |
| CI pipelines | Native CI secrets | If CI should fetch the same inventory used elsewhere |
Smoke test before deploy
SECRETS_PROVIDER=infisical \
NEXT_PUBLIC_APP_URL="https://staging.example.com" \
AUTH_PROVIDER="betterauth" PAYMENT_PROVIDER="stripe" \
npm run secrets:smokeThe smoke test validates that the final env set is complete after merging local env, platform env, and optional provider bootstrap.
If you want a lower-level preflight first, run npm run secrets:doctor. It executes the provider command directly and reports the detected output shape plus allowlist checks when SECRETS_PROVIDER_SECRETS is set.
Troubleshooting
| Error | Usual cause | Fix |
|---|---|---|
| provider command not found | The provider CLI is not installed or not on PATH | Install the CLI or set SECRETS_PROVIDER_COMMAND explicitly |
| provider auth error | The CLI exists but is not authenticated | Use the provider's machine identity, service token, or login flow |
| Smoke test says a required value is missing | The export ran but the expected env var name was absent | Check the provider project/config and env var names, or set the value directly in platform envs |
| Unexpected bootstrap behavior | Your provider setup needs flags beyond the built-in defaults | Set SECRETS_PROVIDER_COMMAND to the exact export command you want the app to run |
The safest local test is to run the provider export command yourself first. If infisical export --format json or doppler secrets download --no-file --format json fails in your terminal, SaaSyBase will fail too.
If you are still deciding whether to use a provider at all, go back to Getting Started for the simpler SQLite and platform-env path.
Next steps
Continue with the main deployment guide in Deployment. For copy-paste platform examples, read docs/secrets-provider-deploy-examples.md in the repository.

