Login with HUMΛN Passport
# 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 authorizationWire 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
| Layer | What it looks like | When to use |
|---|---|---|
| 1 — React hook | usePassportAuth() · | React app — magic mode, zero config |
| 2 — Web Component | | Any framework — Vue, Angular, Svelte, vanilla HTML |
| 3 — PassportAuth class | new 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 enrollmentReact 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/passportimport { 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:
Authorization: Bearer (JWT has three dot-separated segments; PAT starts with hpat_)scp array in the JWT)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
| Scope | What it grants |
|---|---|
passport:login | Create session + delegation token |
companion:chat | AI chat via Companion |
kb:read:public | Public KB access in Companion |
kb:read:internal | Internal KB (admin-granted) |
human_api:agents:invoke | Call agents directly |
org:settings:read | Read org settings |
Testing
MockPassport server (no device required in CI):
human login --local # starts MockPassport on :3777Injectable 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
Coming Soon
This pattern is currently under development. It will be available when the HUMAN SDK is released.
Get notified when SDK launches →