From c1afe3d1590b0226a5132c3d545ee22f034063c6 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Tue, 8 Sep 2026 13:49:43 -0400 Subject: [PATCH] docs: describe the magic link redirect allowlist that already ships docs/api-contract.md said a destination that cannot be expressed as a WebAuthn origin "needs a magic_link_redirect_uris system config key" living in @seamless-auth/types, and that adding it would take a coordinated release. The key landed with types 0.19.0 in #268: it has a default, an env mapping, a parse case, and resolveMagicLinkUrl passes it to allowedRedirect, with tests covering a custom scheme, exact match and the empty-list fallback. The section now describes what the key does, including that a non-empty list becomes the whole allowlist rather than widening the origin comparison, and the system_config table in docs/configuration.md gains the row it was missing. It was the only env-mapped key absent from that table. Closes #242 --- docs/api-contract.md | 16 +++++++++++----- docs/configuration.md | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/api-contract.md b/docs/api-contract.md index 3892003..448c834 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -71,11 +71,17 @@ That is what lets one tenant serve a web client and a mobile client without them single destination. The token is set as a `token` query parameter on the target, replacing one of that name the caller had already put there. -The allowlist is the WebAuthn `origins` list because there is no dedicated one yet. A -destination that cannot be expressed as one of those, a custom scheme such as `myapp://` or a -universal link on a host that is not a WebAuthn origin, needs a `magic_link_redirect_uris` -system config key. That key lives in `@seamless-auth/types` and so needs a version bump and a -coordinated release across this API and both SDKs. +A destination that cannot be expressed as an origin, a custom scheme such as `myapp://auth` or a +universal link on a host that is not a WebAuthn origin, goes in the `magic_link_redirect_uris` +system config key instead. Entries there are matched exactly, which is what makes a custom +scheme safe to accept: there is no origin to compare, so only a literal an operator listed is +allowed. The key defaults to `[]`, and an empty list falls back to comparing against `origins`, +so a deployment that sets nothing behaves as described above. + +Setting it narrows rather than widens. Once the list is non-empty it is the whole allowlist, and +a destination on a configured origin that is not listed is refused. That is deliberate: a tenant +that needs a mobile scheme should not have to widen `origins`, which gates passkey ceremonies, to +get it. ### Error body diff --git a/docs/configuration.md b/docs/configuration.md index ec5f27f..3697c18 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -312,6 +312,7 @@ Validation is enforced by [`systemConfig.schema.ts`](../src/schemas/systemConfig | `rpid` | string | `RPID` | - | | `origins` | url[] | `ORIGINS` | - | | `frontend_url` | url | `FRONTEND_URL` | - | +| `magic_link_redirect_uris` | string[] | `MAGIC_LINK_REDIRECT_URIS` | `[]` | ## Environment vs `system_config`