Bypassing Bluesky Age-Assurance on a self-hosted PDS
Modern life consists mostly in refusal.
If you’re unlucky enough to live in the United Kingdom (or apparently Texas) you’re subject to age-checks on various websites, including bluesky. This is only enforced client-side, so you can try and patch it in the browser, or if you’re self-hosting your own bluesky server, you can override the endpoint it uses to check the ageAssurance state. There are various posts about how to do this, but naturally the API changes over time. Here is a currently working caddy config:
handle /xrpc/app.bsky.ageassurance.getState {
vars {
lastInitiatedAt "2026-06-24T10:12:54.275Z"
accountCreatedAt "2026-06-23T12:56:39.174Z"
}
header Content-Type "application/json"
header Access-Control-Allow-Headers "authorization,dpop,atproto-accept-labelers,atproto-proxy,x-atproto-device-id,x-atproto-session-id"
header Access-Control-Allow-Origin "*"
respond `{"state":{"lastInitiatedAt":"{vars.lastInitiatedAt}","status":"assured","access":"full"},"metadata":{"accountCreatedAt":"{vars.accountCreatedAt}"}}` 200
}
Here I’ve extracted the dates to variables for convenience. I’m not sure there’s actually any code that cares about their values but it’s nice for them to be plausible. You can get your correct accountCreatedAt from the public api:
curl -fsSG 'https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile' \
--data-urlencode 'actor=USERNAME' | jq -r '.createdAt'
subbing in your handle without the @. lastInitiatedAt is then supposed to be the time when you validated your age, so some time after that.