Environment
What each variable is holding up
Read from a .env at the repository root,
validated once at boot. Nothing here is read lazily, so a missing
value is a startup error and not a surprise on the first request
that needs it.
The server refuses to start without these
Booting without somewhere to send approval requests produces the
worst available failure: over-limit actions pause exactly as they
should and then wait forever, because nothing ever tells a human
they were asked. From the outside that is indistinguishable from a
hung agent, so the server will not do it.
- SMTP_USER required
-
Together with SMTP_PASSWORD, one of the
two transports — the mailbox the approval mail is sent through.
Set one of the pair and not the other and the server stops with
an error naming the missing half. It will not fall back to
Resend: the channel a human is watching must not change because
of a typo.
- SMTP_PASSWORD required
-
An app password, never an account password. Verified with a real
login before the server listens, so a wrong one is a startup
failure rather than a payment that pauses correctly and reaches
nobody.
- RESEND_API_KEY alternative
-
The other transport, used only when the SMTP pair is entirely
absent. It needs an account and a verified sender domain, and
that verification is not instant — set it up well before you
need it.
- APPROVAL_FROM_EMAIL required
-
The address the approval mail is sent from. On Gmail SMTP it
must be the SMTP_USER mailbox or one of
its verified aliases; Gmail silently rewrites anything else, and
the mail arrives from an address you did not choose.
- APPROVER_EMAIL required
-
Where approval requests land. One approver per deployment for
now — per-project approvers would need a column on the projects
table.
- PUBLIC_BASE_URL required
-
The origin the approval link is built on, with trailing slashes
stripped. It must be publicly reachable. This is the one
required variable whose validation cannot save you: any
well-formed URL passes, so a stale tunnel address boots cleanly
and mails links to a host that no longer exists.
These turn features on when you set them
All optional. Leave them out and the server runs exactly as
before, minus the feature — never with the feature quietly
half-on.
- ANTHROPIC_API_KEY classifier
-
Powers the risk classifier. Without it the server runs a stub
that refuses every classification and sends the action to a
person — so a policy that opened methods to a classifier that
was never configured produces approval emails rather than
unattended writes. A missing key must not be a quiet upgrade in
what an agent may do on its own. The demo agent reads the same
variable.
- GITHUB_CLIENT_ID
-
From the GitHub OAuth app. Public; it travels in the redirect
URL.
- GITHUB_CLIENT_SECRET
-
Secret. Never logged, never rendered, never leaves the token
exchange.
- GITHUB_REDIRECT_URI
-
Must match the callback registered on the OAuth app exactly,
including scheme and port. Deliberately its own variable rather
than derived from PUBLIC_BASE_URL: that
one points at a tunnel whose hostname changes every restart, and
a moving callback is a login that breaks every morning. All
three are optional together — without them the dashboard serves
a page explaining how to configure it rather than a broken login
button.
These have defaults worth knowing
Leave every one of them unset and the server still starts and
still behaves correctly. They are here because the defaults are
the ones you will want to change first.
- PORT 3000
-
Change it and your tunnel command changes with it, or the
approval links point at nothing.
- ADEIA_DB_PATH ./adeia.db
-
The SQLite file. Delete it between rehearsals for a clean trail;
tests use an in-memory database instead.
- NODE_ENV development
-
One of development,
test or
production. Anything else fails
validation rather than being treated as unset.
- SMTP_HOST smtp.gmail.com
-
Only read when the SMTP pair is set. Any mailbox that speaks
SMTP works; the default is just the one most people already
have.
- SMTP_PORT 465
-
465 is implicit TLS, 587 is STARTTLS. Pick the one your provider
documents — the wrong one shows up as a connection failure at
boot.
- APPROVAL_TOKEN_TTL_MS 86400000
-
Twenty-four hours. When it lapses the action moves to
expired rather than sitting in
pending_approval forever, which is what
lets a waiting agent stop waiting.
- ADEIA_SITE_ORIGINS localhost:5173
-
Comma-separated origins allowed to call the public site
endpoints. The site is served from a different port than the API
in development, so the origin has to be named rather than
assumed.
- ADEIA_TRUST_PROXY false
-
Whether x-forwarded-for can be
believed. Off by default, because anyone can send that header.
Turn it on only behind a proxy that overwrites it.
- ADEIA_VISIT_SALT adeia-dev-salt
-
Salt for the visitor hash. No address or user agent is stored,
only a hash of them, and the salt is what keeps that hash from
being trivially reversible over so small an input space. Set a
real value anywhere public.