ScalebrowserDOCS

Passkeys

Signing in without a password: where a profile's passkeys live, why they survive a browser that dies badly, why nothing is ever silently deleted, and the two tools an agent gets.

A passkey is a private key a site accepts instead of a password. More and more sign-ups require one, and an account created with one is permanently unreachable without it. For an agent this is access, not a nicety.

The unusual part: there is no tool for signing in with one. The agent clicks the site's own passkey button and the browser answers from inside the profile. Nothing in the agent layer is involved.

Where things live

WhatWhere
The sensor, that this machine has a fingerprint reader at allThe persona, installed into the engine at startup.
The live key, while a browser runsAn encrypted vault file in the data directory.
The saved key, between runsAn encrypted table in the daemon's database.

The sensor is a statement about the machine, not about the agent, which is why it is a persona axis rather than a setting. Roughly 80 to 90 percent of real consumer machines answer that they have one, so a profile claiming none is the unusual one.

Why a vault file exists

Passkeys were the one piece of profile data that lived only in memory. Cookies, sessions and history are written into the profile directory by Chromium itself; a passkey had to be caught before the process died.

Catching works for an orderly stop. It fails for the two ways a browser really ends: somebody closes the window, or it crashes. In the visible-window tier that is not an edge case, it is how a session normally ends.

So the engine writes each new key into the vault immediately, and the daemon reconciles both sides before the engine starts. A stop over the protocol, a closed window, a crash, even a daemon that died alongside it: each of the four paths ends with the key still there at the next start, with the same counter value.

Nothing disappears silently

A passkey that is gone is a retired row with a reason, never a plain delete:

ReasonWhat it means
operatorYou deleted it, in the settings screen or over REST.
agentAn agent retired it with passkey_retire.
site_revokedThe site declared the credential invalid.
unknownRetired for a reason this build cannot name.

operator and agent are kept apart because "I did that" and "something I set running did that" call for different reactions when an account stops working. And unknown claims nothing on purpose: folding it into operator meant a build one version behind told the operator they had deleted a key an agent had retired.

Only a credential proven loaded may be retired for being absent. A key that was never seen is not evidence of anything.

The two tools

Both are in the opt-in extended set.

passkey_list answers which sites this profile can sign in to without a password, with the account name each one recorded. It deliberately does not hand out the credential id.

passkey_retire stops this profile from offering one, for good. It names the key the way the list shows it: site, plus account when the site has more than one, and it refuses to guess when those two do not identify exactly one key.

Over REST the same two operations are GET /v1/profiles/:id/passkeys and DELETE /v1/profiles/:id/passkeys/:credential_id.

What never leaves

The private key. It has no field in any response, no endpoint, and no representation an agent can ask for. It travels between your own machines only inside the sealed sync blob.

The list an agent gets is metadata: site, account name, when it was created, when it was last used.

The counter has to climb

Every use of a passkey increments a signature counter, and the site can watch it. A counter frozen at zero is the signature of a synced passkey rather than a device-bound one, so the daemon takes the higher of what it holds and what it is told, never an assignment.

That is also why a restored backup does not walk a counter backwards.

Next