# What Happens When PI_WEB_PASSWORD Is Not Set in pi-web?

> Discover what happens when PI_WEB_PASSWORD isn't set in pi-web. Learn how this impacts security and access to the web UI and API endpoints. Find out now.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: how-to-guide
- Published: 2026-08-10

---

**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`](https://github.com/agegr/pi-web/blob/main/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:

```typescript
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`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts) defines the exact conditions:

```typescript
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`](https://github.com/agegr/pi-web/blob/main/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`](https://github.com/agegr/pi-web/blob/main/bin/pi-web.js) detects the missing variable and prints a security notice:

```javascript
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:

```bash

# 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:

```bash
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:

```bash
export PI_WEB_PASSWORD='your-secure-password-here'
pi-web

```

Now all requests must include Basic Auth with username `pi`:

```bash
curl -u pi:your-secure-password-here http://127.0.0.1:30141/api/models

```

Missing or incorrect credentials return:

```http
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:

```typescript
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`](https://github.com/agegr/pi-web/blob/main/proxy.ts) and [`bin/pi-web.js`](https://github.com/agegr/pi-web/blob/main/bin/pi-web.js).

## Key Files Controlling This Behavior

| File | Responsibility |
|------|---------------|
| [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) | Request middleware that conditionally enforces Basic Auth |
| [`lib/web-auth.ts`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts) | `isWebPasswordEnabled()` and credential validation logic |
| [`bin/pi-web.js`](https://github.com/agegr/pi-web/blob/main/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`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts) is the single source of truth for this decision.
- [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) skips all auth checks when the variable is missing or empty.
- [`bin/pi-web.js`](https://github.com/agegr/pi-web/blob/main/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`](https://github.com/agegr/pi-web/blob/main/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`](https://github.com/agegr/pi-web/blob/main/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.