Tessera Phase 0b, workstream W0: proof of concept

Passkey PRF device test

This page checks whether a passkey on this device gives the same encryption key every time: offline, after a restart and in the installed app. It holds no real data and sends nothing. Results stay on this device until you export them.

It creates one throwaway test passkey named Tessera PRF test followed by the date and time. Delete it when you have finished (README, "Delete the test passkey").

Hostname and rp.id
Tool version
Connection
Window
Offline copy

About this device

Saved on this device as you type. Use codes, never names, for the tester and the profile.

What the device modes mean
  • Personal device: one person uses it, with their own passkey.
  • Shared Samsung tablet with separate Android user profiles: each person has their own profile, Google account, screen lock and fingerprint.
  • Shared laptop with separate browser profiles or OS accounts: each person signs in to their own profile or account.
  • Shared device, one profile: several people use the same profile. The weaker mode: it keeps out the operator and thieves, but not colleagues.

Test passkey in use

Where the passkey lives
Carry this passkey's test bundle to another device or profile

The bundle is the sealed test keys, the passkey's id and its key fingerprint. It opens only with the passkey itself, protects nothing real, and is needed for tests 6, 7, 8, 12a and 14. Send it to yourself any way you like.

1. Capabilities

Records what the browser says it supports: the platform authenticator, getClientCapabilities() and whether this is the installed app. What a browser says is recorded, never trusted. Test 3 is what counts.

    2. Create the test passkey

    1. Choose where the passkey lives, under "Test passkey in use".
    2. Press the button and follow the prompt. If you are asked where to save it, choose the provider you are testing and record it under "About this device".

    Whether PRF comes back at creation is recorded. Its absence is not a failure: Samsung Pass and security keys return PRF only when the passkey is used.

      3. Derive and seal

      Unlock once with the new passkey. The page turns its PRF output into a key (HKDF-SHA-256), seals two generated test keys with it, opens them again at once, and stores only the sealed bundle and a fingerprint of the key.

        4. The same key every time

        1. Press "Unlock again" and confirm with your fingerprint, face or PIN. One press for each unlock.
        2. Do it 20 times. Every result must show the same fingerprint.

        After a reload or a restart

        1. Reload this page, then press "Unlock after reload".
        2. Close the browser completely (swipe it away), open this page again, then press "Unlock after browser restart".
        3. Restart the device, open this page again, then press "Unlock after device restart".
        4. If a browser update is waiting, install it, then press "Unlock after browser update".

          5. Offline

          1. Turn on airplane mode and turn Wi-Fi off.
          2. Check that "Connection" at the top of the page says offline.
          3. Press "Unlock offline".
          4. Then restart the device with airplane mode still on, open the page (it opens from its offline copy) and unlock offline again.

            6. Installed app

            1. Install the page. Android Chrome: menu, then "Add to home screen" or "Install app". Samsung Internet: menu, then "Add page to", then "Home screen". iPhone Safari: Share, then "Add to Home Screen". Windows or Mac, Chrome or Edge: "Install page as app". Mac Safari: File, then "Add to Dock".
            2. Open it from the home screen. "Window" at the top should say installed app.
            3. If no passkey is listed there, import the bundle: an iPhone keeps the installed app's storage apart from Safari's.
            4. Unlock 3 to 5 times, once in airplane mode. On field devices, run test 11 here too.

              7. A passkey synced to a second device

              1. On device A, after test 3, copy or download the bundle ("Test passkey in use").
              2. On device B, signed in to the same Google account or Apple Account, open this page on the same hostname and import A's bundle.
              3. Press "Unlock the synced passkey". It must show A's fingerprint.
              4. Then the other way round: create and seal a passkey on B, carry B's bundle to A, and unlock it there.

                8. Laptop using a phone's passkey (QR code)

                For Windows and Mac laptops. Bluetooth must be on, on both the laptop and the phone.

                1. Either import the bundle made on the phone, or press "Create on a phone", scan the QR code with the phone, then run test 3 with the phone.
                2. Press "Unlock with a phone", scan the QR code and confirm on the phone.
                3. Repeat 5 times, with an Android phone and with an iPhone where you have both.

                  9. Security key (optional)

                  Not required to pass. Where a key is at hand: create a passkey on it, run test 3 with it, then unlock 20 times with it.

                    10. Passphrase fallback

                    You choose your own passphrase, so you can remember it instead of writing it down. The page enforces its strength: at least four words or 20 characters, not a common password, and not the same as the login password. The key is derived with PBKDF2-SHA-256 at 600,000 iterations. For this test, choose something new that protects nothing real.

                    Why strength is enforced

                    The passphrase seals a key bundle that is kept on the device and, in Tessera, on the server. Anyone who copies that bundle, the operator included, can try guesses offline with no limit on attempts. The 600,000 iterations make each guess slow; only a phrase nobody would guess makes guessing hopeless. The server also sees the login password at every sign-in, so a passphrase equal to it would hand the operator the key. Capitals and extra spaces are ignored, so a phone capitalising the first letter cannot lock you out.

                    Main test: a passphrase you choose

                    1. Type a made-up login password in the first box. Never type your real one here.
                    2. Choose a passphrase and type it in the second box. The meter shows whether it is accepted. If you want help, press "Suggest a passphrase".
                    3. Press "Seal test keys with this passphrase". The page times the derivation.
                    4. Type the passphrase again under "Unlock and timing" and unlock, then press "Time it three times".

                    Compared on this page as you type, cleared after sealing, never stored and never exported.

                    Refusals

                    1. Type a short phrase, for example sunshine, and press "Seal test keys with this passphrase". It must be refused as too short.
                    2. Type a common one, for example correct horse battery staple, and press it again. It must be refused as too common.
                    3. If you like, type the made-up login password as the passphrase too. It must be refused.

                    Unlock and timing

                      11. Load

                      Unwraps 400 case keys in a worker, decrypts 400 chart headers and one chart of 50 contacts, encrypts and decrypts a 3 MB scan and a 20 MB PDF, then writes 50 MB of ciphertext to IndexedDB, reads it back and deletes it. All of it is generated. It takes from seconds to a few minutes: keep the screen on.

                      On field devices, run it in the installed app, where browsers are likelier to grant persistent storage.

                        12. Shared devices, by device mode

                        12a. Another profile cannot use this passkey

                        1. In profile A: set "Profile" to A, create and seal a passkey (tests 2 and 3), then download or copy its bundle.
                        2. Switch to profile B: another Android user, another browser profile, or another OS account. Open this page there and set "Profile" to B.
                        3. Import A's bundle and press "Try the other profile's passkey". It must be refused. Cancel any prompt that offers a passkey from another device.
                        4. If time allows, repeat from A with B's bundle.

                        12b. A colleague's fingerprint

                        1. A colleague enrols their own fingerprint in the device's settings, if they have not already.
                        2. With your passkey selected, the colleague presses "Unlock with a colleague's fingerprint" and uses their finger.

                        Expected in this mode: it unlocks, because the device accepts any enrolled fingerprint for any passkey on it. The result is recorded, not failed.

                        Is the device's Google or Samsung account shared by several staff?
                        Do several staff know the screen lock PIN?

                        12c. Sign-out clears the keys

                        1. Download the bundle first. Sign-out removes the sealed test keys from this device, as Tessera's sign-out will.
                        2. Unlock once, with any unlock button or the passphrase.
                        3. Check that "Keys in memory" says unlocked, then press "Sign out".
                        4. The page reads its storage back and records anything unlocked that is left. Import the bundle again to carry on testing.

                        Keys in memory:

                        12d. The idle lock

                        1. Choose the idle time. 60 seconds is for testing; Tessera's default for case work is 5 minutes.
                        2. Unlock once, then put the device down without touching it for longer than the idle time. Try it again with the screen turned off.
                        3. Pick it up. The page must say it locked, and "Use the keys in memory" must say locked.

                          14. Wrong hostname (run before 13)

                          A passkey is bound to its relying-party id (rp.id). This page sets rp.id to its own full hostname, so a passkey made here must be unusable from any other hostname.

                          1. On the first test hostname, download the bundle.
                          2. Open this page on the second test hostname (a sibling of the first, never a subdomain of it) and import the bundle there.
                          3. Press attempt A, then attempt B. Both must be refused. Cancel any prompt that appears.
                          Why both must fail

                          Attempt A asks for the first hostname's rp.id from this page. A browser allows an rp.id only when it equals this page's hostname or is a parent domain of it, so it refuses before any prompt, normally with SecurityError. (A browser may first look for a /.well-known/webauthn file on the first hostname; the test host must not serve one.)

                          Attempt B asks for this hostname's own rp.id with the first hostname's passkey id. The authenticator looks passkeys up by rp.id, so the passkey is not found.

                          This is why the rp.id is permanent (hosting decision H12): moving Tessera to a new hostname orphans every passkey unlock. It is also why the rp.id is the full hostname, not tessera-platform.com: a parent-domain rp.id would let every mission's instance under that domain ask for every other mission's passkeys.

                            13. A deleted passkey (run last)

                            1. Make sure test 10 is sealed and you have the passphrase on paper.
                            2. Delete the test passkey in the provider (README, "Delete the test passkey").
                            3. Press "Try the deleted passkey". It must be refused. Cancel any prompt that offers another device.
                            4. Unlock with the passphrase below.
                            5. On a synced device, after the deletion has had time to sync (or after removing the account), try the passkey there too.

                              Summary for this device

                              Blockers

                              The pass rule

                              Send the results

                              The results hold your device notes, the browser's description of itself, each test's outcome and timings, and key fingerprints. They hold no key, no PRF output, no passphrase and no bundle. The page sends nothing: you send the file.

                              When you have finished

                              Delete the test passkey in your password manager (README), then clear this page's data.