> ## Documentation Index
> Fetch the complete documentation index at: https://developers.squads.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Domain

> Host passkey flows on your own custom domain using the Grid WebAuthn proxy.

The advanced integration approach allows you to host passkey flows on your own custom domain (e.g., `auth.yourcompany.com`) while leveraging the Grid API to proxy WebAuthn requests to the blockchain.

**Primary Use Case**: **Custom Domain** - Host passkey authentication on your own domain instead of the default Grid domain for branding, compliance, or security requirements.

<Warning>
  This approach requires WebAuthn expertise and proper challenge handling. Only
  use this if you need your own custom domain. For most applications, use the
  [hosted UI approach](/grid/v1/accounts/passkeys/integration-guide) instead.
</Warning>

## When to Use Advanced Integration

Choose this approach when you need:

* **Custom Domain**: Host passkey flows on `auth.yourcompany.com` instead of the default Grid domain
* **Compliance Requirements**: Internal policies require authentication to happen on company domains
* **Brand Consistency**: Maintain your brand throughout the entire authentication flow
* **Security Policies**: Security requirements mandate own domain usage

## How It Works

### WebAuthn Proxy Flow

1. **Create Session**: Use the passkeys endpoint with your custom `baseUrl`
2. **Extract Challenge**: Parse the challenge from the returned URL
3. **WebAuthn Ceremony**: Implement WebAuthn protocol on your domain with proper ES256 support
4. **Submit Response**: Use the [submit endpoint](/grid/v1/api-reference/endpoint/passkeys/submit) to process the response
5. **Create Account**: Optionally use the [create account endpoint](/grid/v1/api-reference/endpoint/passkeys/create-account) to deploy a smart account
6. **Get Account**: Retrieve account details using the [get account endpoint](/grid/v1/api-reference/endpoint/passkeys/get-account)

### Custom UI Requirements

When implementing a custom passkey UI, your implementation must:

1. **Extract the challenge**: Parse the `challenge` parameter from the URL
2. **Use challenge directly**: Pass the challenge to the WebAuthn protocol as-is (already base64 encoded)
3. **Do NOT re-encode**: The challenge is already base64 encoded - additional encoding will cause errors
4. **Return complete response**: For authentication, return the entire WebAuthn authentication response object
5. **Time constraint**: The challenge is only valid for 60 seconds from URL generation

## Advanced API Endpoints

For custom UI implementations, use these endpoints:

* **[Create Passkey Session](/grid/v1/api-reference/endpoint/passkeys/post)** - Initialize passkey creation with custom baseUrl
* **[Authorize Passkey Session](/grid/v1/api-reference/endpoint/passkeys/auth)** - Authenticate with custom baseUrl
* **[Submit Passkey Session](/grid/v1/api-reference/endpoint/passkeys/submit)** - Process WebAuthn responses
* **[Create Smart Account](/grid/v1/api-reference/endpoint/passkeys/create-account)** - Deploy Grid account with passkey
* **[Get Passkey Account](/grid/v1/api-reference/endpoint/passkeys/get-account)** - Retrieve passkey details
* **[Find Passkey Account](/grid/v1/api-reference/endpoint/passkeys/find)** - Lookup passkey by authenticator

## MetaInfo and BaseURL Usage

### Default vs Custom BaseURL

* **Default baseUrl**: When not specified, Grid uses its default hosted UI which handles the `meta_info` fields
* **Custom baseUrl**: Use your custom domain (e.g., `https://auth.yourcompany.com`) - your UI handles passkey identification and naming

### Example Configuration

```json theme={null}
{
  "meta_info": {
    "appName": "YourCompany App",
    "redirectUrl": "https://yourapp.com/auth-callback"
  },
  "sessionKey": {
    "key": "your-session-key",
    "expiration": 900
  },
  "baseUrl": "https://auth.yourcompany.com"
}
```

## WebAuthn Configuration Requirements

### Required Settings

The on-chain passkey program has specific requirements:

**User Presence Required**:

* `userPresent` must be `true` in the WebAuthn authenticator response
* The authenticator must verify user presence through biometric, PIN, or physical interaction

**Algorithm Requirement**:

* Only ES256 (algorithm `-7`) is supported
* No other cryptographic algorithms are accepted

**WebAuthn Configuration Example**:

```javascript theme={null}
// For passkey creation
const createOptions = {
  publicKey: {
    challenge: challenge, // From API URL - already base64 encoded
    rp: { name: "Your Company" },
    user: {
      /* user info */
    },
    pubKeyCredParams: [{ alg: -7, type: "public-key" }], // REQUIRED: Only -7 (ES256) supported
    authenticatorSelection: {
      userVerification: "preferred", // Ensures user presence
      requireResidentKey: true,
    },
    attestation: "direct",
  },
};

// For authentication
const getOptions = {
  publicKey: {
    challenge: challenge, // From API URL - already base64 encoded
    userVerification: "preferred", // Ensures user presence
    timeout: 60000,
  },
};
```

## Error Handling

### Common Errors

| Error Code                              | Description                           | Solution                  |
| --------------------------------------- | ------------------------------------- | ------------------------- |
| `MissingSessionKey`                     | Session key required for auth actions | Provide valid session key |
| `InvalidAuthenticatorResponse`          | Malformed WebAuthn response           | Validate WebAuthn data    |
| `NoValidExternallySignedAccount`        | Account not found                     | Verify account exists     |
| `InvalidExternallySignedAccountAddress` | Invalid account address format        | Use valid Solana address  |

### Registration Failure Recovery

**If local passkey creation succeeds but submission fails:**

* The passkey exists locally but has no associated on-chain account
* **Solution**: Re-request a new URL and submit again
* The existing local passkey will work with the new challenge
* No need to recreate the local passkey

## Best Practices

### Challenge Handling

* Parse challenge from URL parameters
* Use challenge directly - it's already base64 encoded
* Never re-encode the challenge
* Complete WebAuthn ceremony within 60 seconds of URL generation

### Security

* Validate all inputs
* Use HTTPS for all communications
* Implement proper CORS policies
* Never expose API keys in client-side code
* Store session keys securely on client side
* Validate session expiration on blockchain clock

### Implementation

* Generate unique session keys for each authentication
* Implement comprehensive error handling
* Provide user-friendly error messages
* Use clear, recognizable app names
* Provide loading states during authentication
* Handle environment isolation (sandbox vs production)

### Smart Account Creation

* Use the dedicated create account endpoint after passkey submission
* Store both passkey address and smart account address
* Verify account creation before allowing transactions
* Handle devnet funding appropriately (sandbox only)
* Test account creation flow thoroughly in sandbox

## Getting Started

1. **Review Requirements**: Ensure you have WebAuthn expertise and need custom domain branding
2. **Set Up Domain**: Configure your custom domain for passkey flows
3. **Implement WebAuthn**: Build custom UI following the requirements above
4. **Test on Sandbox**: Thoroughly test your implementation before production
5. **Handle Errors**: Implement robust error handling and recovery
6. **Deploy Smart Accounts**: Use the create account endpoint to deploy Grid accounts

For most applications, consider using the [hosted UI approach](/grid/v1/accounts/passkeys/integration-guide) instead, which handles all this complexity for you including automatic smart account creation.
