Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ def get_ingest_callback_url() -> str:
# os.environ directly.
JWT_SIGNING_KEY = os.getenv("JWT_SIGNING_KEY")
GOOGLE_OAUTH_CLIENT_ID = os.getenv("GOOGLE_OAUTH_CLIENT_ID")
MICROSOFT_GRAPH_OAUTH_CLIENT_ID = os.getenv("MICROSOFT_GRAPH_OAUTH_CLIENT_ID")
MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET = os.getenv("MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET")
GOOGLE_OAUTH_CLIENT_SECRET = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET")

# IBM AMS authentication (Watsonx Data embedded mode)
Expand Down
21 changes: 15 additions & 6 deletions src/connectors/google_drive_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import asyncio
from typing import Any

import jwt
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

Expand Down Expand Up @@ -58,18 +57,28 @@ def google_drive_user_principal(user_email: str | None) -> str | None:


def _email_from_id_token(id_token: str | None) -> str | None:
"""Extract email from Google ID token with signature verification."""
if not id_token:
return None
try:
claims = jwt.decode(
id_token,
options={"verify_signature": False, "verify_aud": False},
)
from config.settings import GOOGLE_OAUTH_CLIENT_ID
from utils.jwt_verification import JWTVerificationError, verify_google_id_token

if not GOOGLE_OAUTH_CLIENT_ID:
logger.error("GOOGLE_OAUTH_CLIENT_ID not configured - cannot verify ID token")
return None

# Verify token with FULL validation
claims = verify_google_id_token(id_token, GOOGLE_OAUTH_CLIENT_ID)
email = claims.get("email")
if email:
return str(email)

except JWTVerificationError as e:
logger.warning("Google ID token verification failed", error=str(e))
except Exception as e:
logger.debug("Could not decode Google id_token email", error=str(e))
logger.error("Unexpected error verifying Google ID token", error=str(e))

return None


Expand Down
50 changes: 40 additions & 10 deletions src/connectors/microsoft_graph_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from typing import Any

import httpx
import jwt

from utils.group_acl import (
acl_principal_label,
Expand All @@ -23,19 +22,33 @@


def tenant_id_from_access_token(access_token: str | None, fallback: str | None = None) -> str:
"""Read the tenant id from a Microsoft access token without validating it."""
"""Extract tenant ID from Microsoft access token with signature verification."""
if access_token:
raw_token = access_token.removeprefix("Bearer ").strip()
try:
claims = jwt.decode(
raw_token,
options={"verify_signature": False, "verify_aud": False},
from config.settings import MICROSOFT_GRAPH_OAUTH_CLIENT_ID
from utils.jwt_verification import (
JWTVerificationError,
verify_microsoft_access_token,
)

if not MICROSOFT_GRAPH_OAUTH_CLIENT_ID:
logger.error(
"MICROSOFT_GRAPH_OAUTH_CLIENT_ID not configured - cannot verify access token"
)
return fallback or "common"

# Verify token with FULL validation
claims = verify_microsoft_access_token(raw_token, MICROSOFT_GRAPH_OAUTH_CLIENT_ID)
token_tenant = claims.get("tid")
if token_tenant:
return token_tenant

except JWTVerificationError as e:
logger.warning("Microsoft access token verification failed", error=str(e))
except Exception as e:
logger.debug("Could not decode Microsoft access token tenant", error=str(e))
logger.error("Unexpected error verifying Microsoft access token", error=str(e))

return fallback or "common"


Expand Down Expand Up @@ -204,14 +217,31 @@ async def get_current_user_microsoft_group_roles(


def _decode_microsoft_user_identifiers(access_token: str, tenant_id: str | None) -> list[str]:
"""Extract user identifiers from Microsoft access token with signature verification."""
raw_token = access_token.removeprefix("Bearer ").strip()
try:
claims = jwt.decode(
raw_token,
options={"verify_signature": False, "verify_aud": False},
from config.settings import MICROSOFT_GRAPH_OAUTH_CLIENT_ID
from utils.jwt_verification import (
JWTVerificationError,
verify_microsoft_access_token,
)

if not MICROSOFT_GRAPH_OAUTH_CLIENT_ID:
logger.error(
"MICROSOFT_GRAPH_OAUTH_CLIENT_ID not configured - cannot verify access token"
)
return []

# Verify token with FULL validation
claims = verify_microsoft_access_token(
raw_token, MICROSOFT_GRAPH_OAUTH_CLIENT_ID, tenant_id=tenant_id
)

except JWTVerificationError as e:
logger.warning("Microsoft access token verification failed", error=str(e))
return []
except Exception as e:
logger.debug("Could not decode Microsoft access token user identifiers", error=str(e))
logger.error("Unexpected error verifying Microsoft access token", error=str(e))
return []

identifiers: list[str] = []
Expand Down
Loading
Loading