Authorization Without Authentication
Authentication and authorization solve different problems
Most applications begin with a gate. Before a user can do anything, they have to establish identity: enter an email, retrieve a verification code, choose a password, or follow a magic link. That step is authentication, the process of confirming who someone is against a record held by a central authority.
Authorization answers a different question: what is this person permitted to do? Teams routinely bundle the two into a single “log in” flow, yet they remain distinct operations. Separating them surfaces a useful insight.
A server does not need to know who a user is in order to enforce what they are allowed to do.
JustCall is built on that separation. It has no sign-up, no account table, no password, and no personal data on the server. Authorization carries the entire system, while authentication in the conventional sense is absent. Three building blocks make this possible: a private key, a public key, and a delegated role called the master key.
How public-key identity replaces accounts
The first time you open JustCall, the browser generates a secret locally and never transmits it. From that secret it derives a key pair, and the public half becomes your user ID:
// The private key is generated on your device. The server never sees it.
privateKey = crypto.randomUUID();
// The PUBLIC half, encoded as text, becomes your user ID.
userId = await derivePublicUserId(privateKey);
The identifier is the public key itself, not a database row that points to one. That single decision removes several liabilities that traditional account systems carry:
- No registration step. The server honors requests signed by an ID the moment it first sees them.
- No email or phone number. The ID derives from a random secret on your device, not from any personal detail.
- No password. There is no shared secret to store, hash, or leak, since the server only ever holds the public key.
- No password-reset flow and no credential stuffing, because there are no reusable credentials to attack.
You never disclose an identity to the server. You prove, cryptographically, that you hold the private key behind a given public key, and that proof is sufficient authorization.
How the server authorizes a request
Without sessions or login tokens, each request carries its own proof. The client builds a payload, signs it with the private key, and sends both. On the server, authorization reduces to a single signature check, with no session lookup and no query against a credential store:
const isValid = await verifyPayload(
request.userId, // the public key = the claimed identity
request.payload, // exactly what was signed
request.signature,
);
if (!isValid) {
return jsonResponse({ message: "invalid signature" }, 401);
}
A valid signature makes the request authentic and authorized in one operation. An attacker cannot forge a request for an ID whose private key they do not hold, because they cannot produce a matching signature. Possession of the private key is the authority.
The master key: linking devices without sharing secrets
A model where one device holds the only key breaks down as soon as someone adds a second device. If your phone holds the sole key to your identity, your laptop is a stranger to the system.
The master key resolves this. The first device becomes the master and holds the original secret your ID derives from. Every additional device generates its own separate key pair. A new device cannot sign on your behalf, and the master key is never copied between devices. Linking works through delegation: the master signs a short certificate that binds the new device’s public key to your ID.
// Only the master can authorize a new device.
const authorization = {
action: "device-authorization",
userId: identity.userId,
devicePublicKey: newDevice.devicePublicKey, // the new device's PUBLIC key
role: newDevice.role,
createdAt: Date.now(),
};
const signature = await signPayload(identity.privateKey, authorization);
From then on, the new device signs its own requests with its own key, and the server verifies them against the key the master vouched for. The master issues a credential without ever exposing its secret, in the same way a certificate authority vouches for a website whose private key it does not hold.
This gives you the full vocabulary of a production permission system: roles, delegation, revocation, and least privilege, all expressed through signatures. The master can rename or revoke any linked device, and a revoked device fails its next signature check as its live connection closes.
What a no-account server stores
Look at what the database actually contains. Each account holds a display name the user chose, an optional avatar, and a list of public device keys. Nothing else. There are no emails, phone numbers, password hashes, or security questions, and no private keys, which never leave the user’s devices.
Consider the standard breach scenario in which the entire database leaks. The attacker obtains a set of public keys, which are public by design and useless without the matching private keys, plus a handful of user-chosen display names. They cannot impersonate anyone, because impersonation requires a private key the server never stored. They cannot match users against a password dump, because no passwords exist. They cannot phish anyone through “your email,” because none was ever collected.
A system cannot leak data it never holds. The most dependable way to protect personal information is to avoid collecting it, and an identity model where the ID is a public key makes that literal.
Why passwordless authorization reduces breach risk
Compare the attack surfaces directly. A conventional email-and-password application has to defend a credentials database, password-reset flows, email and SMS code delivery, session tokens, and a body of regulated personal data it is now accountable for. Each of these is a recurring source of account-takeover and breach incidents.
The public-key model defends one thing: the user keeping their key. That is a genuine trade-off, since no central authority can reset a lost key. In exchange, every item on the previous list disappears. The impact of a server compromise narrows to an attacker reading public keys and display names, information that was never sensitive.
Applying public-key authorization in your own app
The pattern generalizes well beyond a calling app:
- Make identity a key pair and make the user ID the public key. Generate it on the client, never transmit the private half, and let the account come into existence the first time the server sees a valid signature.
- Authorize by verifying signatures rather than checking sessions. Each action carries a payload and a signature. Sign over canonical bytes so the client and server agree on exactly what was signed.
- Use a master key to delegate, not to share. When a principal needs to extend trust to a second device, a teammate, or an API client, have the root key sign a scoped, revocable certificate for a new key. The root secret never moves.
- Store only public material, so the answer to “what happens if we are breached” stays uneventful.
A few constraints deserve attention before you ship. Key custody becomes the central problem, so production systems add recovery options such as social recovery, an optional encrypted backup, or a hardware key. Signed requests need a timestamp or nonce to prevent replay. Because there is no identity, spam prevention shifts to rate limits or invitations rather than email verification. None of these undermine the model. They are the ordinary concerns of any system, minus the password database in the middle.
Frequently asked questions
How can an app authorize a user without authentication? It treats possession of a private key as the authority. The public key serves as the user ID, every action is signed by the matching private key, and the server verifies that signature against the public key. The user proves they are allowed to act without proving their identity to a central account system.
Is a no-account model less secure than email and password? In most respects it is more secure. There is no password database to breach, no reset flow to abuse, and no personal data to leak. The trade-off is key custody: if a user loses their key without a backup, no central authority can recover the account.
What is the difference between authentication and authorization? Authentication establishes who you are. Authorization establishes what you are allowed to do. Most systems combine them, but a key pair lets you perform the second without the first.
What happens if JustCall’s servers are breached? An attacker would find public keys and display names. Public keys are meant to be public and are useless without the private keys, which never leave your devices. There are no passwords, emails, or phone numbers to steal.
Can I use more than one device without an account? Yes. The first device acts as the master and signs a certificate that links each new device’s public key to your ID. The master secret is never copied, and the master can revoke any device at any time.