1010
1111import asyncio
1212import hashlib
13+ import re
1314import socket
1415import threading
1516import time
3940_SERVER_COMMAND = _POOLED_SERVER_COMMAND
4041_MAX_WS_MESSAGE_SIZE = 100 * 1024 * 1024
4142_MAX_HTTP_RESPONSE_SIZE = 100 * 1024 * 1024
43+ _CREDENTIAL_ENV_NAME = re .compile (
44+ r"(?i)(?:^|[_-])(?:auth(?:orization)?|credentials?|password|passwd|"
45+ r"private[_-]?key|secret|token|api[_-]?key|access[_-]?key(?:[_-]?id)?)"
46+ r"(?:$|[_-])|(?:^|[_-])(?:jwt|pat|askpass)(?:$|[_-])"
47+ )
48+ _CREDENTIAL_ENV_ALIASES = frozenset (
49+ {"PGPASSWORD" , "PGPASSFILE" , "MYSQL_PWD" , "GIT_ASKPASS" , "NETRC" }
50+ )
51+ _CREDENTIAL_ENV_VALUE = (
52+ re .compile (r"(?i)\bbearer\s+\S+" ),
53+ re .compile (r"(?i)\b(?:hf_|sk-|github_pat_|gh[pousr]_)[A-Za-z0-9_-]{8,}\b" ),
54+ re .compile (r"\b(?:AKIA|ASIA)[0-9A-Z]{16}\b" ),
55+ re .compile (r"-----BEGIN [A-Z ]*PRIVATE KEY-----" ),
56+ re .compile (r"(?i)\b[a-z][a-z0-9+.-]*://[^/\s@]*:[^/\s@]+@" ),
57+ re .compile (
58+ r"(?i)\b[a-z][a-z0-9+.-]*://[^\s#]*[?&]"
59+ r"(?:auth(?:orization)?|credentials?|password|passwd|token|"
60+ r"api[_-]?key|access[_-]?key|key|sig(?:nature)?|awsaccesskeyid|"
61+ r"googleaccessid|x[-_]amz[-_](?:credential|security[-_]token|signature)|"
62+ r"x[-_]goog[-_](?:credential|signature))=[^&#\s]+"
63+ ),
64+ )
4265_HOP_BY_HOP_HEADERS = {
4366 "connection" ,
4467 "content-encoding" ,
5679_POOL_LOCK = threading .Lock ()
5780
5881
82+ def credential_environment_names (env_vars : dict [str , str ] | None ) -> list [str ]:
83+ """Return names whose name or value appears to carry credentials."""
84+ flagged : list [str ] = []
85+ for raw_name , raw_value in (env_vars or {}).items ():
86+ name = str (raw_name )
87+ value = str (raw_value )
88+ if (
89+ name .upper () in _CREDENTIAL_ENV_ALIASES
90+ or _CREDENTIAL_ENV_NAME .search (name )
91+ or any (pattern .search (value ) for pattern in _CREDENTIAL_ENV_VALUE )
92+ ):
93+ flagged .append (name )
94+ return sorted (flagged )
95+
96+
5997class _NoRedirectWebSocketConnect (ws_connect ):
6098 def process_redirect (self , exc : Exception ) -> Exception | str :
6199 return exc
@@ -300,6 +338,10 @@ def __init__(
300338 self ._secrets = dict (secrets ) if secrets is not None else None
301339 self .flavor = flavor
302340 self ._mode = mode
341+ self ._official_certification = False
342+ self ._official_image : str | None = None
343+ self ._official_flavor : str | None = None
344+ self ._official_env_vars : dict [str , str ] | None = None
303345 self ._sandbox : Any = None
304346 self ._server_process : Any = None
305347 self ._proxy : _LocalAuthProxy | None = None
@@ -326,6 +368,34 @@ def isolation_mode(self) -> Literal["pooled", "dedicated", "unknown"]:
326368 return "unknown"
327369 return "dedicated" if host_id is None else "pooled"
328370
371+ def _lock_for_official_certification (self ) -> None :
372+ """Freeze the settings that cross the official runner trust boundary."""
373+ if self ._sandbox is not None :
374+ raise RuntimeError (
375+ "Official certification must validate and lock the provider "
376+ "before a Hugging Face sandbox is started."
377+ )
378+ self ._official_certification = True
379+ self ._official_image = self .image
380+ self ._official_flavor = self .flavor
381+ self ._official_env_vars = (
382+ dict (self ._env_vars ) if self ._env_vars is not None else None
383+ )
384+
385+ def _verify_official_runtime_isolation (self ) -> None :
386+ try :
387+ host_id = self ._sandbox .host_id
388+ except (AttributeError , RuntimeError ) as exc :
389+ raise RuntimeError (
390+ "Official certification could not verify dedicated isolation "
391+ "for the created Hugging Face sandbox."
392+ ) from exc
393+ if host_id is not None :
394+ raise RuntimeError (
395+ "Official certification requires a dedicated Hugging Face sandbox; "
396+ "the created sandbox is attached to a shared host."
397+ )
398+
329399 def _create_sandbox (self , * , image : str , env_vars : dict [str , str ] | None ) -> Any :
330400 if self .mode == "dedicated" :
331401 Sandbox = _get_sandbox_cls ()
@@ -360,12 +430,37 @@ def start_container(
360430 f"HFSandboxProvider only supports port { _DEFAULT_PORT } (got { port } )."
361431 )
362432
433+ if self ._official_certification :
434+ if (
435+ self .image != self ._official_image
436+ or self .flavor != self ._official_flavor
437+ or self .mode != "dedicated"
438+ or self ._env_vars != self ._official_env_vars
439+ or (image is not None and image != self ._official_image )
440+ ):
441+ raise RuntimeError (
442+ "Official certification does not allow execution-setting changes "
443+ "after the provider trust check."
444+ )
445+ if env_vars is not None :
446+ raise RuntimeError (
447+ "Official certification does not allow environment overrides "
448+ "after the provider trust check."
449+ )
450+ credential_names = credential_environment_names (self ._env_vars )
451+ if credential_names or self ._secrets :
452+ raise RuntimeError (
453+ "Official subject sandboxes cannot receive coordinator credentials."
454+ )
455+
363456 effective_image = self .image if image is None else image
364457 effective_env = self ._env_vars if env_vars is None else env_vars
365458 self ._sandbox = self ._create_sandbox (
366459 image = effective_image , env_vars = effective_env
367460 )
368461 try :
462+ if self ._official_certification :
463+ self ._verify_official_runtime_isolation ()
369464 if not hasattr (self ._sandbox , "proxy_url_for" ) or not hasattr (
370465 self ._sandbox , "proxy_headers"
371466 ):
0 commit comments