Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ memory. The key must authorize both functions. Prefer edge
authentication in production. The default `None` retains legacy query forwarding
with a `DeprecationWarning` for protected registrations; select `"header"`,
`"none"` (no forwarding), or explicitly `"query"` (legacy exposure). The default
will become `"header"` in a future minor release before 1.0.
will become `"header"` in a later minor release before 1.0, not in the release that
first warns; see [Protecting documentation routes](docs/security.md#protecting-documentation-routes).

<details>
<summary>Advanced: describe the schema with raw JSON Schema instead of Pydantic</summary>
Expand Down
6 changes: 4 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ controls protected documentation keys:
| `"none"` | No forwarding; suitable for edge authentication or an anonymous spec |
| `None` (default) | Legacy query behavior with a caller-facing `DeprecationWarning` for protected registrations |

Anonymous routes never forward keys or warn. Explicit values suppress the warning;
the default will become `"header"` in a future minor release before 1.0. The
Anonymous routes never forward keys or warn. Explicit values suppress the warning.
The default will become `"header"` no earlier than the minor release after the one
that first warns, and before 1.0; see the
[migration boundary](security.md#protecting-documentation-routes). The
initial page navigation can still expose the key in access logs before browser
URL replacement. A function-scoped key authorizes only its own function; the
key must authorize both the docs and JSON functions. Prefer production edge auth.
Expand Down
29 changes: 27 additions & 2 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,35 @@ it cannot read or forward a header from the initial page request.
and emits a `DeprecationWarning` once per protected registration. Silence it by
choosing `"header"` explicitly (recommended), or `"none"` for edge-authenticated
or intentionally anonymous specifications. Explicit `"query"` retains the old
key-in-HTML/spec-URL exposure and is only a compatibility escape hatch. The
default will change to `"header"` in a future minor release before 1.0.
key-in-HTML/spec-URL exposure and is only a compatibility escape hatch.
Anonymous registrations never forward a page key, in any mode.

**Who is affected.** Only protected registrations (`auth_level` other than
`ANONYMOUS`) that leave `docs_key_forwarding` unset. Anonymous docs never forward
a key and never change.

| Your setup | What to do |
| --- | --- |
| Opens `/api/docs?code=<key>` in a browser and relies on Swagger UI loading the spec | Set `"header"`. The page behaves the same; the key moves from the spec URL to an `x-functions-key` header on the spec download only. |
| Edge authentication (API Management, Easy Auth) protects the routes **and** the registration uses `auth_level=ANONYMOUS`, or the edge supplies the backend function key itself | Set `"none"`. The page does not need to forward a key. |
| Edge authentication in front of routes that still use `auth_level=FUNCTION` and expect the caller's key | Keep `"header"`. `"none"` would stop sending the key and the spec download would fail authentication even though `/api/docs?code=...` loads. |
| Scripts or tools that read the spec URL out of the served HTML and expect `?code=` in it | Set `"query"` to keep the old output for now, or switch them to send `x-functions-key` to `/api/openapi.json` directly. |
| Anonymous docs | Nothing. No warning, no change. |

**Compatibility boundary.** This package is pre-1.0, so the default is changed in a
minor release, not a patch:

1. The release that first ships the `DeprecationWarning` keeps the default at legacy
`"query"` behavior. No output changes for existing callers.
2. The default changes to `"header"` no earlier than the next minor release after
that, and always before 1.0. That release is announced with a breaking-change
marker so it appears in the release notes (see the Title Convention in
`CONTRIBUTING.md`).
3. Explicit `"query"` keeps working through that change. Removing it would be a
separate, later decision and would be announced the same way.

The switch only affects protected registrations that left the argument unset.

### 3. Enforce access at the platform edge

For identity-aware or policy-based access, keep the documentation endpoints
Expand Down
Loading