Sign in with Beagle
Let people prove who they are without handing you a password or a key — and keep an honest record of who came, how, and what they did.
September 2026Why identity should work like it does in life
A person's acts and footprints on the network should work like they do in physical life: on the record, and checkable. You walk into a shop. The owner can see that you came, how you arrived, how long you stayed. They cannot take your house keys or demand your password.
That is how social software and platforms have to change if they are going to feel like life instead of like a silo that ate the identity. Decent Network, as it should be, is a set of roles — not one login owned by one app.
| Role | Holds | Must not hold |
|---|---|---|
| User | Their keys, their name, their trail | Does not give a website their password |
| Beagle client (web / CLI / iOS / Android) | Signs on the user's behalf, presents identity | Does not keep the user's session for every other service |
| Service (meet, trader, shop…) | Verifies the proof; records who came, how, and what they did | Never takes private keys or passwords |
| Network (Carrier / userid / ENS) | Public face and a reachable address, as far as the user published it | Not an account database for one product |
A service that wants to treat people well can then do four things it cannot do when identity belongs to someone else:
- Know its users — which door they came through, what they are called, how to reach them, which rooms they joined.
- Reward them — you cannot issue points, tokens, or a seat without a record of attendance and contribution.
- Refuse service — a host choosing who to open the door for, not a platform confiscating keys.
- State conditions of entry — a region, a token, an NFT. The conditions live with you; the verification uses the identity the user presented.
Beagle Meet is that case in production today. People who join a call never hand the room their keys, the room records sign-in and attendance, and the host can reward, refuse, or add a gate. Copy this into your service. Build it with us.
What a service should record — the live case
Beagle Meet stores no private keys, no seed phrases, no passwords. It stores the face a person showed while using the service, and what they did there. That record is what makes rewarding and refusing possible at all.
| Record | What it holds | Why a host needs it |
|---|---|---|
| profiles | userid, name, avatar, Carrier address, which door, first and last seen | Who they are and how to reach them |
| profile_history | Previous name / avatar / Carrier when any of them change | The trail — how someone has presented over time |
| auth_events | Each sign-in: when, source, client, platform, origin | Which door they used |
| attendance | join and leave per room, with client and platform | Who was actually in the meeting — the basis for any reward |
| service_denials | userid, reason, who denied, when | Refusing the whole service |
| room block list | Per-room, set by that room's owner | One room refusing one person |
The host console surfaces these as Attendance, People, Sign-ins, and Access, each row carrying the Carrier address — so a host can message, befriend, or pay someone without ever holding their key.
The shape to copy into a trader, a shop, or a forum is short: proof in, record of use, optional deny, never the key.
Conditions of entry
Checks run in order and the first denial wins: a service-wide deny, then the room owner's block list, then whatever gates you write. A gate receives the identity the user presented — userid, stored profile, which door, which room — and returns a pass or a reason.
registerRoomGate(async (ctx) => {
if (!inRegion(ctx))
return { ok: false, error: 'Not available in your region', code: 'region' };
return { ok: true };
});
registerRoomGate(async (ctx) => {
if (!holdsToken(ctx.userid, ctx.profile))
return { ok: false, error: 'A membership token is required', code: 'token' };
return { ok: true };
});A gate is only as good as the record behind it. Collect profiles and attendance before you start gating on them — and gate on what the user presented or what you can look up yourself on-chain, never on something you asked them to hand over.
Checklist for a new service
Single-use, short-lived. The user signs your origin, so the nonce has to come from you.
Decent popup, Apps launch, and wallet all mint the same session. Rejecting a door just turns users away.
Not a bare hostname, not a bundle id. This is the single most common integration bug.
Keep the Carrier address so you can reach the person later — to message them, add them, or send a reward.
Which door, when, and what they did. Without this you can neither reward nor refuse.
A service-level deny and a per-room block. Retrofitting this under pressure is worse.
Region, token, NFT — written against the identity presented, never against a secret you hold.
The wire-level contract, the crypto primitives (X25519 / XEdDSA, not Ed25519), and the native WebView path are documented alongside the Beagle Meet source. Ask in the beagles group for the current links.