Security

Here’s a rundown of the security controls baked into Perch, and the handful of things worth checking before you run it in production.

Before you go to production

Most of Perch’s defenses are on by default. The two things you must do yourself: set PERCH_BASE_URL to your real origin, and use a long random PERCH_HUB_TOKEN. Everything else below is automatic.

CORS

Perch locks CORS to a single allowed origin derived from PERCH_BASE_URL. Set it to your public URL:

.env
PERCH_BASE_URL=https://metrics.example.com

Wildcard fallback

Without this variable set, Perch falls back to a CORS wildcard in non-production environments. In production you should treat PERCH_BASE_URL as required. See Configuration for the full variable reference.

Login lockout

To fend off brute-force attacks, Perch rate-limits password login attempts. Once an account racks up too many failed attempts within 15 minutes, it gets locked out and further tries come back as HTTP 429.

The lockout threshold and whether it’s enabled at all are configurable from Admin → Instance → Sessions & Security. The default is 5 attempts before lockout. See Instance Settings for details.

SSRF protection

Health checks and data source connections let you point Perch at a URL. To prevent the hub from probing your internal network, Perch checks every URL before making a request:

  • Hostnames that resolve to localhost, RFC 1918 addresses (10.x, 172.16-31.x, 192.168.x), link-local addresses (including the cloud metadata IP 169.254.169.254), or CGNAT space all get rejected.
  • The check runs in two stages: a string-based hostname rejection first, then a DNS lookup to catch public hostnames that secretly resolve to private IPs (DNS rebinding).

Tip

If a URL fails this check, Perch returns an error and never makes the request. It’s all automatic, nothing to configure.

Agent authentication

Agents connect to the hub over WebSocket and authenticate with PERCH_HUB_TOKEN. The hub gives each new agent connection 5 seconds to send a valid auth message. Connections that don’t authenticate in time get closed with an auth_error message.

Use a long random string for the token:

generate-token.sh
openssl rand -hex 32

Treat the hub token like a password

Anyone with PERCH_HUB_TOKEN can connect an agent to your hub. Never share it with anyone who doesn’t need to run an agent.

Session security

Session tokens are opaque random strings hashed with SHA-256 before storage. The raw token goes to the client once and never gets stored in plaintext. OAuth callbacks and account recovery links use short-lived single-use handoff codes rather than embedding session tokens in URLs. The client exchanges the code for a token right after redirect, so the token never appears in server logs, browser history, or Referer headers.

Session expiry is configurable. See Instance Settings.

Security headers

Perch adds the following headers to every response:

  • Content-Security-Policy restricts resource loading to trusted sources
  • X-Frame-Options: DENY stops the dashboard from loading inside an iframe
  • X-Content-Type-Options: nosniff keeps browsers from sniffing response content types
  • Permissions-Policy switches off browser features the dashboard doesn’t use (camera, microphone, geolocation)

Note

Nothing to configure here, these ship on by default.

Maintenance mode

If you need to take your instance down for an upgrade, turn on maintenance mode from Admin → Instance. Non-admin users can’t log in while it’s enabled. Admins keep full access. See Instance Settings.