Passkey Authentication and UI access
Human access to the pico-engine developer UI is passkey-based. There are no shared passwords and no central user directory: you prove who you are with a WebAuthn passkey (Touch ID, Windows Hello, a phone, or a security key), and the engine issues a session that unlocks the UI and the internal /c/* API.
Each account is tied to exactly one root pico. That root is your agent in the mesh — the pico you manage after sign-in.
← Back to Identity
What a passkey gives you
After you… | You get… |
|---|---|
Register | A new account, a new root pico, and a signed-in session |
Sign in | A session scoped to your account’s root and its descendants |
Claim (legacy upgrade) | Your existing root linked to your first passkey |
The session is stored in an HTTP-only cookie (pico-session). It lasts 30 days by default and is renewed when you sign in again. Logout clears it.
Sign-in is usernameless: the browser or OS shows passkeys that match this engine; you pick one and complete the biometric or PIN step. You do not type an email or password.
First visit: which screen you see
The UI chooses a flow based on engine state:
Fresh engine (no accounts, no roots)
You see Register with passkey only. Registration creates your account and root pico in one step. This first account is bootstrap — no invite or setup token required.
Optional display name labels your mesh in the UI (defaults to something like pico-abc123 if left blank).
Existing mesh, no auth yet (legacy upgrade)
If the engine already has a root pico from before passkey auth was enabled, you see Claim with passkey instead of register or login. Claim links your passkey to that existing root so your picos and rulesets are preserved.
Normal registration is blocked until claim completes — registering would create a second, orphan root.
Engine with accounts (normal operation)
You see Sign in with passkey. If the operator has enabled open registration, a Create another account link is also shown.
Invite link (?invite=…)
A signed-in user can create a single-use invite link (Settings → Invite). When you open that link:
The UI checks that the invite is valid and not expired (7 days by default).
You see Register with passkey even though the engine already has accounts.
After registration, the invite is consumed and cannot be reused.
If the invite is invalid or expired, the UI shows a warning and registration via that link is not allowed.
Using the UI after sign-in
Once authenticated, the developer UI shows your root pico and its subtree. From there you can:
Browse and manage picos, rulesets, channels, and subscriptions
Open Settings (gear icon) to manage passkeys and invites
Use Logout to end the session
All UI API calls send the session cookie automatically. If the session expires or is cleared, you return to the sign-in gate.
Scope of access
Your session is bound to one root pico. You can work with that root and any pico in its descendant tree. Requests to picos outside your tree are rejected.
This is separate from OAuth, which external apps use on /sky/*. Passkeys are for humans using the engine UI and internal APIs — not for webhook senders or Home Assistant.
When you approve an OAuth app (Authorization Code flow), you must already be signed in. If you were redirected to sign in first, the UI sends you back to the authorize step afterward (oauth_return).
Settings
Open Settings on the main page.
Passkeys
List — passkeys registered for your account (label and date).
Add passkey — enroll another device or security key on the same account. Useful before replacing a laptop or phone.
Remove — delete a passkey you no longer use.
You cannot remove the last passkey on an account. Add another first, then remove the old one.
Adding a passkey does not create a new root or account — it adds another way to sign in to the same account.
Invite links
Available when signed in. Use this when the engine does not allow open self-signup (the default).
Optionally enter a label (shown to the invitee, e.g. “Alice”).
Click Create invite link.
Copy the link and send it to the person who should register.
Each link is single-use and expires after 7 days. The invitee opens the link, registers with a passkey, and gets their own account and root pico.
When self-signup is enabled, anyone can register from the login screen without an invite. Invites still work for controlled onboarding.
What requires a session
Surface | Who | Authentication |
|---|---|---|
Developer UI | You | Passkey → session cookie |
| UI and in-engine HTTP | Session cookie (see localhost note below) |
| Registration, login, session management | Ceremony during WebAuthn; session for management routes |
OAuth app registration, channel credential management | You (signed in) | Session cookie |
/c/* is the internal channel HTTP binding. It is not the public API for third parties. External integrators use /sky/* with OAuth (see sibling pages).
Localhost and in-engine HTTP
By default, requests to /c/* from localhost are allowed without a session. That supports KRL rules that POST to http://localhost:…/c/… from the same machine.
Operators can disable this by setting PICO_ENGINE_ALLOW_LOCALHOST_C=0, which requires a passkey session even from localhost. See Environment variables.
Operator configuration
These environment variables affect human auth:
Variable | Effect |
|---|---|
| Public URL of the engine (scheme + host + port). Must match what users type in the browser. Used as the WebAuthn relying party origin — a mismatch causes registration or sign-in to fail. |
| Set to |
| Set to |
Behind HTTPS, set PICO_ENGINE_BASE_URL to your https://… URL (typically via a reverse proxy). The session cookie is marked Secure when the base URL uses HTTPS.
Troubleshooting
Passkey registration or sign-in fails immediately
Confirm
PICO_ENGINE_BASE_URLmatches the URL in the browser bar (includinghttps://and hostname).On localhost, use
http://localhost:PORTconsistently — not127.0.0.1in one place andlocalhostin another (WebAuthn treats them as different relying parties).
“Self-signup is disabled” when registering
The engine already has accounts and open registration is off. Ask an existing user for an invite link, or have the operator set
PICO_ENGINE_ALLOW_SELF_SIGNUP=true.
“Claim with passkey” instead of login
The engine has a pre-auth root mesh waiting to be linked. Complete claim once; afterward you use normal sign-in.
Locked out
There is no password reset. Recovery requires another passkey still registered on the account (if you added a backup), or operator intervention on the engine data store. Add a second passkey in Settings before retiring a device.
OAuth authorize sent me to sign in and then stopped
After sign-in, the UI should redirect back to the authorize URL. If it does not, open the authorize link again while signed in.
How it fits the identity model
You ──passkey──► account + root pico ──session──► UI and /c/*
│
└── (future) DID/agent identity outward to the meshPasskeys answer “Is this the right human for this root?” Channel policy and OAuth answer “What may this caller do?” on their respective surfaces.