Skip to content

Commit df1a0a3

Browse files
author
chr0nzz
committed
docs: document POST /api/static/trusted-ips/preview
1 parent 756a7f1 commit df1a0a3

3 files changed

Lines changed: 258 additions & 0 deletions

File tree

docs/api.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,48 @@ Response includes the updated `raw` YAML and `parsed` object.
746746

747747
---
748748

749+
### `POST /api/static/trusted-ips/preview`
750+
751+
Compute the result of adding `forwardedHeaders.trustedIPs` to an entrypoint, without writing anything to disk. Backs the **Trusted IPs** helper in the Static Config editor.
752+
753+
Trusting a proxy's IP makes Traefik believe its `X-Forwarded-For`, which then feeds the access logs, CrowdSec, `ipAllowList`, and the login rate-limiter. Only trust proxies you control.
754+
755+
The merge is **additive with dedup**: existing entries are kept, and ranges already covered are skipped by normalized network (so `10.5.5.5/8` will not re-add `10.0.0.0/8`). Sibling keys under `forwardedHeaders`, other entrypoints, and YAML comments are all preserved. The endpoint never saves - the returned `raw` is persisted by the client through [`POST /api/static/config`](#post-api-static-config), which is why it works identically on the Host and on a remote agent.
756+
757+
Called in two modes.
758+
759+
**Inspect** (no `entrypoint`) - lists entrypoints and the presets:
760+
761+
```json
762+
{ "current_raw": "entryPoints:\n websecure:\n address: ':443'\n" }
763+
```
764+
765+
**Preview** (with `entrypoint`) - also returns the merge:
766+
767+
```json
768+
{
769+
"current_raw": "entryPoints:\n websecure:\n address: ':443'\n",
770+
"entrypoint": "websecure",
771+
"cloudflare": true,
772+
"private": false,
773+
"custom_cidrs": "203.0.113.10, 198.51.100.0/24"
774+
}
775+
```
776+
777+
| Field | Type | Description |
778+
|---|---|---|
779+
| `current_raw` | string | Static config YAML to operate on. Falls back to the file on disk when empty. |
780+
| `entrypoint` | string | Target entrypoint. Omit for inspect mode. |
781+
| `cloudflare` | boolean | Include the built-in Cloudflare edge ranges. |
782+
| `private` | boolean | Include the private-range preset (`10/8`, `172.16/12`, `192.168/16`, `fc00::/7`). |
783+
| `custom_cidrs` | string \| string[] | Extra CIDRs or IPs, comma/whitespace-separated or an array. Invalid entries are returned in `invalid` and skipped. |
784+
785+
Inspect mode returns `ok`, `entrypoints` (each with `name`, `address`, `trusted_ips`), `cloudflare_captured`, `cloudflare_ranges`, and `private_ranges`. Preview mode adds `entrypoint`, `existing`, `added`, `invalid`, `final`, the merged `raw` YAML, and the `parsed` object.
786+
787+
Returns `400` if the named entrypoint is absent or the config is not a mapping, and `404` if there is no static config on disk and no `current_raw` was supplied.
788+
789+
---
790+
749791
## Utility
750792

751793
### `GET /api/manager/version`

docs/public/openapi.yaml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,114 @@ paths:
16641664
raw: { type: string }
16651665
parsed: { type: object }
16661666

1667+
/api/static/trusted-ips/preview:
1668+
post:
1669+
tags: [Static Config]
1670+
summary: Preview trusted IPs merge
1671+
description: |
1672+
Compute the result of adding `forwardedHeaders.trustedIPs` to an entrypoint, without
1673+
writing anything to disk. Backs the **Trusted IPs** helper in the Static Config editor.
1674+
1675+
Trusting a proxy's IP makes Traefik believe its `X-Forwarded-For`, which then feeds the
1676+
access logs, CrowdSec, `ipAllowList`, and the login rate-limiter. Only trust proxies you
1677+
control.
1678+
1679+
The merge is **additive with dedup**: existing entries are kept, and ranges already
1680+
covered are skipped by normalized network (so `10.5.5.5/8` will not re-add `10.0.0.0/8`).
1681+
Sibling keys under `forwardedHeaders`, other entrypoints, and YAML comments are all
1682+
preserved. The endpoint is stateless and never saves; the returned `raw` is persisted by
1683+
the client through `POST /api/static` (the normal backup + restart path), which is why it
1684+
works identically on the Host and on a remote agent.
1685+
1686+
Called in two modes:
1687+
1688+
- **Inspect** (no `entrypoint`): returns the entrypoint list with their current
1689+
`trustedIPs`, plus the built-in Cloudflare and private-range presets.
1690+
- **Preview** (with `entrypoint`): additionally returns the merged `raw`, and the
1691+
`existing` / `added` / `invalid` / `final` breakdown for the target entrypoint.
1692+
requestBody:
1693+
required: true
1694+
content:
1695+
application/json:
1696+
schema:
1697+
type: object
1698+
properties:
1699+
current_raw: { type: string, description: "Static config YAML to operate on. Falls back to the file on disk when empty." }
1700+
entrypoint: { type: string, description: "Target entrypoint. Omit for inspect mode." }
1701+
cloudflare: { type: boolean, description: "Include the built-in Cloudflare edge ranges." }
1702+
private: { type: boolean, description: "Include the private-range preset (10/8, 172.16/12, 192.168/16, fc00::/7)." }
1703+
custom_cidrs:
1704+
description: "Extra CIDRs or IPs, as an array or a comma/whitespace-separated string. Invalid entries are returned in `invalid` and skipped."
1705+
oneOf:
1706+
- type: string
1707+
- type: array
1708+
items: { type: string }
1709+
examples:
1710+
inspect:
1711+
summary: Inspect mode
1712+
value:
1713+
current_raw: "entryPoints:\n websecure:\n address: ':443'\n"
1714+
preview:
1715+
summary: Preview a Cloudflare + custom merge
1716+
value:
1717+
current_raw: "entryPoints:\n websecure:\n address: ':443'\n"
1718+
entrypoint: websecure
1719+
cloudflare: true
1720+
custom_cidrs: "203.0.113.10, 198.51.100.0/24"
1721+
responses:
1722+
"200":
1723+
description: Inspect summary, or full preview when an entrypoint was given
1724+
content:
1725+
application/json:
1726+
schema:
1727+
type: object
1728+
properties:
1729+
ok: { type: boolean }
1730+
entrypoints:
1731+
type: array
1732+
description: "Every entrypoint in the static config."
1733+
items:
1734+
type: object
1735+
properties:
1736+
name: { type: string, example: "websecure" }
1737+
address: { type: string, example: ":443" }
1738+
trusted_ips:
1739+
type: array
1740+
items: { type: string }
1741+
description: "The entrypoint's current forwardedHeaders.trustedIPs."
1742+
cloudflare_captured: { type: string, description: "Capture date of the bundled Cloudflare ranges.", example: "2026-07-23" }
1743+
cloudflare_ranges: { type: array, items: { type: string } }
1744+
private_ranges: { type: array, items: { type: string } }
1745+
entrypoint: { type: string, description: "Preview mode only: the target entrypoint." }
1746+
existing:
1747+
type: array
1748+
items: { type: string }
1749+
description: "Preview mode only: trustedIPs before the merge."
1750+
added:
1751+
type: array
1752+
items: { type: string }
1753+
description: "Preview mode only: ranges the merge would add (excludes duplicates)."
1754+
invalid:
1755+
type: array
1756+
items: { type: string }
1757+
description: "Preview mode only: custom entries that failed CIDR/IP validation and were skipped."
1758+
final:
1759+
type: array
1760+
items: { type: string }
1761+
description: "Preview mode only: the resulting trustedIPs (existing + added)."
1762+
raw: { type: string, description: "Preview mode only: the full merged static config YAML, to save via POST /api/static." }
1763+
parsed: { type: object, description: "Preview mode only: the merged config parsed back to JSON." }
1764+
"400":
1765+
description: Named entrypoint not found, or the static config is not a mapping
1766+
content:
1767+
application/json:
1768+
schema: { $ref: "#/components/schemas/ErrorResponse" }
1769+
"404":
1770+
description: No static config on disk and no current_raw supplied
1771+
content:
1772+
application/json:
1773+
schema: { $ref: "#/components/schemas/ErrorResponse" }
1774+
16671775
# ─── CrowdSec ─────────────────────────────────────────────────────────────
16681776

16691777
/api/crowdsec/decisions:

static/openapi.yaml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,114 @@ paths:
16641664
raw: { type: string }
16651665
parsed: { type: object }
16661666

1667+
/api/static/trusted-ips/preview:
1668+
post:
1669+
tags: [Static Config]
1670+
summary: Preview trusted IPs merge
1671+
description: |
1672+
Compute the result of adding `forwardedHeaders.trustedIPs` to an entrypoint, without
1673+
writing anything to disk. Backs the **Trusted IPs** helper in the Static Config editor.
1674+
1675+
Trusting a proxy's IP makes Traefik believe its `X-Forwarded-For`, which then feeds the
1676+
access logs, CrowdSec, `ipAllowList`, and the login rate-limiter. Only trust proxies you
1677+
control.
1678+
1679+
The merge is **additive with dedup**: existing entries are kept, and ranges already
1680+
covered are skipped by normalized network (so `10.5.5.5/8` will not re-add `10.0.0.0/8`).
1681+
Sibling keys under `forwardedHeaders`, other entrypoints, and YAML comments are all
1682+
preserved. The endpoint is stateless and never saves; the returned `raw` is persisted by
1683+
the client through `POST /api/static` (the normal backup + restart path), which is why it
1684+
works identically on the Host and on a remote agent.
1685+
1686+
Called in two modes:
1687+
1688+
- **Inspect** (no `entrypoint`): returns the entrypoint list with their current
1689+
`trustedIPs`, plus the built-in Cloudflare and private-range presets.
1690+
- **Preview** (with `entrypoint`): additionally returns the merged `raw`, and the
1691+
`existing` / `added` / `invalid` / `final` breakdown for the target entrypoint.
1692+
requestBody:
1693+
required: true
1694+
content:
1695+
application/json:
1696+
schema:
1697+
type: object
1698+
properties:
1699+
current_raw: { type: string, description: "Static config YAML to operate on. Falls back to the file on disk when empty." }
1700+
entrypoint: { type: string, description: "Target entrypoint. Omit for inspect mode." }
1701+
cloudflare: { type: boolean, description: "Include the built-in Cloudflare edge ranges." }
1702+
private: { type: boolean, description: "Include the private-range preset (10/8, 172.16/12, 192.168/16, fc00::/7)." }
1703+
custom_cidrs:
1704+
description: "Extra CIDRs or IPs, as an array or a comma/whitespace-separated string. Invalid entries are returned in `invalid` and skipped."
1705+
oneOf:
1706+
- type: string
1707+
- type: array
1708+
items: { type: string }
1709+
examples:
1710+
inspect:
1711+
summary: Inspect mode
1712+
value:
1713+
current_raw: "entryPoints:\n websecure:\n address: ':443'\n"
1714+
preview:
1715+
summary: Preview a Cloudflare + custom merge
1716+
value:
1717+
current_raw: "entryPoints:\n websecure:\n address: ':443'\n"
1718+
entrypoint: websecure
1719+
cloudflare: true
1720+
custom_cidrs: "203.0.113.10, 198.51.100.0/24"
1721+
responses:
1722+
"200":
1723+
description: Inspect summary, or full preview when an entrypoint was given
1724+
content:
1725+
application/json:
1726+
schema:
1727+
type: object
1728+
properties:
1729+
ok: { type: boolean }
1730+
entrypoints:
1731+
type: array
1732+
description: "Every entrypoint in the static config."
1733+
items:
1734+
type: object
1735+
properties:
1736+
name: { type: string, example: "websecure" }
1737+
address: { type: string, example: ":443" }
1738+
trusted_ips:
1739+
type: array
1740+
items: { type: string }
1741+
description: "The entrypoint's current forwardedHeaders.trustedIPs."
1742+
cloudflare_captured: { type: string, description: "Capture date of the bundled Cloudflare ranges.", example: "2026-07-23" }
1743+
cloudflare_ranges: { type: array, items: { type: string } }
1744+
private_ranges: { type: array, items: { type: string } }
1745+
entrypoint: { type: string, description: "Preview mode only: the target entrypoint." }
1746+
existing:
1747+
type: array
1748+
items: { type: string }
1749+
description: "Preview mode only: trustedIPs before the merge."
1750+
added:
1751+
type: array
1752+
items: { type: string }
1753+
description: "Preview mode only: ranges the merge would add (excludes duplicates)."
1754+
invalid:
1755+
type: array
1756+
items: { type: string }
1757+
description: "Preview mode only: custom entries that failed CIDR/IP validation and were skipped."
1758+
final:
1759+
type: array
1760+
items: { type: string }
1761+
description: "Preview mode only: the resulting trustedIPs (existing + added)."
1762+
raw: { type: string, description: "Preview mode only: the full merged static config YAML, to save via POST /api/static." }
1763+
parsed: { type: object, description: "Preview mode only: the merged config parsed back to JSON." }
1764+
"400":
1765+
description: Named entrypoint not found, or the static config is not a mapping
1766+
content:
1767+
application/json:
1768+
schema: { $ref: "#/components/schemas/ErrorResponse" }
1769+
"404":
1770+
description: No static config on disk and no current_raw supplied
1771+
content:
1772+
application/json:
1773+
schema: { $ref: "#/components/schemas/ErrorResponse" }
1774+
16671775
# ─── CrowdSec ─────────────────────────────────────────────────────────────
16681776

16691777
/api/crowdsec/decisions:

0 commit comments

Comments
 (0)