GT AI OS Community Edition v2.0.33

Security hardening release addressing CodeQL and Dependabot alerts:

- Fix stack trace exposure in error responses
- Add SSRF protection with DNS resolution checking
- Implement proper URL hostname validation (replaces substring matching)
- Add centralized path sanitization to prevent path traversal
- Fix ReDoS vulnerability in email validation regex
- Improve HTML sanitization in validation utilities
- Fix capability wildcard matching in auth utilities
- Update glob dependency to address CVE
- Add CodeQL suppression comments for verified false positives

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
HackWeasel
2025-12-12 17:04:45 -05:00
commit b9dfb86260
746 changed files with 232071 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
"""
BGE-M3 Embedding Configuration API for Tenant Backend
Provides endpoint to update embedding configuration at runtime.
This allows the tenant backend to switch between local and external embedding endpoints.
"""
from fastapi import APIRouter, HTTPException
from typing import Optional
from pydantic import BaseModel
import logging
import os
from app.services.embedding_client import get_embedding_client
router = APIRouter()
logger = logging.getLogger(__name__)
class BGE_M3_ConfigRequest(BaseModel):
"""BGE-M3 configuration update request"""
is_local_mode: bool = True
external_endpoint: Optional[str] = None
class BGE_M3_ConfigResponse(BaseModel):
"""BGE-M3 configuration response"""
is_local_mode: bool
current_endpoint: str
message: str
@router.post("/config/bge-m3", response_model=BGE_M3_ConfigResponse)
async def update_bge_m3_config(
config_request: BGE_M3_ConfigRequest
) -> BGE_M3_ConfigResponse:
"""
Update BGE-M3 configuration for the tenant backend.
This allows switching between local and external endpoints at runtime.
No authentication required for service-to-service calls.
"""
try:
# Get the global embedding client
embedding_client = get_embedding_client()
# Determine new endpoint
if config_request.is_local_mode:
new_endpoint = os.getenv('EMBEDDING_ENDPOINT', 'http://host.docker.internal:8005')
else:
if not config_request.external_endpoint:
raise HTTPException(status_code=400, detail="External endpoint required when not in local mode")
new_endpoint = config_request.external_endpoint
# Update the client endpoint
embedding_client.update_endpoint(new_endpoint)
# Update environment variables for future client instances
os.environ['BGE_M3_LOCAL_MODE'] = str(config_request.is_local_mode).lower()
if config_request.external_endpoint:
os.environ['BGE_M3_EXTERNAL_ENDPOINT'] = config_request.external_endpoint
logger.info(
f"BGE-M3 configuration updated: "
f"local_mode={config_request.is_local_mode}, "
f"endpoint={new_endpoint}"
)
return BGE_M3_ConfigResponse(
is_local_mode=config_request.is_local_mode,
current_endpoint=new_endpoint,
message=f"BGE-M3 configuration updated to {'local' if config_request.is_local_mode else 'external'} mode"
)
except Exception as e:
logger.error(f"Error updating BGE-M3 config: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/config/bge-m3", response_model=BGE_M3_ConfigResponse)
async def get_bge_m3_config() -> BGE_M3_ConfigResponse:
"""
Get current BGE-M3 configuration.
"""
try:
embedding_client = get_embedding_client()
# Determine if currently in local mode
is_local_mode = os.getenv('BGE_M3_LOCAL_MODE', 'true').lower() == 'true'
return BGE_M3_ConfigResponse(
is_local_mode=is_local_mode,
current_endpoint=embedding_client.base_url,
message="Current BGE-M3 configuration"
)
except Exception as e:
logger.error(f"Error getting BGE-M3 config: {e}")
raise HTTPException(status_code=500, detail=str(e))