> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pxxl.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Password Protection

> Protect a Pxxl project before traffic reaches your application.

Password Protection adds a shared access gate at the Pxxl edge. Visitors must pass it before their request reaches your deployed application.

It is useful for previews, client review links, internal tools, and staging applications. Your application does not need a new route or middleware.

<Frame caption="Project Protection lets you choose the protected hostnames and save a shared visitor password.">
  <img src="https://mintcdn.com/pxxl/BmMwkLenE04VSQYP/images/project-password-protection.jpeg?fit=max&auto=format&n=BmMwkLenE04VSQYP&q=85&s=b4a8c04e5a8ca758542771e9e7252f30" alt="Pxxl project settings showing Project Protection enabled with preview-only and full-project scope options." width="5088" height="3364" data-path="images/project-password-protection.jpeg" />
</Frame>

## Configure protection

<Steps>
  <Step title="Open Project Protection">
    Open the project, choose **Settings**, and select **Project Protection**.
  </Step>

  <Step title="Turn protection on">
    Enable **Password protection**.
  </Step>

  <Step title="Choose the scope">
    Select **Preview only** for Pxxl preview hostnames, or **Full project** for the project domains, custom domains, assets, and APIs.
  </Step>

  <Step title="Save the password">
    Enter the shared visitor password and select **Save Protection**. Pxxl updates the active edge routes after saving.
  </Step>
</Steps>

## How a protected request works

Protection runs before the deployed service is selected. The application only receives the original request after the edge check succeeds.

```mermaid theme={null}
sequenceDiagram
    participant V as Visitor
    participant E as Pxxl edge
    participant G as Gateway verifier
    participant A as Deployed app

    V->>E: HTTPS request
    E->>G: GET /api/v3/deployment-protection/verify
    Note over E,G: Host, Cookie, Authorization, preview token, password header
    alt Credential accepted
        G-->>E: 2xx, usually 204
        E->>A: Original request
        A-->>E: Application response
        E-->>V: Application response
    else Credential missing or invalid
        G-->>E: 401 or protection page
        E-->>V: Access denied
    end
```

The flow is:

1. The dashboard saves the protection setting. The password is hashed and stored securely, and the project route is updated.
2. The route controller adds a `forward_auth` check to the protected hostname and publishes the change through the route store.
3. The edge makes a small `GET` request to the Gateway verifier. It forwards the request headers needed to identify the host and credential. The original request body is not sent to the verifier.
4. The verifier resolves the host to a project, checks the selected scope, and compares the credential with the stored hash.
5. Any successful `2xx` response allows the original request to continue. A denied response stops the request before the app is reached.

The password is never passed to the application as an application credential. Pxxl removes `X-Pxxl-Protection-Password` from the request before forwarding the request upstream.

## Send the password from server-side code

For server-to-server requests, send the password in `X-Pxxl-Protection-Password`:

```bash theme={null}
curl --fail-with-body \
  -H "X-Pxxl-Protection-Password: $PXXL_SITE_PASSWORD" \
  https://your-domain.com/api/health
```

The same works from a server-side Node.js process:

```js theme={null}
const response = await fetch("https://your-domain.com/api/health", {
  headers: {
    "X-Pxxl-Protection-Password": process.env.PXXL_SITE_PASSWORD,
  },
});

if (!response.ok) {
  throw new Error(`Pxxl returned ${response.status}`);
}
```

Use this header only on a trusted server. Do not put the password in frontend JavaScript, a URL, a query string, or a client-visible configuration value.

The header is for Pxxl's verifier. Your application should not depend on receiving it.

## Browser login and the session cookie

Normal browser navigation does not let a visitor attach a custom header to the first page request. When the browser is not already authorized, Pxxl serves a small password page.

<Frame caption="Visitors see the Pxxl Edge password page before the protected application is served.">
  <img src="https://mintcdn.com/pxxl/BmMwkLenE04VSQYP/images/site-protection-page.jpeg?fit=max&auto=format&n=BmMwkLenE04VSQYP&q=85&s=7d78bb0c73751c4abc181a2500567170" alt="Pxxl Edge shared password page shown before a protected application loads." width="5088" height="3482" data-path="images/site-protection-page.jpeg" />
</Frame>

When the visitor submits the form:

1. The edge sends the form request to the Gateway verifier.
2. The verifier checks the `password` form field.
3. A successful login returns a redirect to the original same-site path and sets `x-pxxl-protection-session`.
4. The browser sends that `HttpOnly`, `Secure` cookie on later requests. The edge forwards it to the verifier.

The session lasts 12 hours. It is tied to the protected host and the saved password hash. Changing the password makes existing sessions invalid.

## Headers used by the edge check

Pxxl copies these headers into the verifier request when they are present:

| Header | What it is used for |
| - | - |
| `Host` or `X-Forwarded-Host` | Finds the project and determines which scope applies. |
| `Cookie` | Checks an existing browser protection session. |
| `X-Pxxl-Protection-Password` | Checks the shared password for trusted server requests. |
| `Authorization` | Supports Basic Auth, bearer tokens, and platform identity checks. |
| `X-Pxxl-Preview-Token` | Supports token-based preview protection. |

These headers are inputs to the edge check, not a contract for the deployed service. The verifier response has no trusted identity headers for the application to consume.

## HTTPS and HTTP

Pxxl public routes redirect HTTP to HTTPS by default. The protection check happens at the edge on the HTTPS route, before the request is sent to the application.

Use HTTPS whenever you send a protection password. If a custom route deliberately allows plain HTTP, the password header and form submission can be exposed in transit and should not be used there.

## Preview-only and full-project scope

| Scope | What it protects |
| - | - |
| **Preview only** | Pxxl preview and default project hostnames. Custom domains are left outside this project-level gate. |
| **Full project** | The project's default domains, custom domains, assets, and APIs. |

The route is rebuilt for each active hostname when the setting changes. If an edge route is temporarily unavailable, the dashboard reports that the protection was saved while route synchronization is pending.

## Other protection modes

The protection record also supports token, email, and team checks for platform integrations. Those modes use `X-Pxxl-Preview-Token` or bearer identity headers instead of a shared visitor password. The dashboard flow above documents the shared-password mode.

## Configure through the API

The dashboard uses these authenticated project endpoints:

```text theme={null}
GET /api/v3/projects/:id/protection
PUT /api/v3/projects/:id/protection
```

An update can include `enabled`, `mode`, `previewOnly`, and `secret`. Pxxl stores only a secure hash of the secret. The current `@pxxlapp/pxxl` SDK and CLI do not expose project protection methods, so use the dashboard or the authenticated API endpoints for this setting.

## What it does not replace

Password Protection is one shared gate. It does not provide per-user accounts, roles, audit history, or application authorization. Keep user authentication inside the application when different users need different access.

<Warning>
  Do not place a production database password, API key, or other secret in the visitor password field. Use [Secrets](/projects/secrets) for values the application needs at build or runtime.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.