Permiso Docs

Callback URL Wildcards

When registering an OIDC client, callback URLs (and logout callback URLs) don’t have to be exact strings. You can use wildcards to match a range of URLs, which is useful for preview deployments, dynamic subdomains, or apps that append query parameters at runtime.

Matching a URL

A callback URL sent by your app must match one of the patterns you’ve registered, once wildcards are expanded. If it doesn’t match any pattern, Permiso rejects the request.

A pattern of * on its own matches any callback URL.

Wildcards in the scheme, host, and port

A single * can replace part of the scheme, hostname, or port:

PatternMatches
*://example.com/callbackAny scheme, e.g. https://example.com/callback or myapp://example.com/callback
https://*.example.com/callbackAny subdomain, e.g. https://app.example.com/callback
https://app-*-server.example.com/callbackPartial segment matches, e.g. https://app-12-server.example.com/callback
https://example.com:*/callbackAny port
https://example.com:80*/callbackAny port starting with 80, e.g. 8080
https://user:*@example.com/callbackAny password in userinfo

Wildcards in the path

The path supports two kinds of wildcards:

  • * matches within a single path segment
  • ** (globstar) matches across multiple path segments
PatternMatches
https://example.com/api/*/callbackhttps://example.com/api/v1/callback, not https://example.com/api/v1/extra/callback
https://example.com/test*https://example.com/test123
https://example.com/**/callbackhttps://example.com/callback, https://example.com/a/b/callback, etc.

Wildcards in query parameters

A * in a query parameter’s value matches any value for that key. The registered pattern and the incoming URL must have the same set of query parameter keys.

PatternMatches
https://example.com/callback?code=*https://example.com/callback?code=abc123
https://example.com/callback?code=*&state=*Any code and state values, but requires both to be present

Loopback redirects

Per RFC 8252, Permiso always allows any port on loopback redirect URIs (http://localhost/..., http://127.0.0.1/..., http://[::1]/...), even without a * in the port. This is meant for native apps that bind to an ephemeral port at runtime.