feat(pat): authenticate personal access tokens

handle_auth resolves a dgpt_pat_ bearer against the database instead of
decoding it as a JWT, for both the Flask and the ASGI routes. Scopes and the
resource filter always come from the token row, and the claims that mark a
PAT are stripped from decoded JWTs so a session token cannot pose as one.
ASGI routes reject tokens unless they name the scope that admits them, and
/api/user/me reports what the calling token may do.
This commit is contained in:
arc53-machine committed 2026-09-19 23:39:58 +01:00
1 parent 22ecc0aee3
commit 174130607a
8 files changed
+604 -3

No files matched your search

+11
View File
@@ -12,6 +12,8 @@ from __future__ import annotations
from flask import jsonify, make_response, request
from flask_restx import Namespace, Resource
from docsgpt.api.pat.tokens import is_pat
me_ns = Namespace("me", description="Current user identity and roles", path="/api")
@@ -31,4 +33,13 @@ class MeResource(Resource):
value = decoded_token.get(field)
if value:
body[field] = value
if is_pat(decoded_token):
# Lets a CLI or pipeline confirm what its token is allowed to do.
body["auth_method"] = "pat"
body["token"] = {
"id": decoded_token.get("pat_id"),
"name": decoded_token.get("pat_name"),
"scopes": decoded_token.get("scopes") or [],
"resource_filter": decoded_token.get("resource_filter") or {},
}
return make_response(jsonify(body), 200)