+
    lHàj 7  ã                  ó  € R t ^ RIHt ^ RIt^ RIt^ RIt]P                  ! R4      tRtRt	Rt
RR0t]! 0 R m4      tR	 R
 ltR R ltR!R R lltR R lt]! R4      tR R ltR R ltR R ltR R ltR R ltR R ltR R ltR# )"a  Egress-proxy (iron-proxy) plumbing for the Docker backend.

Builds the mount/env/host args that route a sandbox through the host-side
credential firewall, and guards the three config surfaces (docker_forward_env,
docker_env, docker_extra_args) that could otherwise weaken or bypass it.
)ÚannotationsNztools.environments.dockerzhermes-egressz#/etc/ssl/certs/hermes-egress-ca.crtÚ"_HERMES_EGRESS_NODE_OPTIONS_APPENDú--use-openssl-caz--use-bundled-cac               ó   € V ^8„  d   QhRR/# )é   Úreturnz+tuple[list[str], dict[str, str], list[str]]© )Úformats   "ÚE/home/ubuntu/.hermes/hermes-agent/tools/environments/docker_egress.pyÚ__annotate__r      s   € ÷ T3ñ T3Ð'Rñ T3ó    c                 óŒ  a€  ^ RI Hp  ^ RIHp T ! 4       P                  R4      ;'       g    / pTP                  R4      '       g   . / . 3# TP                  4       p\        TP                  RR4      4      oR	 T3R
 llpTP                  '       g	   T! R4      # TP                  '       d   TP                  '       g   T! RTP                   R24      # TP                  e!   TP                  P                  4       '       g   T! RTP                   R24      # TP!                  4       pT'       g	   T! R4      # RTP                   R\"         R2.pRTP                   2pRTP                  ^,            2p	RTRTRT	RT	RRRRR\"        R\"        R\"        R\"        R R!\$        R"/p
T Fc  pTP&                  Y«P(                  &   TP&                  T
R#TP(                   2&   \+        TR$R'4      ;'       g    R' F  pTP&                  Y¬&   K  	  Ke  	  R%R&.pYzT3#   \         d&   p\
        P                  RT4       . / . 3u Rp?# Rp?ii ; i)(u”  ``(volume_args, env_overrides, host_args)`` for routing through iron-proxy; all empty
when the proxy is disabled/unconfigured/not running. Under ``proxy.enforce_on_docker``
(default) any half-configured state raises so the sandbox refuses to start unprotected;
otherwise it warns and continues. Only ImportError is swallowed â€” a broken config must
fail visibly rather than silently disable enforcement.©Úload_config©Ú
iron_proxyz%Egress proxy plumbing unavailable: %sNÚproxyÚenabledÚenforce_on_dockerTc               ó   € V ^8„  d   QhRR/# )r   ÚmsgÚstrr   )r	   s   "r
   r   Ú3_egress_proxy_args_for_docker.<locals>.__annotate__1   s   € ÷ ñ �sñ r   c                ó`   <€ S'       d   \        V 4      h\        P                  R V 4       . / . 3# )u:   %s â€” continuing without proxy (enforce_on_docker=false).©ÚRuntimeErrorÚloggerÚwarning)r   Úenforces   &€r
   Ú	_degradedÚ0_egress_proxy_args_for_docker.<locals>._degraded1   s-   ø€ ßÜ˜sÓ#Ð#Ü�‰ÐSÐUXÔYØ�B˜ˆ|Ðr   zvproxy.enabled is true but iron-proxy is not configured. Run `hermes egress setup` to mint tokens and write proxy.yaml.z.iron-proxy is enabled but not running on port z&. Start it with `hermes egress start`.z!iron-proxy CA cert vanished from z0. Re-run `hermes egress setup` to regenerate it.z�iron-proxy is configured but mappings.json is empty or corrupt.  Re-run `hermes egress setup` to mint provider tokens before starting a sandbox.z-vÚ:z:rozhttp://host.docker.internal:ÚHTTPS_PROXYÚhttps_proxyÚ
HTTP_PROXYÚ
http_proxyÚNO_PROXYz127.0.0.1,localhost,::1Úno_proxyÚREQUESTS_CA_BUNDLEÚSSL_CERT_FILEÚCURL_CA_BUNDLEÚNODE_EXTRA_CA_CERTSÚHERMES_EGRESS_PROXYÚ1r   ÚHERMES_PROXY_TOKEN_Úalias_env_namesz
--add-hostz!host.docker.internal:host-gatewayr   )Úhermes_cli.configr   Úagent.proxy_sourcesr   ÚImportErrorr   ÚdebugÚgetÚ
get_statusÚboolÚ
configuredÚpidÚ	listeningÚtunnel_portÚca_cert_pathÚexistsÚload_mappingsÚ_CONTAINER_CAÚ_NODE_OPTIONS_SENTINELÚproxy_tokenÚreal_env_nameÚgetattr)r   ÚipÚexcÚ	proxy_cfgÚstatusr   ÚmappingsÚvolume_argsÚ	proxy_urlÚplain_http_urlÚenv_overridesÚmÚaliasÚ	host_argsr   s                 @r
   Ú_egress_proxy_args_for_dockerrO      s}  ø€ ðÝ1Ý8ñ
 “×!Ñ! 'Ó*×0Ð0¨b€IØ�=‰=˜×#Ò#Ø�B˜ˆ|Ðà�]‰]‹_€FÜ�9—=‘=Ð!4°dÓ;Ó<€G÷ð ð ××ÐÙðMóNð 	Nð �J�JˆJ˜6×+×+Ð+ÙØ<¸V×=OÑ=OÐ<Pð Q3ð 3ó4ð 	4ð ×ÑÒ"¨&×*=Ñ*=×*DÑ*D×*FÒ*Fñ Ø/°×0CÑ0CÐ/Dð E=ð =ó>ð 	>ð
 ×ÑÓ!€HßÙð0ó1ð 	1ð
 ˜F×/Ñ/Ð0°´-°ÀÐDÐE€Kð /¨v×/AÑ/AÐ.BÐC€IØ3°F×4FÑ4FÈÕ4JÐ3KÐL€Nð 	�yØ�yØ�nØ�nàÐ-ØÐ-ð
 	œmØœØœ-Øœ}Ø˜sÜÐ 2ð%%4€Mó, ˆØ)*¯©ˆ—o‘oÑ&ØABÇÁˆÐ+¨A¯O©OÐ+<Ð=Ñ>Ü˜QÐ 1°2Ó6×<Ð<¸"Ò<ˆEØ#$§=¡=ˆMÓ ó =ñ ð ÐBÐC€IØ¨	Ð2Ð2øôW ô Ü�‰Ð<¸cÔBØ�B˜ˆ|Õûðús   ƒH ÈIÈH>È8IÈ>Ic               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rH   ú	list[str]rK   údict[str, str]rN   r   r   r   )r	   s   "r
   r   r   t   s2   € ÷ Dñ DØðDØ+9ðDØFOðDØTWñDr   c                óè   € V '       g   V'       g   V'       g   R# \         P                  ! RV RVRV/RR	R7      p\        P                  ! VP	                  R4      4      P                  4       R,          # )
z@Stable Docker-label value for the egress posture of a container.ÚoffrH   rK   rN   T)Ú	sort_keysÚ
separatorszutf-8:Né   N)Ú,r!   )ÚjsonÚdumpsÚhashlibÚsha256ÚencodeÚ	hexdigest)rH   rK   rN   Úpayloads   &&& r
   Ú_egress_reuse_fingerprintr`   t   sZ   € ÷ Ÿ=¯IÙÜ�jŠjØ	˜ _°mÀ[ÐR[Ð\Ø :ô/€Gô �>Š>˜'Ÿ.™.¨Ó1Ó2×<Ñ<Ó>¸sÕCÐCr   c               ó    € V ^8„  d   QhRRRR/# )r   Údefaultr6   r   r   )r	   s   "r
   r   r      s   € ÷ 	ñ 	 tð 	°tñ 	r   c                ó
  €  ^ RI Hp \        V! 4       P                  R4      ;'       g    / P                  RV 4      4      #   \        \
        3 d    T u # \         d#   p\        P                  RT4       T u Rp?# Rp?ii ; i)zIRead proxy.enforce_on_docker; any config failure fails safe to *default*.r   r   r   z:Could not read proxy config for egress collision check: %sN)	r0   r   r6   r4   r2   ÚOSErrorÚ	Exceptionr   r   )rb   r   rD   s   &  r
   Ú_egress_enforce_on_dockerrf      sp   € ðÝ1Ü‘[“]×&Ñ& wÓ/×5Ð5°2×:Ñ:Ð;NÐPWÓXÓYÐYøÜœÐ!ô ØŠÜô Ü�‰ÐSÐUXÔYØ�ûðús.   ‚'A ªA ÁBÁBÁBÁ A=Á7BÁ=Bc               ó    € V ^8„  d   QhRRRR/# )r   rK   rR   r   úset[str]r   )r	   s   "r
   r   r   ‹   s   € ÷ Kñ K¨nð KÀñ Kr   c                óP   € \        \        4      R0,          \        V 4      ,          # )ag  Env names that would weaken or bypass enforced egress if overridden.

Every name the egress layer writes is critical: mapped tokens land under arbitrary
``real_env_name``/``alias_env_names`` entries from mappings.json, so a suffix
heuristic would silently unprotect any mapped credential not ending in
``_API_KEY``/``_TOKEN`` (e.g. ``AWS_SECRET_ACCESS_KEY``).ÚNODE_OPTIONS)ÚsetÚ_PROXY_CONTROL_ENV)rK   s   &r
   Ú_critical_egress_env_namesrm   ‹   s"   € ô Ô!Ó" nÐ%5Õ5¼¸MÓ8JÕJÐJr   ÚditPqc               ó    € V ^8„  d   QhRRRR/# )r   Úargr   r   ztuple[str, str | None] | Noner   )r	   s   "r
   r   r   š   s   € ÷ ñ ˜ð Ð!>ñ r   c                ó„  € V P                  R4      '       d4   V P                  R4      w  rpVR	9   d   VR,          V'       d   V3# R3# R# V P                  R4      '       g   R# \        V R,          4       FF  w  rEV\        9   d   K  VR8X  d-   W^,           R pVP	                  R4      pRT;'       g    R3u #  R# 	  R# )
zý``("env"|"env-file", inline_value)`` when ``arg`` spells a docker env flag
under pflag parsing, else ``None``. ``inline_value`` is the joined value
(``--env=N=v``, ``-eN=v``) or ``None`` when the flag consumes the next arg
(``-e``, ``--env``, ``-ite``).ú--Ú=:r   NNNÚ-:é   NNÚeÚenv)z--envú
--env-file)Ú
startswithÚ	partitionÚ	enumerateÚ_DOCKER_RUN_BOOL_SHORTHANDSÚremoveprefix)rp   ÚflagÚsepÚinlineÚposÚchÚrests   &      r
   Ú_env_flag_valuer„   š   s½   € ð
 ‡~�~�d×ÒØŸM™M¨#Ó.Ñˆ�6ØÐ*Ô*Ø˜•8§s˜VÐ4Ð4°Ð4Ð4ÙØ�>‰>˜#×ÒÙô ˜S �WÖ%‰ˆØÔ,Ô,ÙØ�Œ9Ø˜Q•w�x�=ˆDØ×$Ñ$ SÓ)ˆDØ˜$Ÿ,˜, $Ð&Ò&Úñ &ñ r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú
extra_argsrQ   Úcritical_namesrh   r   r   )r	   s   "r
   r   r   ´   s"   € ÷ #ñ #¨ið #Èð #ÐV_ñ #r   c                ó~  € V Uu0 uF  q"P                  4       kK  	  pp. p^ pV\        V 4      8  dô   W,          pVR8X  d   Mã\        V4      pVe›   Vw  r‰VR8X  d   VP                  R4       MmV	e   T	M'V^,           \        V 4      8  d   W^,           ,          MRp
V
P	                  R^4      ^ ,          pVP                  4       V9   d   VP                  V4       YYe   ^M^,          pKÉ  VP                  R4      ^ ,          R9   d   VP                  V4       V^,          pEK  \        \        V4      4      # u upi )zCReturn docker_extra_args entries that can override egress controls.rr   zenv-filerx   Ú rs   )z	--networkz--net)ÚupperÚlenr„   ÚappendÚsplitrz   Úsortedrk   )r†   r‡   ÚnÚcritical_foldedÚ
collisionsÚirp   ÚparsedÚkindÚinline_valueÚvalueÚnames   &&          r
   Ú_extra_args_egress_collisionsr˜   ´   s   € ñ
 +9Ó9©. Q—w‘w–y©.€OÐ9Ø€JØ	€AØ
Œc�*‹oÔ
Ø�mˆð �$Œ;ØÜ  Ó%ˆØÒØ!'ÑˆDØ�zÔ!Ø×!Ñ! ,Õ/à(4Ò(@™Ø)*¨Q­´°Z³Ô)@�J 1�uÖ%Àbð à—{‘{ 3¨Ó*¨1Õ-�Ø—:‘:“< ?Ô2Ø×%Ñ% dÔ+ØÒ.‘°AÕ5ˆAÙØ�=‰=˜Ó˜aÕ Ð$:Ô:Ø×Ñ˜cÔ"Ø	ˆQ�‹Ü”#�j“/Ó"Ð"ùò5 :s   …D:c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r   r   r   r6   ÚremedyÚconsequencer   ÚNoner   )r	   s   "r
   r   r   Ö   s0   € ÷ /ñ /˜#ð /¨4ð /¸ð /È3ð /ÐSWñ /r   c               ó†   € T  RV'       d   RMR R2p V'       d   \        V  RV 24      h\        P                  RW4       R# )zJFail loud under enforcement, otherwise warn and let the user's config win.z; enforce_on_docker is r   ÚdisabledÚ.z  z%s  %sNr   )r   r   rš   r›   s   &$$$r
   Ú_collision_guardr    Ö   sA   € àˆEÐ(·g©À:Ð(NÈaÐ
P€CßÜ˜c˜U " V HÐ-Ó.Ð.Ü
‡N�N�8˜SÖ.r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úforward_envrQ   Úcriticalrh   r   r6   r   rœ   r   )r	   s   "r
   r   r   Þ   s0   € ÷ [ñ [¨ið [À8ð [ÐVZð [Ð_cñ [r   c                ó²   a€ V Uu0 uF  q3P                  4       kK  	  upo\        V3R  lV  4       4      pV'       d   \        RV 2VRRR7       R# R# u upi )c              3  óT   <"  € T F  qP                  4       S9   g   K  Vx € K  	  R # 5i©N)rŠ   )Ú.0Úkr�   s   & €r
   Ú	<genexpr>Ú/check_forward_env_collisions.<locals>.<genexpr>ã   s   øé € ÐO¡;˜a·'±'³)¸Ñ2NŸš£;ùs   ƒ(ž
(z@docker_forward_env would inject real egress-protected variables zgRemove these names from docker_forward_env or disable enforce_on_docker to opt out of egress isolation.z?Explicit docker_forward_env values will override egress tokens.©r   rš   r›   N)rŠ   rŽ   r    )r¢   r£   r   r¨   r‘   r�   s   &&&  @r
   Úcheck_forward_env_collisionsr¬   Þ   sX   ø€ ñ +3Ó3©( Q—w‘w–y©(Ñ3€OÜÔO¡;ÓOÓO€JßÜØNÈzÈlÐ[Øð5àY÷	[ñ ùò 4s   †Ac               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úuser_envrR   Ú
egress_envr   r6   r   rœ   r   )r	   s   "r
   r   r   í   s*   € ÷ .ñ .¨.ð .Ànð .Ð_cð .Ðhlñ .r   c                ó<  a aaa€ \        4       o ^ RIHp VP                  4        Uu0 uF  qDP                  kK  	  upoR VVV 3R llo\        V3R l\        S,           4       4      pV'       d   \        RV 2VRRR7       R	# R	# u upi   \
         d     L[i ; i)
z°Reject docker_env overrides of proxy-control vars or real provider keys (read from the
live token mappings; for those ANY override collides since a real key bypasses the swap).r   c               ó    € V ^8„  d   QhRRRR/# )r   r¨   r   r   r6   r   )r	   s   "r
   r   Ú1check_docker_env_collisions.<locals>.__annotate__÷   s   € ÷ @ñ @�Sð @˜Tñ @r   c                ó¤   <€ V S9  d   R # V S9   d!   V S9  ;'       g    SV ,          SV ,          8g  # V S9   ;'       d    SV ,          SV ,          8g  # )Fr   )r¨   r¯   Úprovider_keysr®   s   &€€€r
   Ú	_collidesÚ.check_docker_env_collisions.<locals>._collides÷   sU   ø€ Ø�HÔÙØ�ÔØ˜JÑ&×FÐF¨(°1­+¸ÀA½Ñ*FÐFØ�J‰×?Ð? 8¨A¥;°*¸Qµ-Ñ#?Ð?r   c              3  óH   <"  € T F  pS! V4      '       g   K  Vx € K  	  R # 5ir¦   r   )r§   r¨   rµ   s   & €r
   r©   Ú.check_docker_env_collisions.<locals>.<genexpr>þ   s   øé € ÐXÑ$F˜aÉ9ÐUVÏ<ŸšÓ$Fùs   ƒ"˜
"z;docker_env in config.yaml overrides egress-proxy variables z^Remove these keys from docker_env or disable enforce_on_docker to opt out of egress isolation.zTFalling back to docker_env values; sandbox traffic will NOT route through the proxy.r«   N)	rk   r1   r   r=   rA   re   rŽ   rl   r    )r®   r¯   r   rC   rL   r‘   rµ   r´   s   ff&   @@r
   Úcheck_docker_env_collisionsr¹   í   s˜   û€ ô "›e€MðÝ8Ø24×2BÑ2BÔ2DÓEÑ2D¨QŸœÑ2DÑEˆ÷@ò @ô ÔXÔ$6¸Ö$FÓXÓX€JßÜØIÈ*ÈÐVØð*ð-÷	.ñ ùò FøÜô Ùðús!   �B ¨B¼B ÂB ÂBÂBc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r†   rQ   r£   rh   r   r6   r   rœ   r   )r	   s   "r
   r   r   	  s0   € ÷ Jñ J¨Ið JÀð JÐTXð JÐ]añ Jr   c                óT   € \        W4      pV'       d   \        R V 2VRRR7       R# R# )z7docker_extra_args would override egress-proxy controls zNRemove these args or disable enforce_on_docker to opt out of egress isolation.z.Extra Docker args may bypass egress isolation.r«   N)r˜   r    )r†   r£   r   r‘   s   &&& r
   Úcheck_extra_args_collisionsr¼   	  s0   € Ü.¨zÓD€JßÜØEÀjÀ\ÐRØØcØH÷		Jñ r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r®   rR   r¯   r   r6   r   r   )r	   s   "r
   r   r     s*   € ÷ ñ ˜~ð ¸>ð ÐTXð Ð]kñ r   c                ó„  € V'       d   V'       d   / V CVCM/ VCV CpVP                  \        R4      pV'       dü   VP                  4       pVP                  RR4      P	                  4       pV\
        9   dg   V Uu. uF  qw\
        9   g   K  Wu8w  g   K  VNK  	  ppV'       d   \        P                  RW…4       V Uu. uF  qw\
        9  g	   Wu8X  g   K  VNK  	  ppWV9  d   VP                  V4       RP                  V4      P                  4       VR&   VR,          '       g   VP                  RR4       V# u upi u upi )zÿMerge docker_env with egress overrides (egress wins under enforcement, docker_env
otherwise) and resolve the NODE_OPTIONS sentinel: the flag is APPENDED to the operator's
NODE_OPTIONS after stripping conflicting CA-mode flags so it wins deterministically.Nrj   r‰   zOverriding conflicting NODE_OPTIONS CA-mode flag(s) %s with egress-required %s to keep Node routed through the egress CA store.Ú )
Úpopr?   Ústripr4   r�   Ú_CA_MODE_FLAGSr   r   rŒ   Újoin)	r®   r¯   r   ÚmergedÚ
raw_appendÚappend_tokenÚtokensÚtÚdroppeds	   &&&      r
   Úmerge_egress_envrÊ     s  € ÷ ,3·zÐ'�Ð'˜JÑ'ÐGaÈ*ÐGaÐX`ÐGa€Fà—‘Ô2°DÓ9€JßØ!×'Ñ'Ó)ˆØ—‘˜N¨BÓ/×5Ñ5Ó7ˆØœ>Ô)Ù"(ÓV¡&˜Q´Ñ,?”qÀAÑDU—q�q¡&ˆGÐVßÜ—‘ð'à(/ô?ñ "(ÓX¡˜A´NÔ+BÀaÑFW—a�a¡ˆFÐXØÔ%Ø�M‰M˜,Ô'Ø!$§¡¨&Ó!1×!7Ñ!7Ó!9ˆˆ~ÑØ�n×%Ô%Ø�J‰J�~ tÔ,Ø€Mùò Wùò Ys   Á:D8ÂD8ÂD8Â=D=ÃD=>
   r&   r'   r$   r%   r"   r#   r)   r*   r(   r+   )T)Ú__doc__Ú
__future__r   r[   rY   ÚloggingÚ	getLoggerr   Ú_EGRESS_LABEL_KEYr>   r?   rÂ   Ú	frozensetrl   rO   r`   rf   rm   r|   r„   r˜   r    r¬   r¹   r¼   rÊ   r   r   r
   Ú<module>rÑ      s¢   ðñõ #ã Û Û à	×	Ò	Ð6Ó	7€à#Ð Ø5€Ø=Ð Ø$Ð&8Ð9€ñ ò  ó Ð õT3õnD÷	õKñ (¨Ó0Ð õõ4#õD/õ[õ.õ8J÷r   