🐛 Prevent MCP tokens from being used as access tokens (#10962)

MCP tokens now use a separate JWT issuer claim (`urn:penpot:mcp-token`) instead of `access-token`, preventing them from being validated as API access tokens.

Fixes #10960

AI-assisted-by: qwen3.7-plus
This commit is contained in:
Andrey Antukh 2026-07-31 13:19:45 +02:00 committed by GitHub
parent 9bb5861322
commit ab1c70115b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 1 deletions

View File

@ -37,7 +37,8 @@
(let [token-id (uuid/next)
expires-at (some-> expiration (ct/in-future))
created-at (ct/now)
token (tokens/generate cfg {:iss "access-token"
token-iss (if (= type "mcp") "urn:penpot:mcp-token" "access-token")
token (tokens/generate cfg {:iss token-iss
:uid profile-id
:iat created-at
:tid token-id})

View File

@ -9,6 +9,7 @@
[app.common.uuid :as uuid]
[app.db :as db]
[app.http :as http]
[app.http.access-token :as actoken]
[app.rpc :as-alias rpc]
[app.storage :as sto]
[backend-tests.helpers :as th]
@ -205,3 +206,29 @@
(t/is (not (contains? all-ids (:id first-mcp))))
(t/is (not (contains? all-ids (:id second-mcp))))
(t/is (contains? all-ids (:id third-mcp))))))))
(t/deftest mcp-tokens-cannot-be-used-as-access-tokens
(let [prof (th/create-profile* 1 {:is-active true})
cfg th/*system*]
(t/testing "MCP tokens use different issuer claim"
(let [{:keys [result]} (th/command! {::th/type :create-access-token
::rpc/profile-id (:id prof)
:type "mcp"
:name "mcp token"})
mcp-token (:token result)
;; Try to decode as access token (should fail)
decoded (actoken/decode-token cfg mcp-token)]
(t/is (nil? decoded))))
(t/testing "Regular access tokens use access-token issuer claim"
(let [{:keys [result]} (th/command! {::th/type :create-access-token
::rpc/profile-id (:id prof)
:name "regular token"})
access-token (:token result)
;; Should decode successfully
decoded (actoken/decode-token cfg access-token)]
(t/is (some? decoded))
(t/is (= (:id prof) (:uid decoded)))))))