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
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const models = [
{ value: "claude-sonnet-4-5", label: "Claude Sonnet 4.5" },
{ value: "claude-opus-4-6", label: "Claude Opus 4.6" },
{ value: "claude-opus-4-5", label: "Claude Opus 4.5" },
{ value: "claude-opus-4-1", label: "Claude Opus 4.1" },
{ value: "claude-haiku-4-5", label: "Claude Haiku 4.5" },
];

Expand Down
44 changes: 13 additions & 31 deletions components/runners/claude-code-runner/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# User context sanitization
# ---------------------------------------------------------------------------


def sanitize_user_context(user_id: str, user_name: str) -> tuple[str, str]:
"""Validate and sanitize user context fields to prevent injection attacks."""
if user_id:
Expand All @@ -46,8 +47,8 @@ def sanitize_user_context(user_id: str, user_name: str) -> tuple[str, str]:

# Anthropic API → Vertex AI model name mapping
VERTEX_MODEL_MAP: dict[str, str] = {
"claude-opus-4-6": "claude-opus-4-6@default",
"claude-opus-4-5": "claude-opus-4-5@20251101",
"claude-opus-4-1": "claude-opus-4-1@20250805",
"claude-sonnet-4-5": "claude-sonnet-4-5@20250929",
"claude-haiku-4-5": "claude-haiku-4-5@20251001",
}
Expand All @@ -67,9 +68,7 @@ async def setup_vertex_credentials(context: RunnerContext) -> dict:
Raises:
RuntimeError: If required environment variables are missing.
"""
service_account_path = context.get_env(
"GOOGLE_APPLICATION_CREDENTIALS", ""
).strip()
service_account_path = context.get_env("GOOGLE_APPLICATION_CREDENTIALS", "").strip()
project_id = context.get_env("ANTHROPIC_VERTEX_PROJECT_ID", "").strip()
region = context.get_env("CLOUD_ML_REGION", "").strip()

Expand All @@ -82,9 +81,7 @@ async def setup_vertex_credentials(context: RunnerContext) -> dict:
"ANTHROPIC_VERTEX_PROJECT_ID must be set when CLAUDE_CODE_USE_VERTEX=1"
)
if not region:
raise RuntimeError(
"CLOUD_ML_REGION must be set when CLAUDE_CODE_USE_VERTEX=1"
)
raise RuntimeError("CLOUD_ML_REGION must be set when CLAUDE_CODE_USE_VERTEX=1")

if not Path(service_account_path).exists():
raise RuntimeError(
Expand All @@ -103,6 +100,7 @@ async def setup_vertex_credentials(context: RunnerContext) -> dict:
# Backend credential fetching
# ---------------------------------------------------------------------------


async def _fetch_credential(context: RunnerContext, credential_type: str) -> dict:
"""Fetch credentials from backend API at runtime.

Expand All @@ -114,9 +112,7 @@ async def _fetch_credential(context: RunnerContext, credential_type: str) -> dic
Dictionary with credential data or empty dict if unavailable.
"""
base = os.getenv("BACKEND_API_URL", "").rstrip("/")
project = os.getenv("PROJECT_NAME") or os.getenv(
"AGENTIC_SESSION_NAMESPACE", ""
)
project = os.getenv("PROJECT_NAME") or os.getenv("AGENTIC_SESSION_NAMESPACE", "")
project = project.strip()
session_id = context.session_id

Expand Down Expand Up @@ -154,14 +150,10 @@ def _do_req():

try:
data = _json.loads(resp_text)
logger.info(
f"Successfully fetched {credential_type} credentials from backend"
)
logger.info(f"Successfully fetched {credential_type} credentials from backend")
return data
except Exception as e:
logger.error(
f"Failed to parse {credential_type} credential response: {e}"
)
logger.error(f"Failed to parse {credential_type} credential response: {e}")
return {}


Expand Down Expand Up @@ -190,8 +182,7 @@ async def fetch_jira_credentials(context: RunnerContext) -> dict:
data = await _fetch_credential(context, "jira")
if data.get("apiToken"):
logger.info(
f"Using Jira credentials from backend "
f"(url: {data.get('url', 'unknown')})"
f"Using Jira credentials from backend (url: {data.get('url', 'unknown')})"
)
return data

Expand Down Expand Up @@ -229,9 +220,7 @@ async def fetch_token_for_url(context: RunnerContext, url: str) -> str:
return token

except Exception as e:
logger.warning(
f"Failed to parse URL {url}: {e}, falling back to GitHub token"
)
logger.warning(f"Failed to parse URL {url}: {e}, falling back to GitHub token")
return os.getenv("GITHUB_TOKEN") or await fetch_github_token(context)


Expand Down Expand Up @@ -270,9 +259,7 @@ async def populate_runtime_credentials(context: RunnerContext) -> None:
user_email = google_creds.get("email", "")
if user_email and user_email != "user@example.com":
os.environ["USER_GOOGLE_EMAIL"] = user_email
logger.info(
f"✓ Set USER_GOOGLE_EMAIL to {user_email} for workspace-mcp"
)
logger.info(f"✓ Set USER_GOOGLE_EMAIL to {user_email} for workspace-mcp")

# Jira credentials
jira_creds = await fetch_jira_credentials(context)
Expand Down Expand Up @@ -300,20 +287,15 @@ async def populate_runtime_credentials(context: RunnerContext) -> None:
async def fetch_github_token_legacy(context: RunnerContext) -> str:
"""Legacy method — kept for backward compatibility."""
base = os.getenv("BACKEND_API_URL", "").rstrip("/")
project = os.getenv("PROJECT_NAME") or os.getenv(
"AGENTIC_SESSION_NAMESPACE", ""
)
project = os.getenv("PROJECT_NAME") or os.getenv("AGENTIC_SESSION_NAMESPACE", "")
project = project.strip()
session_id = context.session_id

if not base or not project or not session_id:
logger.warning("Cannot fetch GitHub token: missing environment variables")
return ""

url = (
f"{base}/projects/{project}/agentic-sessions/"
f"{session_id}/github/token"
)
url = f"{base}/projects/{project}/agentic-sessions/{session_id}/github/token"
logger.info(f"Fetching GitHub token from legacy endpoint: {url}")

req = _urllib_request.Request(
Expand Down
Loading
Loading