Skip to content

docs(server): document the OIDC SSRF guard env vars (#88)#93

Merged
bigpuritz merged 1 commit into
mainfrom
feature/88_oidc-ssrf-guard-env-vars
May 10, 2026
Merged

docs(server): document the OIDC SSRF guard env vars (#88)#93
bigpuritz merged 1 commit into
mainfrom
feature/88_oidc-ssrf-guard-env-vars

Conversation

@bigpuritz
Copy link
Copy Markdown
Contributor

Closes #88.

Plugwerk 1.0.0-beta.3 added an SSRF guard around OIDC discovery and stored issuer/endpoint URIs. The guard rejects private (RFC 1918), loopback, link-local (incl. AWS/GCP/Azure metadata at 169.254.169.254), and ULA IPv6 hosts at write time and at every registry refresh, plus two configurable hostname blocklists, plus a brute-force escape hatch.

The release notes (already shipped in PR #91) call out that the SSRF guard exists. This PR is the operator-facing reference for the three new env vars.

Files changed

File What
server/configuration.mdx 3 new env-var rows + new dedicated "OIDC SSRF guard" section with the configuration surface
server/oidc-providers.mdx Prerequisites, Local-Keycloak <Aside>, Security best-practices, Troubleshooting — each gets a targeted SSRF-guard pointer to the configuration section

No other pages touched.

What the new section covers

  • What is hardcoded vs configurable in a small table — RFC 1918, loopback, link-local (covers all major cloud metadata services), ULA IPv6, IPv4-mapped IPv6: hardcoded. Two hostname blocklists: configurable.
  • Replace-only-semantics prominently as :::caution. This is the most likely operator footgun: setting BLOCKED_HOST_SUFFIXES to a corporate suffix silently drops every default. Two override examples (drop a single default; add a corporate suffix on top of the defaults — full union spelled out).
  • Escape hatch: the literal startup WARN line that fires when ALLOW_PRIVATE_DISCOVERY_URIS=true, plus the production-must-stay-false reminder.

Why correct env-var prefix is PLUGWERK_AUTH_OIDC_*

The issue title said PLUGWERK_SECURITY_OIDC_*; the body said PLUGWERK_AUTH_OIDC_*. Verified against the actual source at v1.0.0-beta.3:

  • plugwerk-server/.../security/url/OidcSsrfPolicy.kt@Value("\${plugwerk.auth.oidc.allow-private-discovery-uris:false}") etc.
  • Confirmed default values: localhost,metadata.google.internal,metadata for BLOCKED_HOST_NAMES, .localhost,.local,.lan,.internal for BLOCKED_HOST_SUFFIXES, false for the escape hatch.
  • Confirmed startup WARN line wording.

Issue title was edited to docs: document PLUGWERK_AUTH_OIDC_* SSRF guard env vars to match. Source files read for accuracy, not cited in the docs (per AGENTS.md no-internal-link rule). Internal-link grep returns 0 hits in the new content.

Acceptance criteria from #88

  • All three variables listed in the configuration reference (table rows + dedicated section)
  • Local-dev page shows the env-var in the Keycloak example (Local Keycloak <Aside> in oidc-providers.mdx)
  • Security/hardening page describes the trade-off and points at the WARN log (oidc-providers.mdx Security best-practices bullet + the dedicated section's escape-hatch sub-block carries the literal WARN line)
  • At least one override example with replace-only semantics — both examples from the issue body are included verbatim

Out of scope

  • A standalone "Security / hardening" page — would be scope-creep for an env-var issue. The OIDC-specific content fits naturally under oidc-providers.mdx Best practices, the configuration-surface content under configuration.mdx. If a dedicated security page is wanted later, this content can be lifted into it without rewriting.

Test plan

  • npm run format clean
  • npm run format:check clean
  • npm run build clean (31 pages)
  • AGENTS.md ADR/internal-PR grep clean in the new content
  • Anchor #oidc-ssrf-guard rendered on /server/configuration/
  • All four cross-links from /server/oidc-providers/ resolve to that anchor
  • Reviewer: open /server/configuration/#oidc-ssrf-guard and verify the :::caution block renders, the table looks readable, the two bash examples render
  • Reviewer: open /server/oidc-providers/, verify the Local-Keycloak <Aside> now contains the env-var snippet, Prerequisites + Best-practices + Troubleshooting all carry their new SSRF pointer

Plugwerk 1.0.0-beta.3 added an SSRF guard around OIDC discovery
and stored issuer/endpoint URIs (rejects private/loopback/link-
local/metadata-service hosts at write and read time, with
configurable hostname blocklists and a brute-force escape hatch).
Three new env vars need documentation:

- PLUGWERK_AUTH_OIDC_ALLOW_PRIVATE_DISCOVERY_URIS  (default false)
- PLUGWERK_AUTH_OIDC_BLOCKED_HOST_NAMES            (replace-only)
- PLUGWERK_AUTH_OIDC_BLOCKED_HOST_SUFFIXES         (replace-only)

server/configuration.mdx:

- Three new rows in the Optional Environment Variables table, each
  pointing at the new dedicated section via #oidc-ssrf-guard.
- New "OIDC SSRF guard" section after the table:
    * Table of what is hardcoded vs configurable (RFC 1918, loopback,
      link-local incl. AWS/GCP/Azure metadata, ULA IPv6, IPv4-mapped
      IPv6 → all hardcoded; two hostname lists → configurable).
    * `:::caution` block on the replace-only semantics — the most
      likely operator footgun ("set BLOCKED_HOST_SUFFIXES to my
      corporate suffix" silently drops the entire default list).
    * Two override examples from the issue (drop `.internal` because
      it is legitimate public; add a corporate suffix on top of the
      defaults — full union spelled out).
    * Escape-hatch sub-block with the literal startup WARN line and
      the explicit production-must-stay-false reminder.

server/oidc-providers.mdx:

- Prerequisites: new bullet on the publicly-resolvable issuer host,
  pointing at the configuration page for the override surface.
- Local Keycloak `<Aside>`: explicit
  `PLUGWERK_AUTH_OIDC_ALLOW_PRIVATE_DISCOVERY_URIS=true` snippet,
  with the production reminder.
- Security and best practices: new bullet on the SSRF guard,
  explaining the metadata-endpoint threat model so the operator
  knows *why* the default is `false`.
- Troubleshooting: new entry "Issuer URI host is blocked" with two
  fix paths (public IdP → check the replace-only blocklists; local
  IdP → escape hatch).

Property names and defaults verified against the actual source at
v1.0.0-beta.3 (OidcSsrfPolicy.kt) — env var prefix is AUTH_OIDC,
not SECURITY_OIDC as the issue title (now corrected) suggested.

Closes #88
@bigpuritz bigpuritz added this to the 1.0.0-beta.3 milestone May 10, 2026
@bigpuritz bigpuritz added the documentation Improvements or additions to documentation label May 10, 2026
@bigpuritz bigpuritz merged commit 8e6b44f into main May 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: document PLUGWERK_AUTH_OIDC_* SSRF guard env vars

1 participant