How to give a second Bluesky account a subdomain handle
Each Bluesky handle needs a TXT record of its own: a subdomain handle like @rubric.hrih.si gets one at _atproto.rubric, because the root domain’s record does nothing for it. That’s the part that’s easy to get wrong. I run two Bluesky accounts on one domain. Mine is @hrih.si, and Rubric, my daily tech edition, posts as @rubric.hrih.si.
One TXT record per handle
Bluesky checks a domain handle by looking for a TXT record at _atproto. followed by the handle. The record holds the account’s DID, the id that stays the same when the handle changes. These are mine:
_atproto.hrih.si TXT "did=did:plc:dx4qyo2eyyf4wqjmygtepbbh"
_atproto.rubric.hrih.si TXT "did=did:plc:ow3tqck73woxcn6qo4mgk4ea"
So the subdomain’s record sits at _atproto.rubric, inside the same zone. Most DNS panels take the name relative to the domain: you type _atproto.rubric and the panel adds .hrih.si. Bluesky’s tutorial shows the same thing for a subdomain called me, whose record is _atproto.me.
There’s no wildcard to fall back on. A made-up name like _atproto.anything.hrih.si doesn’t exist, so a handle without its own record fails the DNS check. That’s also what keeps the accounts apart: each record names exactly one DID.
Getting the value
Sign in as the account that should get the handle. Open Settings, then Account, then Handle, and choose “I have my own domain”. Type the handle, and Bluesky shows the TXT record to create, with that account’s DID in it.
The value belongs to whoever is signed in. For the subdomain, that has to be the second account, not your main one.
Check before you verify
DNS changes take a while to reach every resolver, so I look the record up myself before asking Bluesky to:
nslookup -type=TXT _atproto.rubric.hrih.si 1.1.1.1
dig +short TXT _atproto.rubric.hrih.si @1.1.1.1
Once a public resolver prints the did= line, go back to the app and verify.
The HTTPS method
Bluesky also accepts the DID as a plain-text file at https://<handle>/.well-known/atproto-did, answered with a 200. Neither of my domains has that file (both answer 404). For a subdomain that is also a website, with its own build and deploys, the DNS record is simpler: it works whether or not the site is up, and no release can drop it. Bluesky’s tutorial suggests the HTTPS route for organizations that hand out many subdomains, where a record for each gets tedious.
For an account a script posts from
Rubric posts from a script. It signs in with an app password, created in the account’s settings and kept in the script’s environment, never with the account password. You can revoke an app password on its own, and the account carries on.