MCPcopy
hub / github.com/OpenHands/OpenHands / validate_session_key

Function validate_session_key

openhands/app_server/sandbox/session_auth.py:37–100  ·  view source on GitHub ↗

Validate an ``X-Session-API-Key`` and return the associated sandbox. Security: This function enforces that session API keys are only valid for RUNNING sandboxes. This is a critical security measure to prevent leaked keys from being used to access user secrets after a san

(session_api_key: str | None)

Source from the content-addressed store, hash-verified

35
36
37async def validate_session_key(session_api_key: str | None) -> SandboxInfo:
38 """Validate an ``X-Session-API-Key`` and return the associated sandbox.
39
40 Security:
41 This function enforces that session API keys are only valid for RUNNING
42 sandboxes. This is a critical security measure to prevent leaked keys
43 from being used to access user secrets after a sandbox has been paused,
44 stopped, or deleted.
45
46 Raises:
47 HTTPException(401): if the key is missing or does not map to a sandbox.
48 HTTPException(401): if the sandbox is not in RUNNING state.
49 HTTPException(401): in SAAS mode if the sandbox has no owning user.
50 """
51 if not session_api_key:
52 raise HTTPException(
53 status.HTTP_401_UNAUTHORIZED,
54 detail='X-Session-API-Key header is required',
55 )
56
57 # The sandbox service is scoped to users. To look up a sandbox by session
58 # key (which could belong to *any* user) we need an admin context. This
59 # is the same pattern used in webhook_router.valid_sandbox().
60 state = InjectorState()
61 setattr(state, USER_CONTEXT_ATTR, ADMIN)
62
63 async with get_sandbox_service(state) as sandbox_service:
64 sandbox_info = await sandbox_service.get_sandbox_by_session_api_key(
65 session_api_key
66 )
67
68 if sandbox_info is None:
69 raise HTTPException(
70 status.HTTP_401_UNAUTHORIZED, detail='Invalid session API key'
71 )
72
73 # Security: Reject session keys for non-running sandboxes.
74 # This prevents leaked keys from being used to access secrets after
75 # the sandbox has been paused, stopped, or deleted.
76 if sandbox_info.status != SandboxStatus.RUNNING:
77 _logger.warning(
78 'Session key rejected for non-running sandbox',
79 extra={
80 'sandbox_id': sandbox_info.id,
81 'status': sandbox_info.status.value,
82 },
83 )
84 raise HTTPException(
85 status.HTTP_401_UNAUTHORIZED,
86 detail='Sandbox is not running',
87 )
88
89 if not sandbox_info.created_by_user_id:
90 if get_global_config().app_mode == AppMode.SAAS:
91 _logger.error(
92 'Sandbox had no user specified',
93 extra={'sandbox_id': sandbox_info.id},
94 )

Calls 5

get_sandbox_serviceFunction · 0.90
get_global_configFunction · 0.90
warningMethod · 0.80
errorMethod · 0.80