Skip to content

Commit 211e11b

Browse files
authored
Merge pull request #21 from VectorInstitute/fix_token_service
Fix token service auth header issue
2 parents 9c3da62 + 6b10511 commit 211e11b

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

services/token-service/main.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)