The added regression tests use keys with unrestricted permissions scoped to a single store: broad authority over actions, with a separate limit on where they apply. One asserts that an administrator-owned key must be denied access to server roles. Another asserts that an ordinary user’s key must be denied deletion of that user’s account.
These examples involve broad store-scoped grants. They do not establish that an invoice-only key can obtain administrator powers. Server-level access also depends on the owner’s administrator role.
The authorization change narrows a fallback used when a request has no resolved scope: accepting a grant from any store is now allowed only for store permissions. That fallback no longer satisfies server-wide or account-wide checks. According to the PR description, existing unscoped administrator keys retain their behavior.
To prevent an authorized key-creation call from producing a more powerful credential, the patch also checks requested permissions against the caller’s grants. An added test asserts rejection when an administrator’s key limited to server-settings authority requests an unrestricted, unscoped key.
Key creation still has separate entry requirements. The self-service endpoint requires unrestricted authority without a store scope; the administrator’s user-targeted endpoint requires server-settings modification authority. The controller change adds a check on what the caller may grant after those requirements are met.
The public PR does not report confirmed exploitation, affected merchants or losses.
Version 2.4.5’s tagged authorization handler and key controller retain the earlier checks changed by this PR. The first affected version remains unclear.
BTCPay’s documentation recommends requesting the narrowest useful permissions. Merchants can review delegated keys for broad grants and their owners’ privileges, then narrow permissions to what each integration needs. The next concrete remediation milestone is a published release containing PR #7684, followed by confirmation that the deployed build includes it.
