commits
Add GATEKEEPER_REQUEST_LOGGING=true to enable per-request tracing
with method, path, client_ip, status, and latency_ms. Disabled by
default — existing behavior unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Firefox rejects credentialed cross-origin requests when
Access-Control-Allow-Headers is `*`, because per the Fetch spec
the wildcard is not treated as a wildcard when credentials are
involved. This causes failures on endpoints like getSession
and createSession when accessed from bsky.app.
Switch from `.allow_headers(Any)` to `.allow_headers(AllowHeaders::mirror_request())`
which echoes the browser's Access-Control-Request-Headers back verbatim,
matching the behaviour of the PDS's Express cors middleware.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
example
```
// Multi-community endpoint
.route("/xrpc/community.shared.moderation.report",
post(report).layer(from_fn_with_state(
with_rules(AuthRules::All(vec![
AuthRules::HandleEndsWithAny(vec![
".blacksky.team".into(),
".bsky.team".into(),
".mod.social".into(),
]),
AuthRules::ScopeEquals("atproto".into()),
]), &state),
auth_middleware
)))
```
Adds two new features to allow PDS admins to gatekeep their PDS from bots creating accounts instead of invite codes
Firefox rejects credentialed cross-origin requests when
Access-Control-Allow-Headers is `*`, because per the Fetch spec
the wildcard is not treated as a wildcard when credentials are
involved. This causes failures on endpoints like getSession
and createSession when accessed from bsky.app.
Switch from `.allow_headers(Any)` to `.allow_headers(AllowHeaders::mirror_request())`
which echoes the browser's Access-Control-Request-Headers back verbatim,
matching the behaviour of the PDS's Express cors middleware.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
example
```
// Multi-community endpoint
.route("/xrpc/community.shared.moderation.report",
post(report).layer(from_fn_with_state(
with_rules(AuthRules::All(vec![
AuthRules::HandleEndsWithAny(vec![
".blacksky.team".into(),
".bsky.team".into(),
".mod.social".into(),
]),
AuthRules::ScopeEquals("atproto".into()),
]), &state),
auth_middleware
)))
```