diff --git a/gsap_broker/routers/authorize.py b/gsap_broker/routers/authorize.py index a841579..8906060 100644 --- a/gsap_broker/routers/authorize.py +++ b/gsap_broker/routers/authorize.py @@ -1,7 +1,7 @@ """POST /governance/authorize/ — GSAP §5.2""" import secrets, uuid from datetime import datetime, timedelta, UTC -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter, Depends, HTTPException, Request from sqlmodel.ext.asyncio.session import AsyncSession from gsap_broker.db import get_session from gsap_broker.db_models import AuthorizationContextDB @@ -14,14 +14,33 @@ from gsap_broker import chronicle router = APIRouter() + +def _extract_token_data(http_request: Request) -> dict: + """Extract and decode JWT from Authorization header (unverified — driver validates).""" + auth = http_request.headers.get("authorization", "") + if not auth.startswith("Bearer "): + return {} + token = auth[7:] + try: + import base64, json + payload = token.split(".")[1] + payload += "=" * (4 - len(payload) % 4) + return json.loads(base64.urlsafe_b64decode(payload)) + except Exception: + return {} + + @router.post("/authorize/", response_model=AuthorizeResponse, summary="Issue AC (GSAP §5.2)") -async def authorize(request: AuthorizeRequest, db: AsyncSession = Depends(get_session)): +async def authorize(body: AuthorizeRequest, http_request: Request, db: AsyncSession = Depends(get_session)): + request = body + token_data = _extract_token_data(http_request) try: driver = DriverRegistry.get(request.driver_id, config={ "requested_accord": request.accord_template, "domain": settings.keycloak_domain, "did_template": settings.keycloak_did_template, "elevated_suffix": settings.keycloak_elevated_role_suffix, + "_token_data": token_data, }) except KeyError as e: raise HTTPException(status_code=400, detail=str(e))