Skip to content

PIN Authentication

PIN authentication provides anonymous, shared-device access. Instead of identifying a specific user, PINs grant access with a specific set of privileges. Ideal for:

  • TV/kiosk displays
  • Shared household devices
  • Guest access with limited permissions
  1. Admin creates a PIN for a project (via admin API or authdash)
  2. User enters the PIN on the auth login page
  3. Auth service verifies against all active PINs for that project
  4. On match: issues a PIN token (sub: "anon", no user identity)

PIN tokens differ from user tokens:

ClaimUser TokenPIN Token
subusr_xxx"anon"
role"admin" / "member""pin_member"
pin_idpin_xxx
privileges["view", "edit"]
emailUser’s email
Refresh lifetime7 days30 days
POST https://auth.beshoy.ai/auth/pin-form
Content-Type: application/x-www-form-urlencoded
POST https://auth.beshoy.ai/auth/pin
Content-Type: application/json
FieldTypeRequiredDescription
pinstringYesNumeric PIN (5+ digits)
project_idstringYesTarget project
redirect_uristringYesWhere to redirect after auth
code_challengestringYesPKCE S256 challenge
statestringYesOpaque state to return

The auth service:

  1. Retrieves all active PINs for the project
  2. Compares the submitted PIN against each hash (Argon2id)
  3. First match wins — no indication of which PIN matched in the response

When a PIN is revoked:

  • New authentications with that PIN are rejected immediately
  • Existing sessions (refresh tokens) are rejected on next refresh attempt
  • Current access tokens remain valid until their 5-minute expiry
  • 5 attempts per 15 minutes per IP per project
  • Same rate limit pool as password authentication

PINs carry a privileges array — arbitrary strings that your app interprets:

{
"pin_id": "pin_abc123",
"privileges": ["view", "edit", "date-spots"]
}

The auth service doesn’t enforce these — it just embeds them in the token. Your app decides what each privilege means.

See Admin PINs API for creating and managing PINs.