Skip to main content

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:

FieldTypeDefaultMeaning
enabledbooleanWhether HSTS is sent.
max_ageint31536000How long (seconds) browsers enforce HTTPS. Default is 1 year.
include_subdomainsbooleanApply the policy to all subdomains.
preloadbooleanSignal 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 }
}'
info

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.