Security
Protect your notification pipeline with context-level authentication, sensitive value masking, and Cloudflare edge security.
HTTP Authentication
Each HTTP context can optionally require a token. When the token field is set on a context, incoming requests must include a matching Authorization header.
Supported header formats:
Authorization: Bearer {token}— The standard bearer token format. TheBearerprefix is case-sensitive (lowercasebearerwill not match).Authorization: {token}— A raw token without theBearerprefix.
If the context has no token field, all requests are allowed without authentication.
danger
On authentication failure, the worker returns HTTP 403. If the context has an error_topic configured, an error-debug.json attachment is sent to that topic containing the timestamp, error type, context name, interpreter, and request details (method, URL, headers with the Authorization header stripped, and Cloudflare properties).
{
"timestamp": "2026-04-15T12:00:00.000Z",
"error": {
"type": "authentication",
"message": "Token mismatch"
},
"context": {
"name": "My Service",
"interpreter": "plain-text"
},
"request": {
"method": "POST",
"url": "https://myservice.ntfy.example.com/",
"headers": {
"content-type": "text/plain",
"user-agent": "curl/8.0"
},
"cf": {
"country": "US",
"colo": "SJC"
}
}
}
The Authorization header is stripped before sending. Interpretation errors include an additional body field with type and json or text sub-fields.
Email Authentication
Email contexts use the allowed_from field to control which senders can trigger notifications.
- Exact match —
[email protected]allows only that address. - Wildcard —
*@example.comallows any sender from that domain. - Not set — All senders are allowed.
Matching is case-insensitive. If the context has an error_topic configured, unauthorized emails send an error-debug.json attachment to that topic.
{
"timestamp": "2026-04-15T12:00:00.000Z",
"error": {
"type": "authentication",
"message": "Sender not in allowed_from"
},
"context": {
"name": "pfSense Alerts",
"interpreter": "pfsense"
},
"email": {
"from": "[email protected]",
"to": "[email protected]",
"subject": "Alert notification"
}
}
Email interpretation errors include an additional textBody field inside the email object.
Sensitive Value Masking
The worker masks sensitive values in the landing page debug section when show_response_output is enabled.
- Server tokens — Replaced with
***. - Server URLs — Replaced with
***. - Base domain — Replaced with
***. - Context IDs and topics — Replaced with
***. - Context tokens and
allowed_from— Replaced with***when present. - Error topics — Replaced with
***when present.
This masking applies to the collapsible debug section on the GET landing page. The POST/PUT JSON response includes context name, interpreter, and server results only when show_response_output is enabled.
Debug Output
The show_response_output setting controls whether detailed information is included in responses.
- Enabled — POST/PUT responses include context name, interpreter, per-server delivery results, and message details. The GET landing page shows a collapsible debug section with the masked config. Useful during initial setup.
- Disabled — POST/PUT responses include only the delivery status. The GET landing page shows only the operational badge. Recommended for production.
Visiting any context URL in a browser (GET request) shows a landing page instead of processing a notification. When show_response_output is enabled, the landing page includes a collapsible section with the full configuration, with sensitive values masked. When disabled, it shows only an operational status badge.
Cloudflare Edge Protection
Running on Cloudflare Workers provides several security benefits at the edge.
- Origin IP shielding — Your ntfy server IPs are never exposed to webhook senders.
- HTTPS enforcement — HTTP requests are automatically redirected to HTTPS via 301 (except on localhost for local development).
- DDoS protection — Cloudflare's built-in DDoS mitigation applies to all traffic.
WAF Configuration
Cloudflare's bot protection can block legitimate webhooks. You may need to adjust these settings.
- Bot Fight Mode (free plan) — Disable this in Dashboard > Security > Bots if automated requests are being blocked with 403 responses. Bot Fight Mode cannot be bypassed with WAF rules.
- WAF skip rule (Pro+) — Pro plans and above use Super Bot Fight Mode, which can be skipped. Create a custom rule that skips Super Bot Fight Mode for your proxy's hostnames:
- If:
(http.host contains "ntfy.example.com" and not http.request.headers["sec-fetch-mode"] eq "navigate") - Then: Skip all Super Bot Fight Mode rules.
- If:
- Configuration rule — Set a custom filter to match your proxy hostnames, disable Browser Integrity Check, and set Security Level to "Essentially Off".
warning
Bot Fight Mode cannot be skipped via WAF rules on any plan. The skip rule above targets Super Bot Fight Mode, which is available on Pro plans and above. Free plan users will need to disable Bot Fight Mode entirely if it blocks webhook traffic.
HTTPS Enforcement
The worker automatically redirects HTTP requests to HTTPS using a 301 redirect. This applies to all requests where the hostname includes the configured base_domain, except those on localhost (for local development with wrangler dev).
Best Practices
- Set a unique
tokenon each HTTP context that receives traffic from the public internet. - Use
allowed_fromwildcards on email contexts to restrict senders to expected domains. - Disable
show_response_outputin production to minimize information exposure. - Disable
show_visitor_infounless you need IP and location details in notifications. - On Pro plans and above, set up a Super Bot Fight Mode skip rule rather than disabling bot protection entirely.
- Use
error_topiconly with ntfy servers you control — error notifications include full context details, request metadata, and email content as unmasked JSON attachments.