Security headers (HSTS & more)
Paradarum can add common security response headers at the edge so every response your property serves is hardened — without changing your origin. These are part of the property's general settings and are toggled on the General tab.
HSTS
HTTP Strict Transport Security tells browsers to only ever connect to your site over HTTPS. The hsts object has four fields:
| Field | Type | Default | Meaning |
|---|---|---|---|
enabled | boolean | — | Whether HSTS is sent. |
max_age | int | 31536000 | How long (seconds) browsers enforce HTTPS. Default is 1 year. |
include_subdomains | boolean | — | Apply the policy to all subdomains. |
preload | boolean | — | Signal eligibility for browser HSTS preload lists. |
{
"hsts": {
"enabled": true,
"max_age": 31536000,
"include_subdomains": true,
"preload": true
}
}
:::warning Preload and include_subdomains are sticky
include_subdomains and preload are strong commitments. Once a browser has cached your HSTS policy (up to max_age), every subdomain must serve valid HTTPS or visitors will be blocked. Only enable preload when you are certain every subdomain is HTTPS-ready.
:::
Clickjacking protection
clickjacking_protection is a single boolean toggle. When on, the CDN sends an X-Frame-Options-style header so other sites can't embed your pages in a frame.
{ "clickjacking_protection": true }
MIME-sniffing protection
mime_sniffing_protection is a single boolean toggle. When on, the CDN sends an X-Content-Type-Options-style header so browsers don't guess (and mis-execute) content types.
{ "mime_sniffing_protection": true }
Saving security headers safely
Each toggle is part of the same general-settings object, and saving works the same way as every other general setting.
:::danger General settings are one blob with no server-side merge
General settings are stored as a single snake_case JSONB object, and the API does not merge partial updates — a PUT replaces the whole blob. Saving a partial object (for example, just one HSTS toggle) can overwrite other fields with defaults.
The panel avoids this by always sending the full object: it reads the current settings, applies your change, and PUTs everything back. Do the same when scripting against the API — GET first, then PUT the complete object.
:::
A full save including the security headers looks like this:
curl -X PUT "https://api.paradarum.com/api/property/42/general-settings?accountId=123" \
-H "X-API-Key: pdm_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"hsts": { "enabled": true, "max_age": 31536000, "include_subdomains": true, "preload": true },
"clickjacking_protection": true,
"mime_sniffing_protection": true,
"browser_caching": { "mode": "override", "ttl": 3600 },
"query_string": { "mode": "except", "values": ["page", "lang"] },
"image_optimization": { "enabled": true, "quality": 80, "max_width": 4000, "max_height": 4000, "only_if_smaller": true },
"always_online": { "enabled": true, "codes": ["error", "timeout", "500", "502", "503", "504"] },
"origin_shield": { "enabled": true, "shield_id": 3 }
}'
Field names are persisted in snake_case (clickjacking_protection, mime_sniffing_protection, browser_caching, and so on). Use those exact keys — camelCase variants are not read by the server.
Related
- Browser caching & query strings — more general settings, same full-object save rule.
- Header rules — add or rewrite custom headers per path.