+
    lHàju%  ã                  ó  a € 0 t $ R t^ RIHt ^ RIt^ RIHt ^ RIHtH	t	 ]P                  ! ]4      t]! 4       tR]R&   R R lt/ tR	]R
&   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 R lltR R ltR R ltR# )a–  Environment variable passthrough registry: the session-scoped allowlist of vars a
skill's ``required_environment_variables`` (registered by ``skill_view``) or
``terminal.env_passthrough`` in config.yaml may forward into sandboxed children
(execute_code, terminal), which strip secrets by default. Under profile multiplexing,
forwarded values resolve through the profile's secret scope, not the process env.)ÚannotationsN)ÚIterable)Úcfg_getÚread_raw_configúset[str]Ú_allowed_env_varsc               ó   € V ^8„  d   QhRR/# )é   Úreturnr   © )Úformats   "Ú:/home/ubuntu/.hermes/hermes-agent/tools/env_passthrough.pyÚ__annotate__r   #   s   € ÷ ñ �hñ ó    c                 ó   € \         # )z1Get the process-wide skill passthrough allowlist.)r   r   r   r   Ú_get_allowedr   #   s   € äÐr   zdict[str, frozenset[str]]Ú_config_passthroughc               ó    € V ^8„  d   QhRRRR/# )r	   ÚnameÚstrr
   Úboolr   )r   s   "r   r   r   .   s   € ÷ Rñ R¨ð R°ñ Rr   c                ó¢   €  ^ RI HpHp T! T 4      ;'       g	    T! T 4      #   \         d"   p\        P                  RY4        Rp?R# Rp?ii ; i)uï  True if ``name`` is a Hermes-managed provider credential per
``_HERMES_PROVIDER_ENV_BLOCKLIST`` or a dynamic Hermes-internal secret
(AUXILIARY_*_API_KEY / _BASE_URL, GATEWAY_RELAY_*). Skill-declared
``required_environment_variables`` must not override this â€” that was the
GHSA-rhgp-j443-p4rf bypass (a skill registered ``OPENAI_API_KEY`` and received it
in the ``execute_code`` child); non-Hermes keys (TENOR_API_KEY, â€¦) stay
registerable. Fails closed when the blocklist cannot be imported.)Ú_is_hermes_internal_secretÚ_is_provider_env_blocklistedz}env passthrough: provider credential blocklist import failed; failing closed and refusing passthrough registration for %r: %sNT)Ú#tools.environments.local_env_policyr   r   Ú	ExceptionÚloggerÚwarning)r   r   r   Úes   &   r   Ú_is_hermes_provider_credentialr   .   sU   € ð÷	Fñ & dÓ+×QÐQÑ/KÈDÓ/QÐQøô ô Ü�‰ðNØOSô	Xõ ûð	ús   ‚" ¢A­A	Á	Ac               ó    € V ^8„  d   QhRRRR/# )r	   Ú	var_namesúIterable[str]r
   ÚNoner   )r   s   "r   r   r   D   s   € ÷ =ñ =¨ð =¸$ñ =r   c                ó˜   € \        R V  4       R4       F2  p\        4       P                  V4       \        P	                  RV4       K4  	  R# )u.  Register env var names as allowed in sandboxed environments (typically a
skill's ``required_environment_variables``). Hermes-managed provider credentials
are rejected (GHSA-rhgp-j443-p4rf) â€” such skills should use the main-process tools
(web_search, web_extract, â€¦); third-party keys pass normally.c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5i©N)Ústrip)Ú.0Úns   & r   Ú	<genexpr>Ú+register_env_passthrough.<locals>.<genexpr>I   s   é € Ð8©i¨Ÿ7™7Ÿ9˜9«iùs   ‚zÓenv passthrough: refusing to register Hermes provider credential %r (blocked by _HERMES_PROVIDER_ENV_BLOCKLIST). Skills must not override the execute_code sandbox's credential scrubbing; see GHSA-rhgp-j443-p4rf.zenv passthrough: registered %sN)Ú	_acceptedr   Úaddr   Údebug)r!   r   s   & r   Úregister_env_passthroughr/   D   sA   € ô
 Ñ8©iÓ8ð	9öˆô 	‹×Ñ˜4Ô Ü�‰Ð5°tÖ<ór   c               ó   € V ^8„  d   QhRR/# )r	   Úrefusal_msgr   r   )r   s   "r   r   r   S   s   € ÷ 	ñ 	 #ñ 	r   c              #  óŒ   "  € V  F9  pV'       g   K  \        V4      '       d   \        P                  W4       K5  Vx € K;  	  R# 5i)z~Yield non-empty *names* that are not Hermes provider credentials; refused
names are logged with *refusal_msg* (``%r`` = name).N)r   r   r   )Únamesr1   r   s   && r   r,   r,   S   s6   é € ó ˆßÙÜ)¨$×/Ò/Ü�N‰N˜;Ô-ÙØŒ
ó ùs   ‚AAc               ó   € V ^8„  d   QhRR/# ©r	   r
   zfrozenset[str]r   )r   s   "r   r   r   _   s   € ÷ )ñ ) .ñ )r   c                 óØ  € ^ RI Hp   V ! 4       p\        P                  V4      pVe   V# \        4       p \        \        4       RR4      p\        V\        4      '       d   TMR	pVP                  \        R V 4       R4      4       \!        V4      \        V&   \        V,          #   \        \        3 d    Rp L«i ; i  \         d!   p\        P                  RT4        Rp?L^Rp?ii ; i)
zÖLoad ``tools.env_passthrough`` from config.yaml (cached). Same credential
filter as register_env_passthrough: operator config must not tunnel provider
credentials into sandbox children either (GHSA-rhgp-j443-p4rf).)Úhermes_home_keyÚ NÚterminalÚenv_passthroughc              3  ór   "  € T F-  p\        V\        4      '       g   K  VP                  4       x € K/  	  R # 5ir&   )Ú
isinstancer   r'   )r(   Úis   & r   r*   Ú+_load_config_passthrough.<locals>.<genexpr>q   s#   é € Ð P±E¨q¼ZÈÌ3×=O¤ §¡§ ³Eùs   ‚7Ÿ7zôenv passthrough: refusing to register Hermes provider credential %r from config.yaml (blocked by _HERMES_PROVIDER_ENV_BLOCKLIST). Operator configuration must not override the execute_code sandbox's credential scrubbing; see GHSA-rhgp-j443-p4rf.z4Could not read tools.env_passthrough from config: %sr   )Úhermes_constantsr7   ÚRuntimeErrorÚOSErrorr   ÚgetÚsetr   r   r<   ÚlistÚupdater,   r   r   r.   Ú	frozenset)r7   Úhome_keyÚcachedÚresultÚpassthroughÚitemsr   s          r   Ú_load_config_passthroughrL   _   sà   € õ 1ðÙ"Ó$ˆô !×$Ñ$ XÓ.€FØÒØˆÜ“u€FðPÜœoÓ/°Ð=NÓOˆÜ)¨+´t×<Ò<‘À"ˆØ�‰”iÑ P±EÓ Pð#óô 	ô %.¨fÓ$5Ô˜Ñ!Ü˜xÕ(Ð(øô+ œ'Ð"ô àŠðûô$ ô PÜ�‰ÐKÈQ×OÑOûðPús)   ˆB% µAB> Â%B;Â:B;Â>C)Ã	C$Ã$C)c               ó    € V ^8„  d   QhRRRR/# )r	   Úvar_namer   r
   r   r   )r   s   "r   r   r      s   € ÷ >ñ > ð >¨ñ >r   c                óv   € V \        4       9   ;'       g    V \        4       9   ;'       d    \        V 4      '       * # )aX  True if *var_name* was registered by a skill or listed in config and is not a
Hermes-managed credential NOW. Ownership changes after acceptance (a platform plugin
registered later declares the name in its ``required_env`` or manifest), so the refusal applied at registration
is re-applied here, where every child builder consumes the allowlist.)r   rL   r   )rN   s   &r   Úis_env_passthroughrP      s9   € ð
 œ›Ñ'×QÐQ¨8Ô7OÓ7QÑ+Q÷ =ð =Ü2°8Ó<Ô<ð>r   c               ó   € V ^8„  d   QhRR/# r5   r   )r   s   "r   r   r   ˆ   s   € ÷ Bñ B˜^ñ Br   c                 óf   € \        R \        \        4       4      \        4       ,           4       4      # )z™Return the union of skill-registered and config-based passthrough vars, minus names
that have become Hermes-managed credentials since they were accepted.c              3  óL   "  € T F  p\        V4      '       d   K  Vx € K  	  R # 5ir&   )r   )r(   r   s   & r   r*   Ú&get_all_passthrough.<locals>.<genexpr>‹   s"   é € ð BÑ&\˜dÜ:¸4×@÷ ’TÓ&\ùs   ‚$š
$)rF   r   rL   r   r   r   Úget_all_passthroughrU   ˆ   s1   € ô ñ B¤i´³Ó&?ÔBZÓB\Ö&\ó Bó Bð Br   c               ó$   € V ^8„  d   QhRRRRRR/# )r	   r   r   Úfallbackz
str | Noner
   r   )r   s   "r   r   r   �   s&   € ÷ Dñ D Cð D°:ð DÈñ Dr   c                ó²   € ^ RI HpHpHpHp V! V 4      '       d   Ve   V# V! 4       pV! 4       f   V'       d	   V! V 4      # T# T! Y'       d   R4      # T4      # )aç  Resolve an allowlisted variable without crossing profile boundaries. ``fallback``
is what the caller would have forwarded before secret scopes existed (a snapshot of
``os.environ`` / the profile ``.env``). An active multiplex scope is authoritative:
a missing key returns ``None``, never the process-global env, and an unscoped read
raises the fail-closed ``UnscopedSecretError``. Outside multiplexing an installed
scope keeps overlay semantics and an unscoped caller keeps its fallback.)Ú_is_global_envÚcurrent_secret_scopeÚ
get_secretÚis_multiplex_activeN)Úagent.secret_scoperY   rZ   r[   r\   )r   rW   rY   rZ   r[   r\   Úmultiplex_actives   &&     r   Úresolve_passthrough_valuer_   �   sa   € ÷Oó Oñ �d×Ò Ò 4ØˆÙ*Ó,ÐÙÓÒ%ß#3‰z˜$ÓÐA¸ÐAÙ�dÖ$4˜DÓCÐC¸(ÓCÐCr   c               ó    € V ^8„  d   QhRRRR/# )r	   Úpresentr"   r
   zdict[str, str]r   )r   s   "r   r   r   ¢   s   € ÷ ñ ¨-ð ¸Nñ r   c                óÖ   € ^ RI HpHp V! 4       pV'       g   / # \        V 4      p / p\	        4        F4  pWP9   g   V! V4      '       d   K  VP                  V4      pVf   K0  WdV&   K6  	  V# )uI  Declared passthrough names the bound profile secret scope supplies but the env being
filtered (*present*) lacks. A routed profile's ``.env`` and hydrated sources never enter
``os.environ`` (``load_hermes_dotenv`` skips the process-global load for a routed home), so a
name-by-name filter over the process env can only forward a declared name the LAUNCH profile
also happens to define â€” the served profile's own value has no way in (#114209). Reads the
bound scope alone: never ``os.environ``, never another profile. Empty without a scope, so
single-profile spawns are byte-identical.)rY   rZ   )r]   rY   rZ   rC   rU   rB   )ra   rY   rZ   ÚscopeÚ	additionsr   Úvalues   &      r   Úscoped_passthrough_additionsrf   ¢   sg   € ÷ HÙ Ó"€EßØˆ	Ü�'‹l€GØ "€IÜ#Ö%ˆØŒ?™n¨T×2Ò2ÙØ—	‘	˜$“ˆØÔØ#�d‹Oñ &ð Ðr   c               ó   € V ^8„  d   QhRR/# )r	   r
   r#   r   )r   s   "r   r   r   ¹   s   € ÷ ñ ˜tñ r   c                 ó6   € \        4       P                  4        R# )z·Reset the skill-registered allowlist (e.g. on session reset).

Clears the process-wide set; a later ``skill_view`` re-registers its
vars on demand, so recovery is a single skill load.N)r   Úclearr   r   r   Úclear_env_passthroughrj   ¹   s   € ô
 ƒN×ÑÖr   r&   )Ú__conditional_annotations__Ú__doc__Ú
__future__r   ÚloggingÚtypingr   Úhermes_cli.configr   r   Ú	getLoggerÚ__name__r   rC   r   Ú__annotations__r   r   r   r/   r,   rL   rP   rU   r_   rf   rj   )rk   s   @r   Ú<module>rt      s}   øðôUõ #ã Ý ß 6à	×	Ò	˜8Ó	$€ñ& "›eÐ �8Ó #õð 24Ð Ð.Ó 3õRõ,=õ	õ)õ@>õB÷Dõ&÷.r   