What Happens When PI_WEB_PASSWORD Is Not Set in pi-web?
When the PI_WEB_PASSWORD environment variable is not set, pi-web runs without HTTP Basic Auth, allowing unrestricted access to the web UI and all API endpoints.
The agegr/pi-web repository implements optional password protection for its Next.js-based web interface. Authentication is strictly opt-in via environment variable configuration. If you skip this step, the server starts normally but remains completely open to any client that can reach it.
How Authentication Is Triggered
The authentication decision happens in proxy.ts, which acts as middleware for incoming requests. The code checks whether PI_WEB_PASSWORD exists and has content before enforcing any credential challenge:
const password = process.env.PI_WEB_PASSWORD;
if (
isWebPasswordEnabled(password) && // ← true only when set
!isValidBasicAuthorization(request.headers.get("authorization"), password)
) {
return new NextResponse("Authentication required", { … });
}
The isWebPasswordEnabled() helper in lib/web-auth.ts defines the exact conditions:
export function isWebPasswordEnabled(
password: string | undefined = process.env.PI_WEB_PASSWORD,
): password is string {
return typeof password === "string" && password.length > 0;
}
When PI_WEB_PASSWORD is undefined, an empty string, or not a string, this function returns false. The if block in proxy.ts never executes, so requests proceed without authentication headers.
Consequences of an Unset PI_WEB_PASSWORD
The following occurs when you start pi-web without defining this environment variable:
- Authentication is completely disabled — No username/password prompt appears in browsers, and API requests return
200 OKwithoutAuthorizationheaders. - All endpoints are public — Anyone with network access to the host can list connected Raspberry Pi devices, view logs, and execute commands through the web interface.
- A startup warning is logged — The CLI entry point in
bin/pi-web.jsdetects the missing variable and prints a security notice:
const passwordEnabled = Boolean(process.env.PI_WEB_PASSWORD);
…
if (!loopbackHostnames.has(hostname)) {
if (passwordEnabled) {
console.warn(`Warning: pi-web is listening on ${hostname} with Basic Auth over HTTP…`);
} else {
console.warn(`Warning: pi-web is listening on ${hostname} without authentication…`);
}
}
The warning distinguishes between two insecure configurations: password-enabled Basic Auth over unencrypted HTTP (credential exposure risk) versus no authentication at all (unrestricted access risk).
Running pi-web Without Authentication
This is the default behavior when launching pi-web without configuration:
# No environment variable defined — or explicitly empty
pi-web
# Console output: Warning: pi-web is listening on 0.0.0.0 without authentication…
Any client can immediately access:
curl http://127.0.0.1:30141/api/models # Returns JSON without 401 response
Enabling PI_WEB_PASSWORD Protection
To require credentials, export a non-empty value before starting the server:
export PI_WEB_PASSWORD='your-secure-password-here'
pi-web
Now all requests must include Basic Auth with username pi:
curl -u pi:your-secure-password-here http://127.0.0.1:30141/api/models
Missing or incorrect credentials return:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic
Code-Level Verification
You can programmatically verify the authentication state using the same helper the server uses:
import { isWebPasswordEnabled } from "@/lib/web-auth";
const pwd = process.env.PI_WEB_PASSWORD;
console.log(isWebPasswordEnabled(pwd)); // false when unset, true when non-empty string
This matches the runtime behavior in proxy.ts and bin/pi-web.js.
Key Files Controlling This Behavior
| File | Responsibility |
|---|---|
proxy.ts |
Request middleware that conditionally enforces Basic Auth |
lib/web-auth.ts |
isWebPasswordEnabled() and credential validation logic |
bin/pi-web.js |
CLI startup script that logs authentication status warnings |
Summary
- No
PI_WEB_PASSWORDequals no authentication — the server runs open. - The
isWebPasswordEnabled()function inlib/web-auth.tsis the single source of truth for this decision. proxy.tsskips all auth checks when the variable is missing or empty.bin/pi-web.jsemits a console warning to alert operators of the insecure configuration.- Username is hardcoded to
pi; only the password is configurable via environment variable.
Frequently Asked Questions
Does pi-web require a password by default?
No. According to the agegr/pi-web source code, authentication is disabled unless you explicitly set PI_WEB_PASSWORD to a non-empty string. The server starts without credentials and logs a warning about the unsecured state.
What username do I use with PI_WEB_PASSWORD?
The username is always pi. Only the password is configurable. This is encoded in the Basic Auth validation logic within lib/web-auth.ts, which extracts and compares the password portion of the Authorization header against your PI_WEB_PASSWORD value.
Is there a way to disable the startup warning about missing authentication?
No built-in option exists to suppress this warning. The message in bin/pi-web.js fires for any non-loopback hostname when PI_WEB_PASSWORD is undefined. You would need to modify the source or filter stderr to hide it.
Does setting PI_WEB_PASSWORD to an empty string enable authentication?
No. The isWebPasswordEnabled() function explicitly checks password.length > 0, so empty strings evaluate to false and authentication remains disabled. Only non-empty strings activate the protection layer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →