One interactive diagram walks the whole of a third-party sign-in: from the button you press, through the single tap on your phone, to the moment you are actually signed in. No reusable KeyLockr login password is handed over, and no blanket access is quietly granted. The jargon is not hidden — hover or tap any box or arrow for the plain-language version.
The app never receives a reusable KeyLockr login password. After you approve on your phone, it receives a one-time result signed by the KeyLockr server and encrypted for that recipient.
Before it draws anything, your phone asks the server which registered service is behind the request and puts that name on screen. Nothing is written anywhere until you tap approve.
You grant one named capability at a time, each spelled out on the approval screen. One tap on the phone stops future access; it cannot claw back content the service already read or stored.
This is a timeline: left to right is request, approval on the phone, and server issuance, then back around to the finished session. Dashed lines are paths that exist afterwards, not steps in this run. Click any box or arrow for the full story; press Esc to close.
There are exactly three capabilities, named the same way in the code. The ceiling for each is fixed when the service registers; your approval can only stay inside that ceiling or narrow it further.
| Capability | What it allows | Who sets the ceiling |
|---|---|---|
sso |
Sign in to that service as you, and nothing else. It cannot read a single password, note, or 2FA entry. | Registration, then your per-request approval. |
app_data |
Lets the service keep a small encrypted blob of its own. Your device encrypts it; neither the server nor that service's backend sees plaintext. | The service's data_approved flag, plus your approval. |
ap |
Treats the service as an Access Point that may read entries inside a scope you allow. The scope is limited to 2fa, passwords, and notes. |
Requires KeyLockr admin approval (ap_approved), then your choice of scope. |
ap capability with 2fa in scope may receive short-lived current and next codes after phone approval, but never the seed needed to generate codes indefinitely.
A grant is one row, unique on (safe_id, app_tag, sign_pk). If a service turns up with a different signing key it is a different binding, and it inherits nothing.
That row also holds the envelopes addressed to the service. Deletion stops new delivery, but cannot erase data the service already opened or stored.
Running app_del on the phone that granted access deletes the row and its envelopes together. The other side does not have to cooperate or agree.
Afterwards, KeyLockr refuses later requests and stops delivering new envelopes. If the service saved plaintext or keys before revocation, revocation cannot remotely erase those copies.
What follows is the actual protocol behaviour, not an illustration. Action names, parameters, and limits match the code.
| Item | Specification |
|---|---|
| Handshake address | sso://login?tmp_id=... (white-label) / keylockr://sso?tmp_id=... (branded) |
| Identifying the requester | app_scan_info — returns the registered title and app_tag. A read; it grants nothing. |
| Creating the binding | app_add — writes one binding row and its envelopes, unique on (safe_id, app_tag, sign_pk). |
| Revoking | app_del — deletes the row and envelopes; only the Safe that approved it may run this. |
| The sign-in result | app_auth_result Signed by the KeyLockr server with Ed25519 and sealed with box to the app's enc_pk; the recipient verifies with the server signing public key. |
| Result size limit | 12 KiB. Beyond that the server answers app_auth_result_too_large; nothing is silently truncated. |
| Larger payloads | Switch to data_deferred: the result carries a pointer and the app fetches the body itself with app_get_data / app_set_data. |
| Delivery paths | Both at once: a push down the tmp channel, and the keylockr_result parameter (base64url) on the return URL. The two are byte-for-byte identical. |
| De-duplication | First-valid-wins: keep the first copy that verifies and discard the rest silently. One approval yields one session. |
| Where to verify | Always verify the signature on your backend, never in the UI. The front end's only job is to hand the result to the backend. |
tmp_id |
A one-time handshake address. It is not an account and not a key; once used or expired it means nothing. |
| tmp device | The WebSocket connection the login page opens. It owns nothing, expires on its own, and losing it costs nothing. |
capabilities |
The list of named powers you granted — only sso, app_data, and ap exist. Anything not on the list is not permitted. |
app_tag |
The service's identifier, fixed at registration. The name on your approval screen corresponds to it. |
| Ed25519 | The signature algorithm. It proves a frame was signed by a particular private key; change one byte and it no longer verifies. |
| Safe | Your phone. Every approval happens here, and so does every revocation. |
| AP (Access Point) | A consumer allowed to read entries. The phone grants its access and the phone takes it back. |
| KPS | KeyLockr Protocol Suite — the frame format devices speak, always signed on the outside. |