@@ -57,8 +57,20 @@ def verify_service_account_identity() -> str | None:
5757 Service account or user email if verified, None otherwise.
5858 """
5959 try :
60- # Cloud Run validates the Authorization header before reaching our app
61- # If we get here, the token is valid - we can safely decode it
60+ # First, try to get email from Cloud Run's injected header
61+ # Format: "accounts.google.com:[email protected] " 62+ goog_email_header = request .headers .get ("X-Goog-Authenticated-User-Email" , "" )
63+ if goog_email_header :
64+ # Strip the prefix if present
65+ if ":" in goog_email_header :
66+ email = goog_email_header .split (":" , 1 )[1 ]
67+ else :
68+ email = goog_email_header
69+ return email
70+
71+ logger .warning ("X-Goog-Authenticated-User-Email header not found" )
72+
73+ # Fallback: try to extract from token
6274 auth_header = request .headers .get ("Authorization" , "" )
6375
6476 if not auth_header or not auth_header .lower ().startswith ("bearer " ):
@@ -71,17 +83,18 @@ def verify_service_account_identity() -> str | None:
7183 # so we don't need to verify signature)
7284 decoded = jwt .decode (token , options = {"verify_signature" : False })
7385
74- # Extract email from token
75- # For service accounts: email field
76- # For user accounts: email field
86+ # Extract email from token (user accounts have this, service accounts may not)
7787 email = decoded .get ("email" )
7888
79- if not email :
80- logger .warning (f"No email in token. Token claims: { list (decoded .keys ())} " )
81- return None
89+ if email :
90+ return email
8291
83- logger .info (f"Authenticated user: { email } " )
84- return email
92+ # For service accounts without email claim, we accept any authenticated caller
93+ # since Cloud Run IAM has already validated the token
94+ # Return a placeholder that indicates authentication succeeded
95+ # The actual authorization happens in get_github_handle_from_workspace_sa
96+ sub = decoded .get ("sub" )
97+ return f"service-account:{ sub } "
8598
8699 except Exception as e :
87100 logger .error (f"Failed to verify service account: { e } " )
@@ -125,7 +138,6 @@ def get_github_handle_from_workspace_sa(service_account_email: str) -> str | Non
125138 logger .warning (f"Participant { github_handle } not found in Firestore" )
126139 return None
127140
128- logger .info (f"Found participant: { github_handle } " )
129141 return github_handle
130142
131143 except Exception as e :
@@ -155,7 +167,6 @@ def generate_custom_token(github_handle: str) -> tuple[bool, str | None, str | N
155167
156168 # Token is returned as bytes, decode to string
157169 token_str = custom_token .decode ("utf-8" )
158- logger .info (f"Generated custom token for { github_handle } " )
159170
160171 return True , token_str , None
161172
0 commit comments