FIDO2/WebAuthn Authentication
AuthProxy provides FIDO2/WebAuthn support for hardware security key authentication. This is based on the actual FIDO2 implementation found in the codebase.
FIDO2 Configuration
This configuration is used for FIDO2 keys and also in several other processes.
{
"FIDO2": {
"serverDomain": "domain.com",
"serverName": "web.domain.com",
"timestampDriftTolerance": 300000,
"serverIcon": "https://web.itbuild.app/android-chrome-192x192.png",
"origins": [
"https://localhost:7285",
"http://localhost:7285",
"https://localhost:5173",
"http://localhost:3000"
]
}
}
Configuration Options
| Setting | Description | Example Value |
|---|---|---|
serverDomain | Domain for FIDO2 operations | "yourdomain.com" |
serverName | Display name for FIDO2 | "AuthProxy" |
timestampDriftTolerance | Clock drift tolerance in milliseconds | 300000 |
serverIcon | Icon URL for authenticator display | "https://domain.com/icon.png" |
origins | Static allowed origins | Array of URLs |
API Integration
FIDO2 keys are managed through the same /auth/v1/keys/ endpoints as Ed25519 software passkeys — there are no FIDO2-specific endpoints. The flow distinguishes a FIDO2 enrolment from a software-key enrolment by the payload supplied to register_key.
Register a key (FIDO2 or software)
POST /auth/v1/keys/register_key
Content-Type: application/json
Body (AuthIn):
challengeId—longfrom a preceding/auth/v1/login_optionsor/auth/v1/register_optionscall.code— verification code returned by the registration flow.credentialNew—AuthenticatorAttestationRawResponsefromnavigator.credentials.create()for FIDO2 keys; the server validates it against the challenge'sfido2Options.publicKey— base64url Ed25519 public key for a software passkey (UserKeyorPassKey).passKeyFlag—trueto mark a password-derived key (replaces olderPasswordKeyentries automatically).
A FIDO2 enrolment stores both the public key and the CBOR attestation; a software passkey stores only the Ed25519 public key.
List the current user's keys
GET /auth/v1/keys/user_keys
Returns ApiResponse<List<UserKey>> with id, publicKey (base64url), keyType (PasswordKey | UserKey | FIDO2 | Unknown), utcCreate, current, mcpAccess, cardDavAccess.
Remove a key
POST /auth/v1/keys/remove_key
Content-Type: application/json
{ "keyId": "638412345678901234" }
Soft-deletes the key (KeyFlag.Deleted is OR-ed into flags).
Toggle MCP / CardDAV access
POST /auth/v1/keys/update_key
Content-Type: application/json
{ "keyId": "638412345678901234", "mcpAccess": true, "cardDavAccess": false }
Operator-side bulk listing across users lives in the admin panel (/ProxyAdmin/UserKeys), not on the public API.
Database Storage
FIDO2 keys are stored in the user_key table:
timetick— internal key identifierclient_id— owning user (apguser.timetick)public_key— EdDSA Ed25519 public key (32 bytes); for FIDO2 keys this holds the credential idfido2_key— FIDO2 public key in CBOR formatsign_count— FIDO2 signature counter (reserved; not currently advanced by the platform)flags—KeyFlagbitmask (PasswordKey/UserKey/Fido2Key/McpAccess/CardDav/Deleted)
Implementation Notes
- AuthProxy uses the Fido2NetLib library for FIDO2 attestation and assertion verification.
- Software passkeys and FIDO2 keys live in the same table, distinguished by the
KeyFlagbits. - The maximum number of active keys per user is configurable via
ActiveKeysLimit.
For the live request/response shape see the built-in Swagger UI at /docs/swagger/.