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 OK without Authorization headers.
  • 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.js detects 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_PASSWORD equals no authentication — the server runs open.
  • The isWebPasswordEnabled() function in lib/web-auth.ts is the single source of truth for this decision.
  • proxy.ts skips all auth checks when the variable is missing or empty.
  • bin/pi-web.js emits 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →