POST /auth/devices/register
Registers a device's verifying key (public key from Secure Enclave) for MPC operations.
Used in flow: Initial device setup after user registration, device recovery/switch
Authentication: JWT + Device Signature + Conditional Face Verification
Security Model
| Scenario | Face Registered? | Behavior |
|---|---|---|
| Same user, same device key | N/A | No-op, return 200 |
| Same user, NEW device key | ❌ No | Allow registration (201) |
| Same user, NEW device key | ✅ Yes | Require face match (403 → 201) |
| Different user, existing device key | N/A | 409 Conflict |
Request
Authorization: Bearer <access_token>
Content-Type: application/json
Without face verification
{
"device_id": "<hex>",
"signature": "<hex>"
}
With face verification
{
"device_id": "<hex>",
"signature": "<hex>",
"face_scan": "<base64>",
"audit_trail_image": "<base64>",
"low_quality_audit_trail_image": "<base64>",
"user_agent": "<string>"
}
| Field | Type | Required | Description |
|---|---|---|---|
device_id | string | Yes | Hex-encoded uncompressed device public key (04 || X || Y) |
signature | string | Yes | Hex-encoded DER ECDSA P-256 signature |
face_scan | string | Conditional | Required if user has face registered |
audit_trail_image | string | Conditional | Base64-encoded high-quality audit image |
low_quality_audit_trail_image | string | Conditional | Base64-encoded low-quality audit image |
user_agent | string | Conditional | Client's user-agent (required by FaceTec) |
Signature Generation
JSON_MESSAGE = { "challenge": "<hex_challenge_from_get_challenge>" }
Signature = DER-encoded ECDSA (P-256) over SHA256(canonicalize(JSON_MESSAGE).to_utf8_bytes())
// Canonicalization: RFC 8785
Response
201 Created — new device
{
"success": true,
"message": "Device registered successfully"
}
200 OK — device already registered by same user
{
"success": true,
"message": "Device already registered"
}
403 — face verification required
{
"error": {
"code": 100702,
"message": "Face verification required for new device registration",
"requires_face": true
}
}
409 — device owned by different user
{
"error": {
"code": 100603,
"message": "Device already registered"
}
}