From 4c5d82c94c2e6dbdcf168be5f9262ebaae425ae4 Mon Sep 17 00:00:00 2001 From: Aleksandr Kolbasov Date: Sat, 7 Feb 2026 03:20:24 +0300 Subject: [PATCH] Passkeys: Permissions Policy support --- keepassxc-browser/content/passkeys-inject.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/keepassxc-browser/content/passkeys-inject.js b/keepassxc-browser/content/passkeys-inject.js index 3ffb1fb..1462fd0 100644 --- a/keepassxc-browser/content/passkeys-inject.js +++ b/keepassxc-browser/content/passkeys-inject.js @@ -63,7 +63,18 @@ const enablePasskeys = async function() { } }; - const isSameOriginWithAncestors = function () { + /** + * @param {'create' | 'get'} action + * @returns {boolean} + */ + const isAllowedByPolicy = function (action) { + // https://www.w3.org/TR/webauthn-2/#sctn-permissions-policy + const policy = document.featurePolicy || document.permissionsPolicy; + if (policy) { + return policy.allowsFeature(`publickey-credentials-${action}`); + } + + // fallback to sameOriginWithAncestors try { return window.origin === window.top.origin; } catch (_err) { @@ -80,14 +91,14 @@ const enablePasskeys = async function() { if (ev.detail.action === 'passkeys_create') { const publicKey = kpxcPasskeysUtils.buildCredentialCreationOptions( ev.detail.publicKey, - isSameOriginWithAncestors(), + isAllowedByPolicy('create'), ); passkeysLogDebug('Passkey request', publicKey); await sendResponse('passkeys_register', publicKey); } else if (ev.detail.action === 'passkeys_get') { const publicKey = kpxcPasskeysUtils.buildCredentialRequestOptions( ev.detail.publicKey, - isSameOriginWithAncestors(), + isAllowedByPolicy('get'), ); passkeysLogDebug('Passkey request', publicKey); await sendResponse('passkeys_get', publicKey);