← Back to Patterns

Login with HUMΛN Passport

Coming Soonpassportbeginner

# Login with HUMΛN Passport

HUMΛN Passport is a portable, device-rooted identity. When a user logs into your app with Passport, they prove ownership of their private key via a WebAuthn biometric gesture. You get back a delegation token — a scoped JWT you can use to authorize calls to any HUMΛN service.

The full auth chain:

Device biometric → WebAuthn assertion → Session token → Delegation JWT (or hpat_ PAT)
     identity            authentication       session           authorization

Wire format: Authorization: Bearer (three segments) or Authorization: Bearer hpat_… for Passport API tokens. There is no hdgt_ or other prefix on the Bearer credential.

---

Pick your layer

LayerWhat it looks likeWhen to use
1 — React hookusePassportAuth() · React app — magic mode, zero config
2 — Web ComponentAny framework — Vue, Angular, Svelte, vanilla HTML
3 — PassportAuth classnew PassportAuth(config)Custom UI, complex workflows, server-side testing
---

Layer 1: React hook (Magic Mode)

npm install @human/passport @human/passport/react

// components/HumanAuth.tsx
'use client';
import { usePassportAuth } from '@human/passport/react';

export function HumanAuth({ onAuthenticated }: { onAuthenticated?: (token: string, did: string) => void }) { const { login, register, isAuthenticated, isLoading, did, delegationToken, error } = usePassportAuth({ apiUrl: process.env.NEXT_PUBLIC_HUMAN_API_URL ?? 'https://api.haio.run', });

if (isAuthenticated && delegationToken && did) { onAuthenticated?.(delegationToken, did); return

Authenticated as {did}

; }

return (

{error &&

{error.message}

}
); }

Or use the pre-built component for zero JSX:

import { HumanPassportAuth } from '@human/passport/react';

{ // Send delegationToken to your server for verification }} />

Environment

# .env.local
NEXT_PUBLIC_HUMAN_API_URL=https://api.haio.run
HUMAN_API_URL=https://api.haio.run     # server-side verify

---

Layer 2: Web Component (any framework)

Works in vanilla HTML, Vue, Angular, Svelte — anywhere custom elements are supported.

npm install @human/passport
# OR use CDN (no install):
# 


Available Web Components:

  • — combined login + register
  • — existing passport only
  • — new passport creation
  • — account recovery
  • — recovery key enrollment
  • React wrapper:

    'use client';
    import { useEffect, useRef } from 'react';

    export function HumanPassportWC({ onAuthenticated }: { onAuthenticated?: (token: string, did: string) => void }) { const ref = useRef(null); useEffect(() => { import('@human/passport').then(() => { const el = ref.current; if (!el) return; const handler = (e: Event) => { const { delegationToken, did } = (e as CustomEvent).detail; onAuthenticated?.(delegationToken, did); }; el.addEventListener('authenticated', handler); return () => el.removeEventListener('authenticated', handler); }); }, [onAuthenticated]); return ; }

    ---

    Layer 3: PassportAuth class (Control Mode)

    Full lifecycle control — use when building custom designs or server-side integrations.

    npm install @human/passport

    import { PassportAuth } from '@human/passport/browser';

    const auth = new PassportAuth({ humanApiUrl: 'https://api.haio.run', fetch: customFetch, // optional — inject for testing });

    // Convenience: authenticate = login + exchange in one call const result = await auth.authenticate(); // result: { token: "eyJ...", did: "did:human:...", capabilities: [...], expiresAt: "..." }

    // Step-by-step control: const session = await auth.login(); // → LoginResult { sessionToken, passportId, did, displayName, verificationTier, expiresAt }

    const delegation = await auth.exchangeForDelegation(session.sessionToken, ['companion:chat']); // → DelegationResult { token: "eyJ...", delegationId, did, capabilities, expiresAt }

    // New passport registration: const minted = await auth.mint('My Name'); // → MintResult { did, passportId, displayName, publicKey, ... }

    ---

    The delegation token

    After auth, you hold a delegation JWT (or hpat_ PAT for automation). This credential:

  • Is sent as Authorization: Bearer (JWT has three dot-separated segments; PAT starts with hpat_)
  • Contains scope claims (e.g. scp array in the JWT)
  • Must be verified server-side — never trust client claims alone
  • Always verify server-side:

    // app/api/auth/verify/route.ts (Next.js App Router)
    export async function POST(request: Request) {
      const { delegationToken } = await request.json();

    const res = await fetch(${process.env.HUMAN_API_URL}/v1/sessions/verify, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: Bearer ${delegationToken}, }, body: JSON.stringify({ token: delegationToken }), });

    if (!res.ok) return Response.json({ error: 'Invalid token' }, { status: 401 }); const verified = await res.json(); // verified: { did: "did:human:...", scopes: ["companion:chat"], exp: 1734307200 } return Response.json({ verified: true, did: verified.did }); }

    ---

    Common scopes

    ScopeWhat it grants
    passport:loginCreate session + delegation token
    companion:chatAI chat via Companion
    kb:read:publicPublic KB access in Companion
    kb:read:internalInternal KB (admin-granted)
    human_api:agents:invokeCall agents directly
    org:settings:readRead org settings
    ---

    Testing

    MockPassport server (no device required in CI):

    human login --local   # starts MockPassport on :3777

    Injectable fetch (unit tests, no server):

    import { PassportAuth } from '@human/passport/browser';

    const TEST_JWT = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6aHVtYW46dGVzdCJ9.mock_sig';

    const auth = new PassportAuth({ humanApiUrl: 'http://localhost:3777', fetch: async (url, options) => { if (String(url).includes('/v1/passport/delegation')) { return new Response(JSON.stringify({ token: TEST_JWT, delegationId: 'dlg_test', did: 'did:human:test_user', capabilities: ['companion:chat'], passportId: 'psp_test', verificationTier: 1, identityTier: 1, createdAt: new Date().toISOString(), expiresAt: new Date(Date.now() + 3600000).toISOString(), })); } return fetch(url, options); }, });

    const result = await auth.authenticate(); // result.token is a JWT-shaped delegation token

    ---

    Quick start with MCP scaffold

    If you have the HUMΛN MCP server connected:

    human.scaffold({ type: "passport-auth", framework: "nextjs-app-router" })

    Returns ready-to-write files (components/HumanAuth.tsx + app/api/auth/verify/route.ts) plus install_cmd, env_vars, and next_steps.

    ---

    Next steps

  • Delegation scope vocabulary
  • Embed Companion widget — add AI chat after auth
  • Passport identity deep dive — DIDs, key management, recovery
  • Coming Soon

    This pattern is currently under development. It will be available when the HUMAN SDK is released.

    Get notified when SDK launches →