Identities and passkeys

Prompt:

Add my GitHub sign-in to the same account.

Also works:

  • "Which passkeys work on this site?"
  • "I lost the phone that held my passkey. Remove it."

What your tool does

  • Calls read_account first, to list the account's identities and its passkey counts.
  • For "add my GitHub sign-in", calls link_identity and prints the link_url from the response. It asks you to open the link in a browser within ten minutes and sign in with the other provider. It then calls read_account to confirm the identity is listed.
  • For a passkey, gives you the passkey page's address. You register and remove passkeys in your browser, and the tool has no action that does it.
  • Writes nothing into your project, and changes nothing on your account unless you ask.

What you need

  • A web browser, and if you're linking a second sign-in method, an account with that other provider.
  • For a passkey, an account that signs in by emailed code, and a device or password manager that can store one.

Before your AI starts

This section is for your AI tool: what it checks and gathers before it begins. You don't need to do these steps yourself.

Steps

read_account lists the account's identities, each a provider and the subject it verified.

To add a second sign-in, your tool calls link_identity. It returns a link, valid for ten minutes, which you open in a browser and complete with the other provider. Accounts are never linked by matching email addresses.

A new Google or GitHub sign-in whose address another account already uses is offered a link to that account instead. The page also offers a code to that address.

If your account already uses an address through Google or GitHub, signing in by code to that address adds the code as a sign-in method to that account. It does not create a second account. read_account then lists an identity with provider email and the address as its subject. Connect your tool covers the emailed code.

2. Register and remove passkeys

A passkey is a faster way to sign in by emailed code: it signs you in without waiting for the code. Right after you sign in by emailed code, while your account has no passkey on this host, the platform offers to register one. A sign-in with Google or GitHub offers none, so an account that signs in only with Google or GitHub is not offered a passkey.

To add a passkey to such an account, sign in by code once at the address your Google or GitHub sign-in verified. That adds the code to your account, as step 1 says, and the offer follows. A code sent to another address creates a new account instead. On an account without the emailed code, the passkey page says how to add it, in place of the control that adds a passkey.

If you decline the offer, it returns after thirty days, and the passkey page adds one at any time. A sign-in you make to approve a waiting request is the exception: it goes straight to the request, and the offer waits for your next sign-in by code. A passkey works only on the platform's own host and cannot be used on a look-alike site.

The offer stays open for ten minutes. Signing out everywhere, or a suspension of the account, ends it early; signing that browser out clears the offer's cookie, so the passkey is offered again at your next sign-in by code instead.

The sign-in page offers your saved passkey in the email field as you focus it. Inside the email form, after its button, the link Use a passkey instead signs you in with a passkey on a security key or another device.

The passkey page, /auth/passkeys, registers and removes passkeys later. A passkey stays registered when you sign out, because signing out ends sessions and not passkeys. Removing a passkey asks you to confirm with a passkey. For a passkey you deleted from its device, the page then offers Remove it without the passkey.

For your own session, read_account also returns passkeys: held, the number of your passkeys that work on this host, and stranded, the number registered for another host. It is null where passkeys are not offered.

A passkey change can be undone for three days from the change, on the passkey page, under a sign-in within the last eight hours. Undoing an addition removes the passkey; undoing a removal restores it. Either signs out every other session and connection of the account at once, and the browser that undid it stays signed in.

An undo also ends every token Turn Zero Blueprint's command was given, and the answer counts them as exchange_tokens_revoked. A token you minted with mint_token stays. If the undo answers internal and tells you to sign in again, do so and run Sign out everywhere: the undo went through, and that ends any token it could not. The notice below contains no link: you reach the undo by signing in to the passkey page.

After you sign in with a passkey, the sign-in page tells your browser's passkey provider which of your passkeys still work. A passkey whose removal can still be undone still counts until its three days end. If you choose a passkey the platform does not have and cannot restore, the page tells the provider it is unknown. A provider that supports these signals can then hide or delete it. An application's own sign-in page does the same for its users. The sign-in never waits for the provider, and its result is the same either way.

3. Passkey notices

Adding or removing a passkey sends a notice from donotreply@turnzero.ai to every address your identities have verified. The one exception is the passkey registered at the offer after the sign-in that created your account.

The platform removes a passkey whose account has no emailed-code sign-in, at the latest the next time it is used, and announces and records that removal the same way. Such a passkey no longer signs you in, and the sign-in page tells your browser's passkey provider it is unknown.

The notice says what changed and when. It says nothing is needed if the change was yours, and otherwise to sign in and review your passkeys. It contains no link. Notices are rate-limited, as Manage end users states for end users. The change is recorded in your account's event record either way.

Expected result

link_identity returns link_url and expires_in: 600. After you complete the link in a browser, read_account lists the new identity.

After a passkey change, read_account returns the new counts under passkeys, and every verified address receives the notice. The Sign-in & security page, /dashboard/sign-in-methods, shows the same counts and your other sign-in methods, with a link to the passkey page.

The same page also holds Sign out everywhere, which ends every session of the account at once.

Refusals

A refusal changes nothing on the platform. The status is the one the HTTP route returns, and the Model Context Protocol (MCP) tool returns the same name. Refusals lists every refusal the platform returns.

Refusal Status Cause Remedy
app_credential_not_admitted 403 The call ran under an application's platform credential, which only read_account accepts. Use your signed-in session or a minted token.
authentication_required 401 No credential matched an account. Sign in again through your tool.
account_suspended 403 The account is suspended, so actions that need your identity, and sign-ins, are refused. Wait for platform staff to reinstate the account, then sign in again.