Bluesky recently announced that they're complying with the UK's Online Safety Act, which requires users to provide personal identity verification confirming their age (through Epic Games' Kids Web Services) before accessing certain parts of the platform.
This sucks for privacy reasons, but thankfully there are ways to work around it.
This was obvious, but using a VPN to connect from outside the UK will bypass the age assurance requirements entirely.
If you don't already have one, a VPN routes your connection through servers in other countries and prevents your ISP from tracking and selling your browsing data, though you're essentially trading trust from your ISP to your VPN provider instead.
My personal recommendations are Mullvad, IVPN or ProtonVPN.
Don't fall for VPN services that heavily focus on marketing, especially if they market features like "military-grade encryption" or make exaggerated privacy claims.
You don't have to use the official Bluesky app to access the platform. Third-party clients like Klearsky or TOKIMEKI currently don't implement these restrictions. For read-only access without signing in, Anartia is also available.
Note that these alternatives work only as long as their developers don't implement similar age assurance measures or block UK users outright (and as the person behind Anartia, I have no plans to implement such thing.)
You can add the following filter rules to your adblocker.
||bsky.app/ipcc$replace=/(?<="isAgeRestrictedGeo":)true/false/
! Optional, if Bluesky ever adds regional content moderation to UK users
||bsky.app/ipcc$replace=/(?<="countryCode":").+?(?=")/US/
- Open uBlock Origin dashboard › My filters
- Enable Enable my custom filters
- Enable Allow custom filters requiring trust
- Add the rules provided above
- Open Settings › Shields › Content filtering
- Enable Developer mode
- Add the rules provided above to Create custom filters
- Open Adguard Settings › User Rules
- Make sure it's enabled
- Add the rules provided above
Note: Custom filter rules is a paid feature on the Android version.
Based on testing, this seems to produce wonky results. The setup process is also more complex. But if it works, it allows you to use Bluesky's Android app as usual.
- Create a text file containing the filter rules provided above and save it to somewhere accessible
- Open Adguard and navigate to Settings › Filtering › Filters › Custom Filters › Add custom filter
- Tap Browse and locate the text file you created
- Select the file to add it as a custom filter list
Chrome recently introduced breaking changes to their extension platform in the form of Manifest v3, the biggest change involves restricting primarily ad blockers by removing webRequest API in favor of declarativeNetRequest API. It's not quite powerful, but it's good enough for our needs.
And as it turns out, uBlock Origin Lite allows you to add custom declarativeNetRequest (DNR) rules.
- Open uBlock Origin Lite dashboard
- Enable Developer mode
- Head to Develop › View: Custom DNR rules
- Insert the following rules:
---
priority: 1
action:
type: redirect
redirect:
url: https://gist.githubusercontent.com/mary-ext/6e27b24a83838202908808ad528b3318/raw/ipcc-response.json
condition:
requestDomains:
- bsky.app
initiatorDomains:
- bsky.app
- main.bsky.dev
urlFilter: /ipcc
resourceTypes:
- xmlhttprequest
---
priority: 1
action:
type: redirect
redirect:
url: https://gist.githubusercontent.com/mary-ext/6e27b24a83838202908808ad528b3318/raw/getAgeAssuranceState-response.json
condition:
initiatorDomains:
- bsky.app
- main.bsky.dev
urlFilter: /xrpc/app.bsky.unspecced.getAgeAssuranceState
resourceTypes:
- xmlhttprequest
---
You can use userscripts, or scriptlets in Brave.
-
Install a userscript manager
- Chrome: Violentmonkey
- Firefox: Violentmonkey
- Edge: Violentmonkey
- Safari: Userscripts
-
Install this userscript
Open Settings › Shields › Content filtering (or go to about:adblock
)
Enable Developer mode, and add the following scriptlet, saving it as user-bsky-age-assurance.js
.
const _fetch = globalThis.fetch;
globalThis.fetch = async function (req, init) {
if (req instanceof Request) {
const url = new URL(req.url);
switch (url.pathname) {
case "/xrpc/app.bsky.unspecced.getAgeAssuranceState": {
return Response.json({
lastInitiatedAt: "2025-07-14T14:22:43.912Z",
status: "assured",
});
}
}
} else if (req === "https://bsky.app/ipcc") {
return Response.json({
countryCode: "US",
isAgeRestrictedGeo: false,
});
}
return _fetch.call(this, req, init);
};
Then reference the scriptlet in a custom filter.
bsky.app##+js(user-bsky-age-assurance.js)
main.bsky.dev##+js(user-bsky-age-assurance.js)
If your account is hosted on a PDS you own or control, you can add these rules to your Nginx or Caddy configuration.
server {
server_name pds.example.com;
location /xrpc/app.bsky.unspecced.getAgeAssuranceState {
default_type application/json;
add_header access-control-allow-headers "authorization,dpop,atproto-accept-labelers,atproto-proxy" always;
add_header access-control-allow-origin "*" always;
return 200 '{"lastInitiatedAt":"2025-07-14T14:22:43.912Z","status":"assured"}';
}
}
pds.example.com {
handle /xrpc/app.bsky.unspecced.getAgeAssuranceState {
header content-type "application/json"
header access-control-allow-headers "authorization,dpop,atproto-accept-labelers,atproto-proxy"
header access-control-allow-origin "*"
respond `{"lastInitiatedAt":"2025-07-14T14:22:43.912Z","status":"assured"}` 200
}
}
Bluesky's implementation of age-based content restrictions is entirely client-side, this is an intentional design decision. The API (called the "AppView") doesn't impose content restrictions directly and isn't aware of your UK location as requests are proxied through your account's hosting server (called the "PDS").
bsky.app (or the "client") checks your location by making a request to https://bsky.app/ipcc
, which returns:
countryCode
: your country based on IP address, which is used for regional content moderation.isAgeRestrictedGeo
: whether your country mandates identity verification
When isAgeRestrictedGeo
is true, it will then make a request to <pds host>/xrpc/app.bsky.unspecced.getAgeAssuranceState
, which returns:
status
: your account's current verification statuslastInitiated
: when you last started the identity verification process
These workarounds exploit the client-side nature of these checks.
Worth noting that decentralized social networks aren't above the law. All platforms, including Mastodon and other federated networks, must comply with local regulations like the Online Safety Act, and a fully decentralized network may need individual server operators to handle compliance.
It remains unclear whether UK regulators would consider Bluesky's client-side implementation sufficient for OSA compliance. However, Bluesky Social PBC could reasonably argue the restrictions are effectively enforced for users on their PDS using unmodified clients, and that's as far as they can guarantee in a decentralized network like Bluesky.
I am not a lawyer however.
While these workarounds provide immediate relief, consider taking action to address the root cause:
There's an ongoing petition to the UK Parliament calling for the repeal of the Online Safety Act. If you're a UK citizen or resident, consider signing it to show opposition to these privacy-invasive measures.
Reach out to your Member of Parliament to express concerns about the Act's impact on privacy and digital rights. You can find your MP and their contact details on the UK Parliament website.
Mention VPN as an option?