How passkeys are scoped to domains.

Domain Passkeys

How Passkeys and Domains Work Together

A passkey created on app.example.com only works on app.example.com. It will not work on other-site.com or even www.example.com.

This is a security feature built into the WebAuthn standard. It prevents phishing attacks.

When creating wallets, the rpIdHash ties the wallet to a specific domain. Passkallet validates that the rpIdHash matches one of your organization's registered domains.

Multiple Passkeys

A single wallet can have multiple passkeys (recovery passkeys). You can query them via the BaaS API:

Endpoint: GET /baas/passkeys?walletAddress=0x...

Required scope: passkey:manage

bash
curl "https://gateway.dev.passkallet.com/sepolia/api/v1/passkallet/baas/passkeys?walletAddress=0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18" \
  -H "x-api-key: pk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4"
json
{
  "statusCode": 200,
  "content": {
    "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
    "passkeys": [
      {
        "qx": "0x1f2e3d4c5b6a...",
        "qy": "0xa0b1c2d3e4f5..."
      }
    ]
  }
}

Computing rpIdHash

The rpIdHash is the SHA-256 hash of the WebAuthn Relying Party ID (your domain name):

javascript
const crypto = require('crypto');
const rpId = 'app.example.com';
const rpIdHash = '0x' + crypto.createHash('sha256').update(rpId).digest('hex');