# Settings and secrets

The values your app needs, kept off your computer.

Apps often need a key for an email service, a payment provider or an external API. The command finds every setting the code reads (`process.env.RESEND_API_KEY` and the like) and asks for the ones it does not already provide:

```
secrets   3 required - RESEND_API_KEY missing
          ? paste value, or press enter to skip and set later
```

## Where values live

On the platform, encrypted. Never in the code, never in `deploy.json`, never in the source we keep for you. When you [clone an app to another computer](/docs/another-computer), the secrets stay behind and the app keeps working because the platform still has them.

## Setting or changing one later

- Ask your AI: "set RESEND_API_KEY for the family app to ...".
- Or from the dashboard: the app's **Settings** tab, under *Settings your app needs*.
- Or from a terminal: `npx uarpie deploy -e RESEND_API_KEY=...`.

A change made on the **Settings** tab, or by your AI, creates a new version without rebuilding the app, so it takes about half a minute and shows up in **Versions** like any other change. A setting the app reads while it is built (a `NEXT_PUBLIC_` or `VITE_` one, for example) is built into it, so changing one rebuilds the app; and `npx uarpie deploy -e` sends the code as well, so it builds too.

## Provided for you

These are set for you and never need a value from you: `PORT`, `UARPIE_PROJECT_ID`, `UARPIE_PROJECT_URL`, `UARPIE_JWKS_URL`, `UARPIE_ENV`, `AUTH_TRUST_HOST`; `DATABASE_URL` when the app uses a database; `UARPIE_STORAGE_BUCKET` and `UARPIE_STORAGE_PREFIX` when it stores files.

## Your app's address

Every request tells the app which address the visitor used: `X-Forwarded-Host` holds it (your custom domain as well as the app's own address) and `X-Forwarded-Proto` is `https`. The platform sets both and replaces anything a visitor sends. The `Host` header is the app's internal name, so read the address from `X-Forwarded-Host`. Outside a request, for example in a scheduled job, `UARPIE_PROJECT_URL` is the uarpie.app address.

- **Next.js** reads it already. Forms and Server Actions need no setting.
- **Auth.js** (next-auth 5) needs no setting: `AUTH_TRUST_HOST` is set, so it takes the address from `X-Forwarded-Host` and people sign in on whichever address they opened. Leave `AUTH_URL` and `NEXTAUTH_URL` unset: either one moves every sign-in to that one address, and signing in then fails for anyone who opened the other one. Add the sign-in callback for each address to your Google or GitHub settings.
- **NextAuth 4** signs people in the same way, but its middleware (`withAuth`) only finds the sign-in cookie when `NEXTAUTH_URL` starts with `https://`. If the app uses that middleware, set `NEXTAUTH_URL` to the one address people sign in on.
- **Payload**: if `payload.config` sets `csrf` or `serverURL`, list every address people use in `csrf`, your custom domain included. With a list set, Payload ignores the sign-in cookie on any request whose `Origin` is not on it, so saving in the admin fails.
- **Django** needs `USE_X_FORWARDED_HOST = True` and `SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")` in settings. Then `ALLOWED_HOSTS` and form checks work with the real address.
- **Astro**, when it runs as a server (`@astrojs/node`), needs `security: { allowedDomains: [{ protocol: "https" }] }` in `astro.config.mjs`. Without it Astro takes its own address to be `http://localhost`, so it refuses every form the app's own pages send ("Cross-site POST form submissions are forbidden") and `Astro.url` gives wrong links. With it, Astro reads the address from `X-Forwarded-Host`, your custom domain included, and still refuses forms sent from other sites. It is safe here because the platform sets that header itself.
- **SvelteKit** needs no setting: the platform tells it to read the address from `X-Forwarded-Host`.

## Limits

All settings together must fit in 4 KB, which is plenty for keys. The ones Uarpie adds for the database, files and sign-in take part of that space; if everything does not fit, the deploy says which ones to shorten. For anything larger (a certificate, a big JSON blob), put the file in storage and keep only its name in a setting.
