Skip to main content

Maintenance Mode Bypass Token

Audience: Internal developers only. Do not share this document or any tokens externally.

When the application is in maintenance mode, a small set of trusted developers can temporarily bypass it using a secret token. This page explains how to:

  • Generate a strong token
  • Hash and store the token securely
  • Send the token via header or cookie
  • Avoid common security pitfalls
warning

Treat the maintenance bypass token like a password with production access. Anyone who has it can see the site while users see maintenance pages.

1. Generate a secure token

Use a long, random token. Do not use human-readable phrases or anything that could be guessed.

openssl rand -hex 32

Example output:

5b27e0f6de3c4f6e9e7f3a6f5f9a1c2d832f4e5a6b7c8d9e0f1a2b3c4d5e6f7

Option B: Node.js REPL

node
const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('hex');
console.log(token);

Use the generated value as your raw bypass token (keep it secret).

2. Hash the token

The raw token should never be stored in code or config. Instead:

  1. Hash the token once locally.
  2. Store only the hash in an environment variable or secure secret store.
  3. At runtime, the middleware compares the hash of the incoming token to the stored hash.

Example: One-off Node script using crypto.scrypt

node scripts/hash-maintenance-token.mjs
// scripts/hash-maintenance-token.mjs
import {scryptSync, randomBytes} from 'node:crypto';

const rawToken = process.env.MAINTENANCE_BYPASS_TOKEN;

if (!rawToken) {
throw new Error('Set MAINTENANCE_BYPASS_TOKEN in your environment before running this script.');
}

const salt = randomBytes(16);
const key = scryptSync(rawToken, salt, 32);

const hash = Buffer.concat([salt, key]).toString('base64');

console.log('Store this hash in your env (do NOT store the raw token):');
console.log(hash);

Usage:

export MAINTENANCE_BYPASS_TOKEN="your-raw-token-here"
node scripts/hash-maintenance-token.mjs

Then set (for example) in your hosting platform:

  • MAINTENANCE_BYPASS_HASH=<printed-hash>
TODO

Align the hashing algorithm and environment variable names here with the actual middleware implementation in the main application repository (for example, MAINTENANCE_BYPASS_HASH, MAINTENANCE_BYPASS_HEADER, etc.).

How you present the token to the application is implementation-specific. The two common patterns are:

  • Custom HTTP header (recommended for API tools / automated checks)
  • Secure cookie (recommended for browser access during manual QA)

3.1 Send via custom header

Assuming the middleware checks a header like X-Maintenance-Bypass:

curl https://your-domain.com/ \
-H "X-Maintenance-Bypass: your-raw-token-here"

In Postman or similar tools:

  • Add a header X-Maintenance-Bypass with value your-raw-token-here.

This header must not be logged or exposed in client-side code.

Assuming the middleware checks a cookie like maintenance_bypass:

curl https://your-domain.com/ \
-H "Cookie: maintenance_bypass=your-raw-token-here"

In a browser:

  1. Open DevTools → Application / Storage tab.
  2. Manually add a cookie for your domain:
    • Name: maintenance_bypass
    • Value: your-raw-token-here
    • Flags: Secure, HttpOnly, SameSite=Strict (set via server, not DevTools).

Once the cookie is present, reload the page: you should bypass maintenance mode while regular users still see the maintenance screen.

note

Do not store the bypass token in localStorage or expose it via client-side JavaScript. Server-set HttpOnly cookies are safer.

4. Security guidelines

  • Treat as production credentials

    • Only share tokens with developers who genuinely need temporary bypass access.
    • Use a secure channel (password manager, secret manager, or encrypted chat) to share tokens.
  • Rotate regularly

    • Rotate the bypass token after major incidents, role changes, or suspected leaks.
    • When rotating, generate a new token, regenerate the hash, update env vars, and redeploy.
  • Limit scope

    • Ensure the bypass is only honored when maintenance mode is actually enabled.
    • Consider limiting the bypass to specific IP ranges or internal VPNs where possible.
  • Avoid logging

    • Never log the raw token or compare it using logging statements.
    • If you must log something, log only whether a bypass was attempted/succeeded, not the values.
  • Monitor usage

    • Add minimal logging/metrics around successful maintenance bypass usage (timestamp, anonymized identifier).
    • Periodically review who still has access and whether they still need it.

5. Quick checklist

  • Generated a strong, random raw token locally.
  • Hashed the token and stored only the hash in env/secret storage.
  • Verified the middleware checks the expected header/cookie and compares hashes.
  • Sent the token via a secure header or HttpOnly cookie over HTTPS only.
  • Documented rotation and ownership for the current bypass token.