Consider adding passkey support to Koha as an authentication mechanism. I have seen this method as an option more frequently now with all the various online services I use. Some articles: 1. Bitwarden article - What are passkeys? https://bitwarden.com/blog/what-are-passkeys-and-passkey-login/ 2. tom's guide - What are passkeys? Everything you need to know about the death of passwords https://www.tomsguide.com/news/what-are-passkeys
See Koha Community Chat thread https://chat.koha-community.org/koha-community/pl/4irec4ocjtyy8pgezeaz9c9nwo Includes "It could also be a gateway to finally moving "password" out of the borrowers table and into a "credentials" table...".
This is properly the best guidance on how to incorporate it: https://www.passkeys.com/guide What we also should do beforehand is to decide on how we'd like to do JSON-RPC in Koha :) See bugs: - 30652: RPC style action endpoint for choosing matches - 34784: Add ability to populate empty item call numbers for a record based on the itemcallnumber system preference - 38224: Move populate_empty_callnumbers logic into Koha::Biblio for reusability - 38226: Add RPC endpoint for batch filling empty callnumbers - 38745: Add a proof of concept JSON-RPC driven endpoint for RPC style calls that don't fit REST ideals Can't yet declare one of them as a dependency for this one.
An article from Troy Hunt attempting to explain passkeys and why they are needed: Passkeys for Normal People (5 May 2025), https://www.troyhunt.com/passkeys-for-normal-people/
Created attachment 185295 [details] [review] Bug 39601: Atomic update
Created attachment 185296 [details] [review] [DO NOT PUSH] Bug 39601: DBIC changes
Created attachment 185297 [details] [review] Bug 39601: Add staff passkeys (WebAuthn) support Introduce staff passkey (WebAuthn) registration and authentication in Koha. Provides REST endpoints, persistence, UI hooks, and session integration so staff can register a passkey against a patron record and authenticate on the staff login screen using platform authenticators. Implementation: - New controller Koha::REST::V1::Webauthn with endpoints: - POST /api/v1/webauthn/register/challenge - POST /api/v1/webauthn/register - POST /api/v1/webauthn/authenticate/challenge - POST /api/v1/webauthn/authenticate - Use Authen::WebAuthn validate_registration/validate_assertion - Generate cryptographically secure challenges; store challenge and patron_id in the session - Handle base64url consistently for WebAuthn fields; convert to/from standard base64 at the API boundary - Derive origin and rp_id from StaffClientBaseURL (or the request URL) to enforce correct WebAuthn origins - Persist credentials (credential_id, public_key as raw bytes) in the new webauthn_credentials table; set created_on as DATETIME; update sign_count and last_used after successful authentication - Build allowCredentials from stored credential IDs for authentication challenges - On successful authentication, issue a staff session and set the CGISESSID cookie so the user is logged in to the staff interface API: - Add api/v1/swagger/paths/webauthn.yaml defining the WebAuthn endpoints, request/response schemas (including allowCredentials), and x-koha- authorization requiring the catalogue permission DB: - Add webauthn_credentials table via installer/data/mysql/atomicupdate/ bug_39601_add_passkey_support.pl - Add Koha::Schema::Result::WebauthnCredential and Koha::WebauthnCredential(s) object classes UI: - Staff login: add JS helper (auth-webauthn.inc) to request a challenge, convert base64url to bytes, call navigator.credentials.get, send results with credentials: "same-origin", and redirect to mainpage on success - Patron page: add JS helper (passkey-register.inc) to request a registration challenge, include RS256 in pubKeyCredParams for compatibility, convert base64url to bytes, and submit attestation for storage Tests: - t/db_dependent/api/v1/webauthn.t: verify challenge endpoints accept patron_id and userid; return 404 when no credentials; include a mocked registration negative path; follow Koha testing conventions - t/db_dependent/Koha/WebauthnCredentials.t: cover ORM add/search/update/delete Documentation notes: - StaffClientBaseURL must match the scheme/host used by the browser (typically https). Ensure staff is served over the same origin for WebAuthn. - New routes under /api/v1/webauthn and a new table webauthn_credentials. Test plan: 1) Apply patches 2) Run database updates to create webauthn_credentials (updatedatabase). 3) Set StaffClientBaseURL to your staff URL (e.g., http://<name>-intra.localhost when using ktd_proxy, haven't tested with unproxied ktd) and ensure the staff interface is served over the same origin. 4) As a staff user, open a patron record and click Register Passkey from More. Complete the OS-native passkey dialog. Verify a row is stored in webauthn_credentials. - This worked well in Zen (Firefox under the hood), less so with Chromium. - Unsure whether ungoogled Chromium supports using the system password manager, worked with a browser-based password manager, though. - Best to test with many browsers! 5) Navigate to the staff login page and choose Sign in with passkey. Verify a challenge is returned, the browser prompts, and you are logged into the staff interface (redirect to mainpage). 6) Call authenticate_challenge for a patron without credentials and verify a 404 response. 7) Run: - prove t/db_dependent/Koha/WebauthnCredential.t - prove t/db_dependent/api/v1/webauthn.t 8) Sign off or review and FQA. NOTE: I think the controllers still need refactoring, this is more a POC regarding the backend.
Forgot something: you need to install libauthen-authn-perl via apt.
(In reply to Paul Derscheid from comment #7) > Forgot something: you need to install libauthen-authn-perl via apt. I think that should be libauthen-webauthn-perl
Yes, sorry, wrote that last minute from memory (which failed me 😅)