+
    „WÝjÃ  ã                  ó  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ]P                  ! R4      tRs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 R ltRRRR/R R lltRRRRRR/R R lltR# )a(  Startup security posture audit (warn-on-load, never blocks).

Surfaces dangerous host / deployment posture at process start. Checks are advisory and
independently fail-safe: they return human-readable strings, any internal error yields no finding,
and nothing here ever raises or blocks startup.
)ÚannotationsN)ÚPath)ÚOptionalzhermes.security_auditFc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚbool© )Úformats   "ÚUC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\security_audit_startup.pyÚ__annotate__r      s   € ÷ ñ �$ñ ó    c                 ó¨   € \        \        RR4      ;'       g    \        \        RR4      p  V RJ;'       d    V ! 4       ^ 8H  #   \         d     R# i ; i)zCTrue when the process runs as POSIX uid 0. Always False on Windows.ÚgeteuidNÚgetuidF)ÚgetattrÚosÚ	Exception)r   s    r   Ú_is_rootr      sQ   € ä”R˜ DÓ)×HÐH¬W´R¸À4Ó-H€FðØ˜TÐ!×3Ð3¡f£h°!¡mÐ3øÜô Úðús   ¬
A ·
A ÁAÁAc               ó   € V ^8„  d   QhRR/# ©r   r   úOptional[str]r
   )r   s   "r   r   r      s   € ÷ Rñ R˜-ñ Rr   c                 ó*   € \        4       '       g   R # R# )Nu	  Running as ROOT. The agent's terminal/file tools execute with full root privileges â€” a single prompt-injection or exposed endpoint is a full host compromise. Run Hermes as an unprivileged user (or in a sandboxed terminal backend / container with a non-root user).)r   r
   r   r   Ú_running_as_rootr      s   € Ü—z’zˆ4ð Rð	QðRr   c               ó   € V ^8„  d   QhRR/# )r   r   ú	list[str]r
   )r   s   "r   r   r   %   s   € ÷ ñ  ñ r   c                 ó„  € . p \        R4      .p VP                  \        \        R4      P                  R4      4      4       V FU  p VP                  RRR7      P                  4       pT P                  R \        \        P                  T4       4       4       KW  	  V #   \         d     Lji ; i  \         d     Kz  i ; i)z;Non-comment lines from sshd_config + its drop-in directory.z/etc/ssh/sshd_configz/etc/ssh/sshd_config.dz*.confz	utf-8-sigÚreplace©ÚencodingÚerrorsc              3  ój   "  € T F)  q'       g   K  VP                  R 4      '       d   K%  Vx € K+  	  R# 5i)Ú#N)Ú
startswith)Ú.0Úss   & r   Ú	<genexpr>Ú*_iter_sshd_config_lines.<locals>.<genexpr>2   s$   é € ÐYÑ 9˜1»Q”QÀqÇ|Á|ÐTW×GX—Q’QÓ 9ùs   ‚	3�3©
3)
r   ÚextendÚsortedÚglobr   Ú	read_textÚ
splitlinesÚmapÚstrÚstrip)ÚlinesÚpathsÚpÚ	raw_liness       r   Ú_iter_sshd_config_linesr5   %   sµ   € à€EÜÐ4Ó5Ð6€EðØ�‰”VœDÐ!9Ó:×?Ñ?ÀÓIÓJÔKó ˆð	ØŸ™¨[À˜ÓK×VÑVÓXˆIð 	�‰ÑY¤¤C§I¡I¨yÔ 9ÓYÖYñ ð €Løô ô Ùðûô
 ô 	Úð	ús#   �2B Á!B0ÂB-Â,B-Â0B?Â>B?c               ó   € V ^8„  d   QhRR/# r   r
   )r   s   "r   r   r   6   s   € ÷ qñ q Mñ qr   c                 óF  € \        4       p V '       g   R# \        \        P                  ! R4      P                  V 4       Uu. uF+  q'       g   K  VP                  ^4      P                  4       NK-  	  ppV'       d   VR,          R8X  d   R# V'       d   RMRpRV R2# u upi )	uª   Warn when sshd has password auth enabled â€” the classic brute-force surface, which pairs
badly with a root-capable agent box. None when there is no sshd config to read.
Nz#(?i)^PasswordAuthentication\s+(\w+)ÚnoÚ u$    (default â€” no explicit directive)z&SSH password authentication is ENABLEDz’. Password auth is brute-forceable and dangerous on an internet-facing box. Set 'PasswordAuthentication no' in sshd_config and use key-based auth.éÿÿÿÿ)r5   r.   ÚreÚcompileÚmatchÚgroupÚlower)r1   ÚmÚ
directivesÚ	qualifiers       r   Ú_ssh_password_auth_enabledrC   6   s’   € ô $Ó%€EßÙä.1´"·*²*Ð=cÓ2d×2jÑ2jÐlqÔ.rÓxÑ.r¨ÓvwÔ$�!—'‘'˜!“*×"Ñ"Ö$Ñ.r€JÐxß�j •n¨Ô,Ùß ‘Ð&L€IØ4°Y°Kð @pð pð qùò	 ys   Á	BÁ#Bc               ó   € V ^8„  d   QhRR/# r   r
   )r   s   "r   r   r   F   s   € ÷ 
Xñ 
X�tñ 
Xr   c                 ór  a € \         P                  P                  R4      '       d   R# \         P                  P	                  R4      '       d   R#  \        R4      P                  RRR7      o \        ;QJ d    T 3R	 lR
 4       F  '       g   K   R# 	  R# ! T 3R	 lR
 4       4      #   \         d     R# i ; i)z@Best-effort container detection (Docker / Podman / generic OCI).z/.dockerenvTÚHERMES_DESKTOP_CHILD_PIDFz/proc/1/cgroupúutf-8r   r   c              3  ó,   <"  € T F	  qS9   x € K  	  R # 5i©Nr
   )r%   ÚtokÚcgroups   & €r   r'   Ú _in_container.<locals>.<genexpr>P   s   øé € ÐWÑ(V �fŽ}Ó(Vùs   ƒ)ÚdockerÚ
containerdÚkubepodsÚlibpod)	r   ÚpathÚexistsÚenvironÚgetr   r,   r   Úany)rK   s   @r   Ú_in_containerrV   F   s‘   ø€ ä	‡w�w‡~�~�m×$Ò$ÙÜ	‡z�z‡~�~Ð0×1Ò1ÙðÜÐ&Ó'×1Ñ1¸7È9Ð1ÓUˆ÷ ‹3ÔWÑ(VÓW�3Œ3ÐWŠ3ÐWˆ3ÔWÑ(VÓWÓWÐWøô ô Úðús   ÁB' Â'B6Â5B6c               ó    € V ^8„  d   QhRRRR/# )r   rQ   r   r   r	   r
   )r   s   "r   r   r   S   s   € ÷ ;ñ ;˜4ð ; Dñ ;r   c                ó  €  V P                  4       p \        R4      P                  RRR7      P	                  4       pR T 4        Uu. uFj  p\        T4      ^8¼  g   K  \        T^,          4      T8X  g$   \        T^,          4      TP                  9   g   KO  \        T^,          4      T^,          3NKl  	  ppT'       g   R# \        TR R7      ^,          pTR	9  #   \         d    T p LÛi ; i  \         d     R# i ; iu upi )
z True if *path* sits on a persistent mount per /proc/mounts, i.e. the most specific
mountpoint at or above it is NOT the ephemeral container root overlay/tmpfs.
z/proc/mountsrG   r   r   Tc              3  ó@   "  € T F  qP                  4       x € K  	  R # 5irI   )Úsplit)r%   Úlines   & r   r'   Ú#_path_is_mounted.<locals>.<genexpr>b   s   é € Ð6©v t—j‘j—l�l«vùs   ‚c                ó8   € \        \        V ^ ,          4      4      # )é    )Úlenr/   )Úentrys   &r   Ú<lambda>Ú"_path_is_mounted.<locals>.<lambda>g   s   € ´#´c¸%À½(³mÔ2Dr   )Úkey)ÚoverlayÚtmpfsÚaufs)Úresolver   r   r,   r-   r_   ÚparentsÚmax)rQ   ÚtargetÚmountsÚpartsÚcoveringÚbest_fstypes   &     r   Ú_path_is_mountedro   S   sú   € ðØ—‘“ˆðÜ�nÓ%×/Ñ/¸ÈÐ/ÓS×^Ñ^Ó`ˆñ 7©vÔ6óá6ˆEÜˆu‹:˜‰?ô 	#ä $ U¨1¥X£°&Ô 8¼DÀÀqÅ»NÈfÏnÉnÑ<\ô 	#Œˆe�A�h‹˜˜q�Ó"Ù6ð ð ÷
 ÙÜ�hÑ$DÔEÀaÕH€KØÐ:Ñ:Ð:øô ô ØŠðûô ô Úðüòs4   ‚C “*C1 ÁDÁ5DÂDÃC.Ã-C.Ã1D Ã?D c               ó    € V ^8„  d   QhRRRR/# )r   Úhermes_homeúOptional[Path]r   r   r
   )r   s   "r   r   r   k   s   € ÷ ;ñ ;¨Nð ;¸}ñ ;r   c                óz   € \        4       '       g   R # V f   ^ RIHp V! 4       p \        V 4      '       d   R # RV  R2# )N)Úget_hermes_homez)Running in a container but the data dir (u¶   ) is NOT on a persistent volume mount â€” sessions, memory, skills, and API keys are ephemeral and lost on container restart. Mount a host volume over the HERMES_HOME data directory.)rV   Úhermes_constantsrt   ro   )rq   rt   s   & r   Ú_container_no_volume_mountrv   k   sB   € Ü�?Š?ÙØÒÝ4á%Ó'ˆÜ˜×$Ò$ÙØ7¸°}ð E:ð :ð ;r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚconfigúOptional[dict]r   r   r
   )r   s   "r   r   r   y   s   € ÷ ,ñ ,¨>ð ,¸iñ ,r   c                ó   € ^ RI Hp T ;'       g    / P                  R4      ;'       g    / p\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d   VP                  R4      '       g   . # VP                  R4      ;'       g    / pVP                  R4      ;'       g!    \
        P                  P                  RR	4      pVP                  R
4      ;'       g!    \
        P                  P                  RR4      pV! \        V4      4      '       d    \        V4      P                  4       '       d   . # RV R2.# )z­Warn about a network-accessible API server with no API_SERVER_KEY. Read-only against
config + env; overlaps the hard fail-closed guards but surfaces the posture at startup.
)Úis_network_accessibleÚ	platformsÚ
api_serverNÚenabledÚextraÚhostÚAPI_SERVER_HOSTz	127.0.0.1rc   ÚAPI_SERVER_KEYr9   z4OpenAI-compatible API server is network-accessible (u¢   ) with NO API_SERVER_KEY. It dispatches terminal-capable agent work â€” an unauthenticated network endpoint is remote code execution. Set a strong API_SERVER_KEY.)	Úgateway.platforms.baser{   rT   Ú
isinstanceÚdictr   rS   r/   r0   )rx   r{   ÚplatsÚapir   r€   rc   s   &      r   Ú_network_listener_without_authrˆ   y   s  € õ
 =à�\ˆ\�r×Ñ˜{Ó+×1Ð1¨r€EÜ%/°´t×%<Ò%<ˆ%�)‰)�LÔ
!À$€CÜ�sœD×!Ò! c§g¡g¨i×&8Ò&8Øˆ	Ø�G‰G�GÓ×"Ð" €EØ�9‰9�VÓ×NÐN¤§
¡
§¡Ð/@À+Ó N€DØ
�)‰)�EÓ
×
BÐ
BœbŸj™jŸn™nÐ-=¸rÓB€CÙ ¤ T£×+Ò+¬s°3«x¯~©~×/?Ò/?Øˆ	ØBÀ4À&ð I+ð +ð ,ð ,r   rq   rx   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rq   rr   rx   ry   r   r   r
   )r   s   "r   r   r   Ž   s"   € ÷ ñ  ~ð Ànð Ð`iñ r   c                ó  a a€ . p\         \        V 3R lV3R l3 FO  p V! 4       p\        T\        4      '       d   TP                  T4       K4  T'       g   K>  TP                  T4       KQ  	  V#   \         d     Kc  i ; i)z€Run all checks and return human-readable warning strings. Pure (no logging); a check that
raises simply contributes no finding.
c                 ó   <€ \        S 4      # rI   )rv   )rq   s   €r   ra   Ú$run_security_audit.<locals>.<lambda>“   s   ø€ ÔHbÐcnÔHor   c                 ó   <€ \        S 4      # rI   )rˆ   )rx   s   €r   ra   rŒ   ”   s   ø€ Ô8¸Ô@r   )r   rC   r   r„   Úlistr)   Úappend)rq   rx   ÚfindingsÚcheckÚrs   dd   r   Úrun_security_auditr“   Ž   sw   ù€ ð €HÜ"Ô$>Ô@oÜ@óBˆð	Ù“ˆAô �aœ×ÒØ�O‰O˜AÖß‰QØ�O‰O˜AÖñBð €Oøô ô 	Úð	ús   ŸA0Á0A?Á>A?Úforcec               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rq   rr   rx   ry   r”   r	   r   r   r
   )r   s   "r   r   r       s,   € ÷ ñ Ø"ðØ3AðØQUðàñr   c                ó  € \         '       d   V'       g   . # Rs \        WR7      pV'       dV   \        P                  R\	        V4      4       \        V^4       F&  w  rE\        P                  RV\	        V4      V4       K(  	  V# )zZRun the audit once per process (``force=True`` re-runs) and log each finding as a warning.T)rq   rx   uD   Security posture audit found %d issue(s) â€” review your deployment:z  [security %d/%d] %s)Ú
_AUDIT_RANr“   ÚloggerÚwarningr_   Ú	enumerate)rq   rx   r”   r�   ÚiÚfs   $$$   r   Úlog_startup_security_warningsr�       sg   € ÷
 ƒzŸ%Øˆ	Ø€JÜ!¨kÔI€HßÜ�‰Ð]Ô_bÐckÓ_lÔmÜ˜h¨Ö*‰DˆAÜ�N‰NÐ2°A´s¸8³}ÀaÖHñ +à€Or   )Ú__doc__Ú
__future__r   Úloggingr   r;   Úpathlibr   Útypingr   Ú	getLoggerr˜   r—   r   r   r5   rC   rV   ro   rv   rˆ   r“   r�   r
   r   r   Ú<module>r¤      s—   ðñõ #ã Û 	Û 	Ý Ý à	×	Ò	Ð2Ó	3€ð €
õõRõõ"qõ 
Xõ;õ0;õ,ð*¸ð ÐW[÷ ð$Ø%)ðØDHðØX]÷ñ r   