Environment variables
Arcjet uses several environment variables that influence its behavior. These are listed and explained in this article.
Arcjet recommends
defining environment variables
based on the guidance and best practices of your chosen framework and hosting
provider. For example, use .env.local files in development and the secrets
management of your hosting platform in production.
List of Arcjet environment variables
Section titled “List of Arcjet environment variables”ARCJET_BASE_URL
Section titled “ARCJET_BASE_URL”URL to Arcjet Cloud API (string, default: "https://decide.arcjet.com"). Set
this only if Arcjet support directs you to. Read by both the JS and Python SDKs.
For more information, see Architecture: Cloud API.
When deployed to Fly.io, the default changes to
"https://fly.decide.arcjet.com", a dedicated endpoint that runs on the Fly
platform for lower latency.
ARCJET_ENV, NODE_ENV
Section titled “ARCJET_ENV, NODE_ENV”Whether the app is running in development
("development" | "production", default: "production").
Arcjet is in development mode if either of these fields is set to "development"
and production mode otherwise.
NODE_ENV is a convention used in Node.js apps – the Python SDK reads
ARCJET_ENV only.
Python SDK users: if your config library doesn’t propagate .env into
os.environ (for example, pydantic-settings), pass ARCJET_ENV with the
environment= kwarg on arcjet() / arcjet_sync() – see the
Python SDK reference.
The timeout for connecting to Cloud API defaults to 2000 ms in both
development and production. This applies to the JavaScript and Python SDKs.
The Python SDK uses this 2000 ms timeout for arcjet() /
arcjet_sync(). For more information, see
Architecture: Timeout
and the
Python SDK reference.
In production, an error is logged when no client IP is found. In development,
the local IP 127.0.0.1 is used as a fallback. When the client IP is missing
(or local), geolocation and other IP lookup info is empty. In development, an
x-arcjet-ip header can be used to overwrite the client IP. This is because
it’s useful to overwrite IPs for testing, but in production headers cannot be
trusted as they can be set by malicious users.
The Arcjet Astro SDK uses ARCJET_ENV and the value at import.meta.env.MODE
(from Vite) but does not use NODE_ENV.
The Go SDK does not read ARCJET_ENV or NODE_ENV and has no
development-mode switch. Set Config.Platform on the HTTP client to select
a hosting platform. To override the detected client IP on a request, pass
WithIPSrc to Protect. For more information, see the
Go SDK reference.
Protect and ProtectDetails apply a 2 second deadline when the incoming
context has none, or 4 seconds when an email rule is configured. A
caller-supplied deadline is not shortened or replaced. For more
information about the deadline, see
Timeouts in the Go SDK reference.
ARCJET_KEY
Section titled “ARCJET_KEY”Arcjet key for your site (string). In most cases, this variable name is a
recommended convention.
The Go SDK reads ARCJET_KEY when Key is empty on NewClient or
NewGuardClient. An explicit Key wins. The Astro SDK also reads this
value automatically.
The JS Guard SDK does not read environment variables. Python Guard and
Python Protect require an explicit key – typically
os.environ["ARCJET_KEY"] or os.environ.get("ARCJET_KEY") passed to
arcjet(key=...), arcjet_sync(key=...), launch_arcjet(key=...), or
launch_arcjet_sync(key=...). Other JS SDKs (except Astro) require you to
retrieve the value and pass it yourself.
For more information, see How to read environment variables.
You can find your site key in the Arcjet dashboard. Select your site, select “SDK configuration”, then click to copy.
Arcjet keys are secrets that are always prefixed with ajkey_.
As this is a secret, do not commit it to source control or otherwise expose it.
ARCJET_LOG_LEVEL
Section titled “ARCJET_LOG_LEVEL”Log level to use ("debug" | "error" | "info" | "warn", default: "warn").
Setting warn, for example, logs warning and error messages. The order of log
levels from most verbose to least verbose is debug, info, warn, error.
Read by both the JS and Python SDKs. The Python SDK applies this to the
arcjet logger (logging.getLogger("arcjet")) and also accepts a numeric
level like "10" (for DEBUG).
List of environment variables read by Arcjet
Section titled “List of environment variables read by Arcjet”FIREBASE_CONFIG, FLY_APP_NAME, RENDER, VERCEL
Section titled “FIREBASE_CONFIG, FLY_APP_NAME, RENDER, VERCEL”Environment variables set by hosting platforms (string). Do not set these in
.env files; the platforms where your app runs set them automatically. Arcjet
checks whether values are non-empty.
FIREBASE_CONFIG is set by Firebase,
FLY_APP_NAME is set by Fly,
RENDER is set by Render, and
VERCEL is set by Vercel.
The inferred platform affects which request headers are trusted when determining the
client IP.
When Fly is detected, that affects the default value of ARCJET_BASE_URL.
The Python SDK only reads FLY_APP_NAME (to switch the default
ARCJET_BASE_URL to the Fly endpoint). It does not read FIREBASE_CONFIG,
RENDER, or VERCEL.
VERCEL_GIT_COMMIT_SHA
Section titled “VERCEL_GIT_COMMIT_SHA”Git SHA of the commit the deployment was triggered by (string). Do not set
this in .env files;
VERCEL_GIT_COMMIT_SHA
is automatically set by Vercel. When present in the Arcjet Next.js SDK, its
value is sent to Arcjet Cloud API as part of the extra fields, which are
displayed in the Arcjet dashboard. The Python SDK does
not read this variable.
HTTP_PROXY, HTTPS_PROXY, NO_PROXY
Section titled “HTTP_PROXY, HTTPS_PROXY, NO_PROXY”Standard proxy environment variables (string). When set, Arcjet routes its
outbound calls to the Arcjet Cloud API through the configured proxy, and
NO_PROXY exempts hosts from proxying. Because the API is reached over HTTPS,
HTTPS_PROXY is the relevant variable for most deployments.
Honored from @arcjet/* 1.6.0 (JS/TS – on runtimes that support outbound
proxying, such as Node.js) and arcjet 0.9.0 (Python). Avoid logging the proxy
URL, as it may contain credentials.
How to define environment variables
Section titled “How to define environment variables”Arcjet recommends using .env.local files in development to set environment
variables. Be sure to avoid committing any .env files that contain secrets to
source control.
In production it is recommended to set environment variables using the dashboard
provided by the platform where your app runs, and not to use .env files.
Node 20+ supports loading environment variables from a local file with
--env-file. If you’re using an older version of Node, you can use a package
like dotenv to load the environment
variables from a .env.local file.
node --env-file .env.local index.jsIn Python, the python-dotenv
package is the standard way to load .env files. Call load_dotenv()
before reading the variables:
from dotenv import load_dotenv
load_dotenv() # Loads .env from the working directoryFlask and pydantic-settings load .env files automatically when python-dotenv
is installed – see the framework-specific notes later on this page.
How to load .env files
Section titled “How to load .env files”Whether .env files are loaded automatically and how to load them manually
depends on the framework and runtime.
In Astro,
Bun,
Nuxt,
Remix (in development), and
SvelteKit
(with adapter-node, in development)
.env files are loaded automatically.
In Deno
you can load .env files by running with the --env-file flag.
In Node.js
(which includes Fastify, NestJS, and React Router)
you can load a specific .env file by running with the --env-file=file flag.
In Next.js
.env files are loaded automatically when using loadEnvConfig from
@next/env.
In
Flask
both .env and .flaskenv files are loaded automatically by the flask CLI
when python-dotenv is installed. .flaskenv is intended for public variables
(for example, FLASK_APP); Use .env for secrets, and add it to .gitignore.
In FastAPI
.env files are loaded automatically when you use
pydantic-settings
and set model_config = SettingsConfigDict(env_file=".env") on your
BaseSettings subclass. Otherwise call load_dotenv() from python-dotenv
manually at module load time.
How to read environment variables
Section titled “How to read environment variables”Arcjet reads most environment variables automatically.
The Go SDK reads ARCJET_KEY when Key is empty. The Astro SDK also reads
it automatically. Other JS SDKs and the Python SDK require you to pass the
key explicitly.
How you read ARCJET_KEY and other environment variables depends on your
framework or runtime:
In Node.js
and Bun
you can read environment variables from process.env.
In Deno
you can read environment variables with Deno.env.get().
In SvelteKit you can read environment variables from
$env/dynamic/private and
the like.
In Go you can read environment variables with
os.Getenv. Passing
Key: os.Getenv("ARCJET_KEY") is the explicit-wins pattern. If you omit
Key, NewClient and NewGuardClient read ARCJET_KEY from the
environment:
aj, err := arcjet.NewClient(arcjet.Config{ Key: os.Getenv("ARCJET_KEY"),})In Python you can read environment variables with
os.environ.
Use os.environ["ARCJET_KEY"] to raise a KeyError if the variable is
missing, or os.environ.get("ARCJET_KEY") to return None. The Arcjet
Python SDK does not read ARCJET_KEY automatically – you must pass it
explicitly:
import osfrom arcjet import arcjet
aj = arcjet( key=os.environ["ARCJET_KEY"], rules=[],)@arcjet/env
Section titled “@arcjet/env”The JS SDKs use @arcjet/env to read info from the
environment.
To read values in the same way as the JS SDKs,
for example to figure out whether Arcjet is in development mode,
you can use this package.
There is no equivalent package for Python or Go. The Python SDK reads environment
variables directly with os.environ or os.getenv in
arcjet/_client.py,
arcjet/_context.py,
and
arcjet/_logging.py.