# HSTS

> Send Strict-Transport-Security from the edge so browsers always use HTTPS for your sites, with subdomains and preload options.

**HTTP Strict Transport Security** (HSTS) tells browsers to use HTTPS for a site for a period of time, even when someone types `http://` or follows an `http://` link. The edge already redirects HTTP to HTTPS; HSTS removes that first unencrypted request.

## How the edge sends it

When `hsts.max_age` is greater than `0`, the edge adds this header to every HTTPS response of the site:

```http
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```

- `includeSubDomains` appears only with `hsts.include_subdomains`, and `preload` only with `hsts.preload`.
- The header is never sent on plain HTTP responses.
- When HSTS is on, the edge's value replaces any `Strict-Transport-Security` header from your origin. When it's off (`max_age` `0`), the origin's header passes through unchanged.

## Settings

| Setting | Values | Default |
|---|---|---|
| `hsts.max_age` | Seconds, `0`–`63072000` (2 years). `0` = no header. | `0` |
| `hsts.include_subdomains` | `true` / `false` | `false` |
| `hsts.preload` | `true` / `false` | `false` |

Like other edge settings, HSTS can be set for the whole zone or overridden for one name (`hosts.<name>.hsts`).

## Turn it on

> **Caution**
>
> Browsers remember HSTS for the whole `max-age` after each visit. Start with a short duration, make sure every page works over HTTPS, then raise it. With **Include subdomains**, every subdomain must work over HTTPS too.


**Dashboard**

In **SSL/TLS › Certificates › HSTS**, choose a **Duration** (1 day, 6 months, 1 year or 2 years), set **Include subdomains** and **Allow preload** as needed, and **Save changes**.

**CLI**

```sh
openwaf-cloud ctl zones set example.com hsts.max_age=86400 --reason "HSTS, 1 day to start"
openwaf-cloud ctl zones set example.com hsts.max_age=31536000 hsts.include_subdomains=true --reason "HSTS 1 year"
```

**API**

```sh
curl -s -X PATCH https://dash.openwaf.dev/v1/orgs/$ORG/zones/$ZONE/edge \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Change-Reason: HSTS 1 year" \
  -d '{"hsts": {"max_age": 31536000, "include_subdomains": true}}'
```

**MCP**

`update_settings` with `{"zone": "example.com", "settings": {"hsts": {"max_age": 31536000, "include_subdomains": true}}, "reason": "HSTS 1 year"}`, first with `confirm=false`, then `confirm=true` and `expected_version`.


Check it:

```sh
curl -sI https://www.example.com/ | grep -i strict-transport-security
```

## Preload

**Allow preload** adds the `preload` directive, which lets you submit the domain to the HSTS preload list built into browsers. Browsers require a duration of at least 1 year with subdomains included.

> **Danger**
>
> Preload is very hard to undo. Once browsers ship the list, removing your domain can take months, and during that time every subdomain must serve HTTPS.


## Turn it off

Set `hsts.max_age` to `0` (**Duration › Off**). Browsers that already saw the header keep using HTTPS until their stored `max-age` runs out.
