Administration
This chapter covers administrator-specific functionality for managing passkeys across all backend users.
Admin API endpoints
The extension provides admin-only REST endpoints for credential and account management. All admin endpoints require the requesting user to have TYPO3 admin privileges.
List user credentials
GET /typo3/passkeys/admin/list?beUserUid=<uid>
Returns all credentials (including revoked ones) for a specific backend user.
Response fields per credential:
uid-- Credential record UIDlabel-- User-assigned labelcreatedAt-- Unix timestamp of registrationlastUsedAt-- Unix timestamp of last successful loginisRevoked-- Whether the credential has been revokedrevokedAt-- Unix timestamp of revocation (0 if not revoked)revokedBy-- UID of the admin who revoked the credential
Revoke a credential
POST /typo3/passkeys/admin/remove
Content-Type: application/json
{"beUserUid": 123, "credentialUid": 456}
Revokes a specific passkey for a backend user. The credential is not deleted but marked as revoked with a timestamp and the revoking admin's UID. Revoked credentials cannot be used for authentication.
Unlock a locked account
POST /typo3/passkeys/admin/unlock
Content-Type: application/json
{"beUserUid": 123, "username": "johndoe"}
Resets the lockout counter for a specific backend user. Use this when a user has been locked out due to too many failed authentication attempts and cannot wait for the lockout to expire automatically.
Credential lifecycle
Passkeys go through the following states:
- Registered -- The credential is created via the management API and
stored in the
tx_nrpasskeysbe_credentialtable. - Active -- The credential is used for successful logins. The
last_used_atandsign_countfields are updated on each use. - Revoked -- An administrator revokes the credential via the admin API.
The
revoked_attimestamp andrevoked_byadmin UID are recorded. Revoked credentials remain in the database but are rejected during authentication. - Deleted -- A user removes their own credential via the management API.
The record is soft-deleted (
deleted = 1).
Database table
The extension uses a single table tx_nrpasskeysbe_credential with the
following schema:
| Column | Type | Description |
|---|---|---|
uid | int | Primary key (auto-increment) |
be_user | int | FK to be_users.uid |
credential_id | varbinary | WebAuthn credential ID (unique) |
public_key_cose | blob | COSE-encoded public key |
sign_count | int | Signature counter (replay detection) |
user_handle | varbinary | WebAuthn user handle (SHA-256 hash) |
aaguid | char(36) | Authenticator attestation GUID |
transports | text | JSON array of transport hints |
label | varchar(128) | User-assigned label |
created_at | int | Unix timestamp of creation |
last_used_at | int | Unix timestamp of last use |
revoked_at | int | Unix timestamp of revocation (0=active) |
revoked_by | int | UID of revoking admin (0=not revoked) |
deleted | tinyint | Soft delete flag |
Monitoring
The extension logs all significant events using the PSR-3 logging interface:
- Successful passkey registrations
- Successful passkey logins
- Failed authentication attempts (with hashed username and IP)
- Admin credential revocations
- Admin account unlocks
- Rate limit and lockout triggers
Configure TYPO3 logging writers to capture these events. Example for file logging:
$GLOBALS['TYPO3_CONF_VARS']['LOG']['Netresearch']['NrPasskeysBe']['writerConfiguration'] = [
\Psr\Log\LogLevel::INFO => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => [
'logFileInfix' => 'passkeys',
],
],
];