License: CC-BY-4.0
For example, in BlueSKy, a handle is a display name, for example lyuma2d.bsky.app.
See Basis documentation: <>
Conceptually, a handle is a username.
However, you can have the backing source of truth for a handle come from other places.
For example, in Steam, Valve / Steam provides the source of truth for a Steam user id number and display name. Or as another example, a database could provide the source of truth for ownership of a handle. Another example of a handle is domain names.
All handles must be valid domain names. Unicode would have to be represented as punycode.
Some handles are globally unique. Other handles are not, or can be changed after they are created. It depends what you're looking for. It depends the platform devleoper what their needs are. Is it a high level of security: Is it something the user self reports, or is it backed by something.
If you are connecting to a realtime server instance (synchronous) and it has temporary state
Some projects might allow users to play without an account, so they might choose a non-unique unverified display name.
There is utility in saying a particular connection has a unique DID (this would have been done through some negotiation process where a proposed username is given to the server and the server can make adjustments to it, such as add a suffix or detect for homograph)
If you want Federation with multiple servers, they do not share a single database. If they don't share a single database, there is no way to have uniqueness guarantees across all servers. By appending the homeserver name to the username, you can create a globally unique handle. You can represent this, for example, as username.vsek.ai.
One of the core things BlueSky did is they want persistent, stable identifiers for a user. For example, you should never change a user's UUID. Especially when you're talking about a federated system, it is literally impossible to change the UUID.
To get around that, what they did is they said that account IDs, for the machine readable identifier of an account, don't attempt to make this human readable. There is a human readable identifier that can be changed and updated, but the machine readable identifier can never be changed.
When we're talking about usernames, at least at the social layer or backend layer, before we're thinking about how a client displays this sutff in game, when we say "handles" or "usernames", we're talking abnout the human readable identifier, not the machine readable identifier
Assertion: a machine readable identifier never needs to be exposed in the UI, not even deep in the menu.
Internally, in various sqlite databases either client side or in the server, the database will store the machine readable identifier.
Assertion: at a particular moment in time, there is a one-to-one (or MAYBE one-to-many) mapping between machine readable identifier human readable identifier. One machine readable identifier can ideally only map to one human readable identifier.
BUT. One handle may map to multiple machine readable identifiers
Let's say a client connects to the instance, using a single bearer token or oauth token, they also need to demonstrate in addition to that, that they have custody of that handle. So there needs to be some additional level of authentication for the handles.
A user can create a one-time id only for use of verifying themselves.
Highly recommend: Do the authentication almost the exact same way that ATProto (BlueSky) performs it.
- DNS TXT record.
- HTTP .well-known/atproto-did
If you do oauth and you just have an opaque Bearer token, it's equivalent to a nonce.
Fire: we picked bearer token because it's simpler Faolan: use public / private keypairs.
We need to make sure anyone can validate this bearer token. JSON Web Token? or ATProto?
Question: what is the public key. WHat do you validate the signature against? Faolan: the host server would have its own public key, but you need a timeout. A user if they want to verify who they say they are, would ask for a verification token.
"Identity proof system"? One-time proof. You can easily automate it. You create one for joining a session. To make it less likely that they are spoofed, you time it.
Butlah: propose how we've been solving this in Nexus and Basis.
Basically, as we described, the user needs some sort of Bearer token. The Bearer token must be validated against some sort of public key. Two cases: either the public key is associated with the homeserver, or the public key is from the user itself. And we need some way to associate that with the user id.
For DID:web, you hit an endpoint, and it gives you this JSON, as in the did:web RFC. Public Private keypairs (ED25519)
e.g. users.vsekai.org/saracen v-sekai.org/api/v1/did/saracen
GET endpoints:
handles reading dids
usernames.v-sekai.org
username.vsek.ai don't use .ai
mix DID should live somewhere.
some of the primitives from ATProto: handles and decentralized identifiers. private keys are stored in a data server.
What to add to your own centralized database:
hostnames would allow users to show up under alice.vsek.ai thebutlah.socialvr.net