carlos / contra Public

Passkeys cannot be exported from 1Password — design the manual path Issue open

Not a deferral so much as a permanent limit that needs a product answer.

1Password does not let passkeys out. No importer, ours or anyone else's, can bring them across. This is 1Password's limit, not a gap in our parser, and pretending otherwise would be the kind of quiet lie the house rules forbid.

So the 1PUX import needs to do three things honestly:

  1. Detect passkey items in the export and count them.
  2. Tell the user exactly which ones need re-creating, by site, as a checklist that survives the import session — not a toast that vanishes.
  3. Never silently drop them. An item that cannot come across is a visible, listed, actionable thing.

Open question for whoever builds it: does the checklist live as real items in the vault (badged "needs re-creating"), or as a separate migration screen? Items-in-the-vault is more likely to actually get done, but puts non-secrets in a surface people curate.

🤖 Answered, by Paul, 2026-09-05 — recording it here because #13 says to settle this before building the passkey half.

Items in the vault, stored as items; a view of their own, not a badge in the list.

The question as written was items-in-the-vault or a separate migration screen, and the answer is that those are two different axes wearing one name. One is where the checklist is stored; the other is where it is shown. Splitting them gets both halves of the trade-off instead of trading one away.

Stored as items, with a distinct type. A list of the sites you hold passkeys for is content in an A1 product — it names services you have accounts with — so it has to be sealed wherever it lives. Reusing the item store means it is sealed by the same path as everything else, covered by the same merciless greps, and needs no new table and no new migration. A separate sealed surface would have been a whole storage surface, with its own canary obligation, for a list people delete once they are done with it.

Shown on its own view, filtered out of the vault list. That answers the real objection in the original question — non-secrets landing in the surface people curate — without paying for a second store. It also means the checklist survives the import session, which a toast does not, because it is a row rather than a notification.

The cost, stated: every path that walks items (search, sharing, the agent surface) now has to know about a row that is not a credential. That is a filter each of them owes, and it is cheaper than a parallel store.

🤖 Update, same day, and it narrows what was decided above.

A desktop .1pux contains no passkeys and no marker that an item ever had one. 1Password exports passkeys only from iOS and Android, through the Credential Exchange standard — never into .1pux. A login that had a passkey exports as an ordinary login, indistinguishable from one that never had one.

So point 1 of this issue, detect passkey items in the export and count them, is not implementable from the file this importer reads. Not a parser gap: the information is absent from the bytes.

Paul's call (2026-09-05): state the limit, do not build a list. The import says plainly that passkeys are not in the file, that we cannot tell which logins had one, and that 1Password's own instruction is to re-create each on the site. No checklist, because populating it would mean guessing — and an empty checklist reads as "you have no passkeys to re-create", which is a worse lie than silence.

The storage decision recorded above still stands if a checklist is ever built: items in the vault, own view. It is simply not built now, because there is nothing truthful to put in it.

Two routes remain open, neither taken today, and both are recorded here rather than lost:

  1. Let the person build the list themselves after import — they know which sites; we do not.
  2. Import Credential Exchange from mobile, which is the only format that actually carries passkeys. That forces a real question first: CONTRA has no WebAuthn provider on the web, so an imported passkey would be stored and unusable until the native app exists.

Leaving this open, since the underlying product problem — a person moving in still has passkeys stranded in 1Password — is not solved by saying so.