skills/device-authorization/SKILL.md
This skill should be used when the user asks to "implement device auth", "add device authorization", "authenticate desktop app", "authenticate CLI tool", "device code flow", "RFC 8628", "poll for token", "get user info after device auth", or mentions authenticating apps that can't handle browser redirects. Provides step-by-step guidance for device authorization with Sigma Identity.
npx skillsauth add b-open-io/better-auth-plugin device-authorizationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Authenticate desktop apps, CLI tools, and devices without browser redirect capability using Sigma Identity.
1. App requests device code from Sigma
2. User visits verification URL in browser
3. User enters code and approves
4. App polls for token (receives access_token when approved)
5. App fetches user info with Bearer token
All endpoints are on https://auth.sigmaidentity.com:
| Endpoint | Method | Purpose |
|----------|--------|---------|
| /api/auth/device/code | POST | Get device_code and user_code |
| /api/auth/device/token | POST | Poll for access_token |
| /api/auth/oauth2/userinfo | GET | Fetch user info with Bearer token |
const authUrl = "https://auth.sigmaidentity.com";
const response = await fetch(`${authUrl}/api/auth/device/code`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: "your-app-name",
scope: "openid profile",
}),
});
const deviceAuth = await response.json();
// {
// device_code: "abc123...",
// user_code: "ABCD-1234",
// verification_uri: "https://auth.sigmaidentity.com/device",
// verification_uri_complete: "https://auth.sigmaidentity.com/device?code=ABCD-1234",
// expires_in: 900,
// interval: 5
// }
Display the user code prominently and open the verification URL:
// Display to user
console.log(`Enter code: ${deviceAuth.user_code}`);
console.log(`Visit: ${deviceAuth.verification_uri}`);
// Or open browser directly with pre-filled code
openBrowser(deviceAuth.verification_uri_complete);
Poll at the specified interval until user approves:
async function pollForToken(deviceCode: string, interval: number): Promise<string> {
const pollInterval = interval * 1000;
while (true) {
await new Promise(r => setTimeout(r, pollInterval));
const response = await fetch(`${authUrl}/api/auth/device/token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
device_code: deviceCode,
client_id: "your-app-name",
}),
});
const data = await response.json();
if (data.access_token) {
return data.access_token;
}
// Handle error cases per RFC 8628
switch (data.error) {
case "authorization_pending":
continue; // Keep polling
case "slow_down":
pollInterval += 5000; // Increase interval
continue;
case "expired_token":
throw new Error("Code expired - please restart");
case "access_denied":
throw new Error("User denied authorization");
default:
throw new Error(data.error || "Unknown error");
}
}
}
Use the access token to get user details:
const userInfoRes = await fetch(`${authUrl}/api/auth/oauth2/userinfo`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const userInfo = await userInfoRes.json();
// {
// sub: "user-id-123",
// name: "satoshi",
// email: "[email protected]",
// picture: "https://...",
// bap_id: "bap-identity-key", // Sigma-specific
// pubkey: "03abc..." // Sigma-specific
// }
Standard OIDC claims:
sub - User ID (use as userId)name - Display nameemail - Email addresspicture - Avatar URLSigma-specific claims:
bap_id - BAP identity key (use as bapId)pubkey - User's public keybap - Full BAP profile (JSON string)For cross-origin requests from localhost or desktop apps, these endpoints allow any origin:
/api/auth/device/code/api/auth/device/token/api/auth/oauth2/userinfoSecurity is enforced via the access token, not origin validation.
| Error | Meaning | Action |
|-------|---------|--------|
| authorization_pending | User hasn't approved yet | Continue polling |
| slow_down | Polling too fast | Increase interval by 5s |
| expired_token | Code expired (15 min default) | Restart flow |
| access_denied | User denied request | Show error to user |
async function deviceAuth() {
const authUrl = "https://auth.sigmaidentity.com";
// 1. Get device code
const codeRes = await fetch(`${authUrl}/api/auth/device/code`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ client_id: "my-app", scope: "openid profile" }),
});
const deviceAuth = await codeRes.json();
// 2. Show code to user
console.log(`Code: ${deviceAuth.user_code}`);
openBrowser(deviceAuth.verification_uri_complete);
// 3. Poll for token
const accessToken = await pollForToken(
deviceAuth.device_code,
deviceAuth.interval
);
// 4. Fetch user info
const userRes = await fetch(`${authUrl}/api/auth/oauth2/userinfo`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const user = await userRes.json();
return {
userId: user.sub,
bapId: user.bap_id,
name: user.name,
image: user.picture,
};
}
The device authorization flow is the primary mechanism for AI agent authentication. Agents (Claude Code bots, autonomous services, CLI tools) cannot handle browser redirects but need verifiable BAP identities.
/device with their BAP identity and approves the agentbap_id, pubkey) linking the agent to the owner's identityClawNet queries the agent's BAP identity to compute a trust score (0-100) based on:
Higher trust scores enable greater agent autonomy: more skills, higher spending limits, less human-in-the-loop approval required.
For Tauri apps, use the shell plugin to open the browser:
// In Tauri command
use tauri_plugin_shell::ShellExt;
app.shell().open(verification_url, None)?;
Or from JavaScript:
import { open } from "@tauri-apps/plugin-shell";
await open(deviceAuth.verification_uri_complete);
development
This skill should be used when the user asks about "TokenPass", "install TokenPass", "run TokenPass server", "TokenPass desktop app", "TokenPass API", "personal identity server", "be your own OAuth provider", or needs help setting up, configuring, or integrating TokenPass Server or Desktop applications. Provides installation, configuration, and API integration guidance.
tools
Setup Sigma Auth OAuth integration in a Next.js application. Guides through installing @sigma-auth/better-auth-plugin, configuring environment variables, creating auth client, implementing sign-in flow, and setting up API routes for token exchange with Bitcoin-native authentication.
tools
Setup Sigma Auth OAuth integration in a Convex application. Guides through installing @sigma-auth/better-auth-plugin, configuring Convex environment variables, and setting up the auth server.
development
Diagnose and troubleshoot bitcoin-auth token generation and verification issues. This skill should be used when users encounter authentication failures, signature verification errors, or integration problems with the bitcoin-auth library.