Set up your secret store
Your project needs credentials to run: a session signing key, OAuth client secrets, a payments token. None of them can live in Git, so NuxtStart keeps them in Infisical and reads them when the applications start.
Follow this page once. Afterwards, configuring a new deployment is a folder you fill in.
New to Infisical? You don't need to learn the product first. Three of its concepts map onto NuxtStart, and the steps below use only those three:
- A project is one application. You create two: one for
apps/web, one forapps/site. - An environment is a secret tier. You get
development,staging, andproduction. - A folder is one runtime context. Local development reads
/local.
Environment values explains why it's arranged that way. You don't need it to finish this page.
Prerequisites
- An Infisical account. The free plan covers everything here.
- Your project cloned, so you can edit
apps/web/.env.infisicalandapps/site/.env.infisical.
Create your projects
Create two projects
Create one project for apps/web and one for apps/site. Name them so you can tell them apart. See
Infisical projects.
Rename the environment slugs
A new Infisical project ships with the slugs dev, staging, and prod. NuxtStart asks for
development, staging, and production. In each project, go to Project > Settings >
Environments and rename the slugs:
| Ships as | Rename the slug to |
|---|---|
dev | development |
staging | staging |
prod | production |
The slug is the part everything addresses. The display name beside it is yours. Renaming edits the environment in place, so any secrets already in it survive.
Do this before anything else. A project still on dev is asked for an environment it doesn't have,
and every command that reads a secret then fails there instead of failing on what you were changing.
Copy each project ID into your repository
Go to Project > Settings > General and copy the Project ID. Then replace
REPLACE_ME in that application's .env.infisical:
# @initInfisical(
# projectId=REPLACE_ME,
Do the same for apps/site/.env.infisical with the other project's ID.
A project ID names a project without granting access to it, which is why it's committed.
Create the folders
Go to Project > Secrets in the apps/web project and select the development environment.
Select the chevron next to Add Secret, then Add Folder, and create three folders: local,
preview, and development. See
Infisical folders.
Nothing else needs folders. The staging and production environments keep their secrets at the
root, and apps/site stores no secrets at all.
Create a machine identity for your machine
Your machine signs in to Infisical as a machine identity, using a client ID and client secret pair. Machine identities creates it and adds it to both projects — one identity per person, reused by every project you own.
Come back here with its Client ID and Client Secret.
Connect your machine
Create a gitignored .env.local in each application and paste the pair into both files:
INFISICAL_CLIENT_ID=<your client ID>
INFISICAL_CLIENT_SECRET=<your client secret>
Both applications sign in separately, so both files need the values.
Add the credentials
Go to Project > Secrets in the apps/web project, select the development environment,
open the local folder, and add every key from the table below.
What to put in the /local folder
All of these belong to apps/web. Needed for names the feature each key serves and the layer
that feature comes from, so you can tell which keys you need today.
| Key | Comes from | Needed for |
|---|---|---|
NUXT_BETTER_AUTH_SECRET | openssl rand -base64 32 | Every sign-in (@app/layer-auth). Rotating it ends every session |
GOOGLE_CLIENT_SECRET | Your Google OAuth client | Google sign-in (@app/layer-auth) |
GITHUB_CLIENT_SECRET | Your GitHub OAuth app | GitHub sign-in (@app/layer-auth) |
POLAR_ACCESS_TOKEN | Your Polar organization | Payments (@app/layer-payments) |
NUXT_WEBHOOK_POLAR_SECRET_KEY | Your Polar webhook | Payments (@app/layer-payments) |
NUXT_EMAIL_PLATFORM_ADMIN_EMAILS | Addresses you choose | Platform alerts (@app/layer-email). Optional — leave it empty to turn them off |
Set up sign-in and payments creates the Google, GitHub, and Polar side of these.
NUXT_EMAIL_PLATFORM_ADMIN_EMAILS has to hold a
value before apps/web starts, so put REPLACE_ME in the ones you're skipping. The product starts,
and only the feature that reads the key fails when you first use it. Do this in /local only — in a
deployed context, a placeholder makes a deploy succeed against a fake credential instead of failing
where you can see it.Two values that look like they belong here don't:
DATABASE_URLis per machine locally, so it goes inapps/web/.env.local.GOOGLE_CLIENT_IDandGITHUB_CLIENT_IDgo in the committedapps/web/.env.development. Environment values explains why an OAuth client ID isn't a secret.
Setting up a deployed context
Everything above is the same for preview, development, staging, and production. Only two
things change: which folder you fill in, and how the build signs in.
A GitHub Actions runner never uses your client ID and secret. It signs in with OIDC, as one of two identities bound to your repository.
- Machine identities creates those two, with the subject and audience each one needs
- Which folder each context reads
Troubleshooting
| What you see | What to fix |
|---|---|
Infisical authentication is required | The client ID and secret in that application's .env.local |
| An error naming an environment | The environment slugs aren't renamed yet |
| An error naming a single key | That key is missing from the folder for the context you're running |
| Secrets resolve, but they're the wrong ones | You're running in a different context than you expected |
Next steps
- Set up sign-in and payments — create the credentials this page asks for
- Local setup — the guide that sends you here
- Environment values — why the store is arranged this way
