Ë
    áß²j¼m  ã            
      ó°  — U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlZddlmZ ddlmZmZmZmZ ddlmZmZmZmZmZ m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z)m*Z*m+Z+m,Z,  ejZ                  e.«      Z/dZ0d	e0› �Z1d
e0› d�Z2dZ3dZ4ee5e5e5f   Z6dZ7dZ8dZ9dZ:d>d„Z; ee7e;¬«      Z<de=d<   e<j|                  Z?e<j€                  ZAeAj„                  ZCd?d@d„ZDe#jŠ                  dfe#jŒ                  dfe#jŽ                  dfe#j�                  dffZIdAd„ZJdBd„ZKddœdCd„ZLdDd „ZMdDd!„ZNdd"œdEd#„ZOdFd$„ZPdGd%„ZQdHd&„ZRdId'„ZSdJd(„ZTdKd)„ZUdLd*„ZVdd+œ	 	 	 dMd,„ZWdd+œ	 	 	 dNd-„ZXdd.d/d0dddd1œ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dOd2„ZYdPd3„ZZdQdRd4„Z[ G d5„ d6e%«      Z\d?dSd7„Z]e]Z^ddl_Z_d8d0dd.d/d0dddd9œ		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dTd:„Z`d;d<iZad=„ Zby)UaS  Bitwarden Secrets Manager (`bws` CLI) integration.

Pulls API keys from BSM at startup so they need not live in ``~/.hermes/.env``.
``bws`` is auto-installed into ``<hermes_home>/bin/bws`` (one pinned version,
SHA-256-verified against the published checksum). The one bootstrap secret is
the access token in ``.env``; every other key can live in BSM. One
``bws secret list <project_id>`` call per fetch, cached in-process and on disk
for ``cache_ttl_seconds``. Failures NEVER block startup. Subprocess-driven on
purpose: one cross-platform binary beats the ``bitwarden-sdk-secrets`` Rust wheel.
é    )ÚannotationsN)ÚPath)ÚDictÚListÚOptionalÚTuple)ÚCachedFetchÚSecretCacheÚatomic_write_jsonÚentry_from_payloadÚfingerprintÚresolve_cache_home)	Ú	ErrorKindÚFetchResultÚSecretSourceÚclassify_cli_errorÚcoerce_floatÚis_valid_env_nameÚget_source_environmentÚrun_cliÚsource_child_envz2.0.0z;https://github.com/bitwarden/sdk-sm/releases/download/bws-vzbws-sha256-checksums-z.txté<   é   zbws_cache.jsonzbws_cache.enc.jsoné   s   hermes-bws-encrypted-cache-v1c                ó$   — dj                  | «      S )NÚ|)Újoin)Ú	cache_keys    úC/home/ubuntu/.hermes/hermes-agent/agent/secret_sources/bitwarden.pyÚ_cache_key_strr    ;   s   € Ø�8‰8�IÓÐó    )Úkey_serializerzSecretCache[_CacheKey]Ú_STOREc                ó,   — t        | «      dz  t        z  S )NÚcache)r   Ú_ENCRYPTED_CACHE_BASENAME©Ú	home_paths    r   Ú_encrypted_disk_cache_pathr)   F   s   € Ü˜iÓ(¨7Ñ2Ô5NÑNÐNr!   )z	timed out)zbinary not availablezfailed to invoke)Úunauthorizedzinvalid tokenzaccess tokenÚ401Ú403Úinvalid_clientÚinvalid_grantz400 bad request)ÚnetworkÚ
connectionÚresolveÚdownloadÚdnsc                ó"   — t        | t        «      S ©N)r   Ú_BWS_ERROR_RULES)Úmessages    r   Ú_classify_bws_errorr8   V   s   € Ü˜gÔ'7Ó8Ð8r!   c                 ó"   — ddl m}   | «       dz  S )z8Where Hermes stores its managed binaries. Profile-aware.r   ©Úget_hermes_homeÚbin)Úhermes_constantsr;   r:   s    r   Ú_hermes_bin_dirr>   ]   s   € å0áÓ˜uÑ$Ð$r!   F©Úinstall_if_missingc                óP  — t        «       t        «       z  }|j                  «       r&t        j                  |t        j
                  «      r|S t        j                  d«      }|rt        |«      S | r	 t        «       S y# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w)zOManaged ``<hermes_home>/bin/bws`` first, then PATH, then optional auto-install.Úbwszbws auto-install failed: %sN)r>   Ú_platform_binary_nameÚexistsÚosÚaccessÚX_OKÚshutilÚwhichr   Úinstall_bwsÚ	ExceptionÚloggerÚwarning)r@   ÚmanagedÚsystemÚexcs       r   Úfind_bwsrQ   d   sŠ   € äÓÔ"7Ó"9Ñ9€GØ‡~�~ÔœBŸI™I g¬r¯w©wÔ7ØˆÜ�\‰\˜%Ó €FÙÜ�F‹|ÐÙð	?Ü“=Ð ð øô ò 	?Ü�N‰NÐ8¸#×>Ð>Øûð	?ús   Á1	A< Á<	B%ÂB Â B%c                 ó8   — t        j                  «       dk(  rdS dS )NÚWindowszbws.exerB   )ÚplatformrO   © r!   r   rC   rC   t   s   € Ü Ÿ™Ó)¨YÒ6ˆ9ÐA¸EÐAr!   c            	     óþ  — t        j                  «       } t        j                  «       j                  «       }|dv rdnd}| dk(  r
dt        › d�S | dk(  rd|› d	t        › d�S | d
k(  rjd}	 t        j                  ddgdddddt
        j                  ¬«      }d|j                  |j                  z   j                  «       v rd}d|› d|› dt        › d�S t        d| › d|› �«      ‚# t        t
        j                  f$ r Y Œ<w xY w)uO   Map (uname, arch, libc) â†’ upstream asset filename (Rust target-triple style).)Úarm64Úaarch64rX   Úx86_64ÚDarwinzbws-macos-universal-z.ziprS   zbws-z-pc-windows-msvc-ÚLinuxÚgnuÚlddz	--versionTúutf-8Úreplaceé   )Úcapture_outputÚtextÚencodingÚerrorsÚtimeoutÚstdinÚmuslz-unknown-linux-Ú-z+Unsupported platform for bws auto-install: Ú )rT   rO   ÚmachineÚlowerÚ_BWS_VERSIONÚ
subprocessÚrunÚDEVNULLÚstdoutÚstderrÚOSErrorÚTimeoutExpiredÚRuntimeError)rO   rj   ÚarchÚlibcÚress        r   Ú_platform_asset_namerx   x   s  € ä�_‰_Ó€FÜ×ÑÓ ×&Ñ&Ó(€GØÐ#7Ñ7‰9¸X€Dà�ÒØ%¤l ^°4Ð8Ð8Ø�ÒØ�d�VÐ,¬\¨N¸$Ð?Ð?Ø�Òàˆð	Ü—.‘. %¨Ð!5ÀdÐQUÐ`gØ(1¸1ÄJ×DVÑDVôXˆCà˜#Ÿ*™* s§z¡zÑ1×8Ñ8Ó:Ñ:Ø�ð �d�V˜?¨4¨&°´,°¸tÐDÐDä
ÐDÀVÀHÈAÈgÈYÐWÓ
XÐXøô	 œ×2Ñ2Ð3ò 	Ùð	ús   Á(AC  Ã C<Ã;C<)Úforcec           	     ó  — t        «       }|j                  dd¬«       |t        «       z  }|j                  «       r| s|S t	        «       }t        j                  d¬«      5 }t        |«      }||z  }|t        z  }t        j                  dt        › d|› �«       t        t        › d|› �|«       t        t        › dt        › �|«       t        ||«      }t        |«      }	|j                  «       |	j                  «       k7  rt!        d|› d|› d	|	› �«      ‚t#        j$                  |«      5 }
t'        |
t        «       «      }t)        |
||«      }d
d
d
«       t        j*                  t-        |«      d¬«      \  }}t/        j0                  |«       t3        j4                  |«       t/        j6                  |d«       t/        j8                  ||«       d
d
d
«       t        j                  dt:        |«       |S # 1 sw Y   Œ¨xY w# 1 sw Y   Œ2xY w)z•Download, verify, and install the pinned ``bws`` binary; raises on any failure
    (the auto-install path catches; the setup wizard shows the error).T)ÚparentsÚexist_okzhermes-bws-)ÚprefixzDownloading %sú/zChecksum mismatch for z: expected z, got Nz.bws_)Údirr}   ií  zInstalled bws %s at %s)r>   ÚmkdirrC   rD   rx   ÚtempfileÚTemporaryDirectoryr   Ú_BWS_CHECKSUM_NAMErL   ÚinfoÚ_BWS_RELEASE_BASEÚ_http_downloadÚ_expected_sha256Ú_sha256_filerk   rt   ÚzipfileÚZipFileÚ_pick_zip_memberÚ_safe_extract_memberÚmkstempÚstrrE   ÚcloserH   Úcopy2Úchmodr_   rl   )ry   Úbin_dirÚtargetÚ
asset_nameÚtmpdirÚtmpÚzip_pathÚchecksum_pathÚexpectedÚactualÚzfÚmemberÚ	extractedÚfdÚstageds                  r   rJ   rJ   ‘   sÈ  € ô Ó€GØ‡M�M˜$¨€MÔ.ØÔ,Ó.Ñ.€FØ‡}�}„™uØˆä%Ó'€JÜ	×	$Ñ	$¨MÔ	:ð #¸fÜ�6‹lˆØ˜Ñ#ˆØÔ0Ñ0ˆä�‰Ð$Ô):Ð(;¸1¸Z¸LÐ&IÔJÜÔ+Ð,¨A¨j¨\Ð:¸HÔEÜÔ+Ð,¨AÔ.@Ð-AÐBÀMÔRä# M°:Ó>ˆÜ˜hÓ'ˆØ�>‰>Ó˜vŸ|™|›~Ò-ÜÐ!7¸
°|À;ÈxÈjÐX^Ð_eÐ^fÐgÓhÐhä�_‰_˜XÓ&ð 	>¨"Ü% bÔ*?Ó*AÓBˆFÜ,¨R°¸Ó=ˆI÷	>ô
 ×%Ñ%¬#¨g«,¸wÔG‰
ˆˆFÜ
�‰�ŒÜ�‰�Y Ô'Ü
�‰�˜ÔÜ
�
‰
�6˜6Ô"÷/#ô2 ‡K�KÐ(¬,¸Ô?Ø€M÷	>ð 	>ú÷#ð #ús&   ÁCG<Ä'"G0Å	BG<Ç0G9	Ç5G<Ç<Hc                óœ  — t         j                  j                  | ddi¬«      }	 t         j                  j                  |t        ¬«      5 }t        |d«      5 }t        j                  ||«       d d d «       d d d «       y # 1 sw Y   ŒxY w# 1 sw Y   y xY w# t         j                  j                  $ r}t        d| › d|› �«      |‚d }~ww xY w)Nz
User-Agentzhermes-agent)Úheaders)re   ÚwbzFailed to download ú: )ÚurllibÚrequestÚRequestÚurlopenÚ_BWS_DOWNLOAD_TIMEOUTÚopenrH   ÚcopyfileobjÚerrorÚURLErrorrt   )ÚurlÚdestÚreqÚrespÚfrP   s         r   r†   r†   ¸   s¿   € Ü
�.‰.×
 Ñ
  ¨|¸^Ð.LÐ
 Ó
M€CðHÜ�^‰^×#Ñ# CÔ1FÐ#ÓGð 	(È4ÔQUÐVZÐ\`ÓQað 	(ÐefÜ×Ñ˜t QÔ'÷	(÷ 	(÷ 	(ñ 	(ú÷ 	(ð 	(ûä�<‰<× Ñ ò HÜÐ0°°°R¸°uÐ=Ó>ÀCÐGûðHúsM   ¥%B Á
BÁA?Á.BÁ6B Á?B	ÂBÂBÂB ÂB ÂCÂ4CÃCc                óü   — | j                  dd¬«      j                  «       D ]>  }|j                  «       j                  «       }t	        |«      dk\  sŒ0|d   |k(  sŒ9|d   c S  t        d|› d| j                  › �«      ‚)	zEParse standard ``sha256sum`` output (``<hex>  <filename>`` per line).r^   r_   )rc   rd   r`   éÿÿÿÿr   zNo checksum entry for z in )Ú	read_textÚ
splitlinesÚstripÚsplitÚlenrt   Úname)Úchecksum_filer”   ÚlineÚpartss       r   r‡   r‡   Á   s   € à×'Ñ'°ÀÐ'ÓK×VÑVÓXò ˆØ—
‘
“×"Ñ"Ó$ˆÜˆu‹:˜‹?˜u R™y¨JÓ6Ø˜‘8ŠOðô Ð/°
¨|¸4À×@RÑ@RÐ?SÐTÓ
UÐUr!   c                óø   ‡— t        j                  «       }t        | d«      5 Št        ˆfd„d«      D ]  }|j	                  |«       Œ 	 d d d «       |j                  «       S # 1 sw Y   |j                  «       S xY w)NÚrbc                 ó&   •— ‰ j                  d«      S )Ni   )Úread)r±   s   €r   ú<lambda>z_sha256_file.<locals>.<lambda>Í   s   ø€  !§&¡&¨£-€ r!   r!   )ÚhashlibÚsha256r©   ÚiterÚupdateÚ	hexdigest)ÚpathÚhÚchunkr±   s      @r   rˆ   rˆ   Ê   si   ø€ Ü�‰Ó€AÜ	ˆd�DÓ	ð ˜QÜÓ/°Ó5ò 	ˆEØ�H‰H�U�Oñ	÷ð �;‰;‹=Ð÷ð �;‰;‹=Ðús   ¢&A!Á!A9c                óâ   — | j                  «       D �cg c]  }|j                  d«      d   |k(  sŒ|‘Œ }}|s#t        d|› d| j                  «       dd › d�«      ‚t        |t        ¬«      S c c}w )	zOFind the binary in the zip; tolerate a top-level dir, prefer the shortest path.r~   r³   zCould not find z% inside downloaded archive (members: Né   z...))Úkey)Únamelistr·   rt   Úminr¸   )r›   Úbinary_nameÚnÚ
candidatess       r   r‹   r‹   Ò   sz   € àŸ[™[›]ÖN˜¨a¯g©g°c«l¸2Ñ.>À+Ó.M’!ÐN€JÐNÙÜ˜_¨[¨Mð :(Ø(*¯©«°b°qÐ(9Ð':¸$ð@ó Að 	AäˆzœsÔ#Ð#ùò	 Os
   “A,°A,c                ó�  — t         j                  j                  |«      }t         j                  j                  t         j                  j                  ||«      «      }	 t         j                  j	                  ||g«      |k(  xr ||k7  }|st        d|›d�«      ‚| j                  ||«       t        |«      S # t
        $ r d}Y Œ;w xY w)zžExtract one member, refusing zip-slip: ``ZipFile.extract`` never verifies the
    joined path stays inside ``dest_dir``, so containment is checked here first.Fz*Refusing to extract unsafe archive member z%: it escapes the extraction directory)	rE   rÇ   Úrealpathr   Ú
commonpathÚ
ValueErrorrt   Úextractr   )r›   rœ   Údest_dirÚ	dest_rootr“   Ú	containeds         r   rŒ   rŒ   Û   s¿   € ô —‘× Ñ  Ó*€IÜ�W‰W×ÑœbŸg™gŸl™l¨9°fÓ=Ó>€FðÜ—G‘G×&Ñ&¨	°6Ð':Ó;¸yÑHÒ`ÈVÐW`ÑM`ˆ	ñ ÜÐGÈÀzð RAð Bó Cð 	Cà‡J�Jˆv�yÔ!Ü�‹<Ðøô ò ØŠ	ðús   Á+B7 Â7CÃCc                óJ   — t        j                  | «      j                  d«      S )NÚascii)Úbase64Ú	b64encodeÚdecode)Úraws    r   Ú_b64erà   î   s   € Ü×Ñ˜CÓ ×'Ñ'¨Ó0Ð0r!   c                ó’   — ddl m} ddlm}  ||j	                  «       d|t
        ¬«      j                  | j                  d«      «      S )z¥HKDF the local cache key from the bootstrap BWS token. cryptography is imported
    lazily: eagerly mapping ``_rust.pyd`` on Windows blocks the updater replacing it.r   )Úhashes)ÚHKDFé    )Ú	algorithmÚlengthÚsaltr„   r^   )Úcryptography.hazmat.primitivesrâ   Ú'cryptography.hazmat.primitives.kdf.hkdfrã   ÚSHA256Ú_ENCRYPTED_CACHE_INFOÚderiveÚencode)Úaccess_tokenrç   râ   rã   s       r   Ú_derive_encrypted_cache_keyrï   ò   s<   € õ
 6Ý<á˜&Ÿ-™-›/°"¸4Ü*ô,ß,2©F°<×3FÑ3FÀwÓ3OÓ,PðQr!   r'   c                ó2  — 	 ddl m} t        j                  d«      }t        j                  d«      }t	        | «      }t        ||«      }t        j                  |j                  |j                  dœd¬«      j                  d«      }	 ||«      j                  ||	|j                  d«      «      }
t        |t        |«      t        |«      t        |
«      d	œ}t        t        |«      |«       t         j"                  j%                  |«       y
# t&        $ r Y y
w xY w)z¥Persist an AES-GCM encrypted last-good entry atomically (best-effort). The raw
    token only derives the key; a successful write removes the legacy plaintext cache.r   ©ÚAESGCMé   é   ©ÚsecretsÚ
fetched_at)ú,ú:)Ú
separatorsr^   )ÚversionrÌ   rç   ÚnonceÚ
ciphertextN)Ú+cryptography.hazmat.primitives.ciphers.aeadrò   rE   Úurandomr    rï   ÚjsonÚdumpsrö   r÷   rí   ÚencryptÚ_ENCRYPTED_CACHE_VERSIONrà   r   r)   r#   ÚdiskÚclearrK   )r   rî   Úentryr(   rò   rç   rü   Úserialized_keyrÌ   Ú	plaintextrý   Úpayloads               r   Ú_write_encrypted_disk_cacher
  þ   så   € ðÝFä�z‰z˜"‹~ˆÜ—
‘
˜2“ˆÜ'¨	Ó2ˆÜ)¨,¸Ó=ˆÜ—J‘JØŸ™°U×5EÑ5EÑFÐS]ô
ç
‰&�‹/ð 	ñ ˜C“[×(Ñ(¨°	¸>×;PÑ;PÐQXÓ;YÓZˆ
Ü6¸~Ü  ›;´°u³ÌUÐS]ÓM^ñ`ˆäÔ4°YÓ?ÀÔIÜ�‰×Ñ˜)Õ$øÜò Ùðús   ‚DD
 Ä
	DÄDc                óh  ‡— |dk  ry	 ddl m} t        j                  t	        |«      j                  d¬«      «      Št        | «      }t        ‰t        «      r,‰j                  d«      t        k7  s‰j                  d«      |k7  ryˆfd„d	D «       \  }}}t        ||«      }	t        t        j                   ||	«      j                  |||j                  d«      «      j                  d«      «      «      }
|
€yt!        j                   «       |
j"                  z
  }|dk  s||kD  rdS |
S # t$        $ r Y yw xY w)
zMDecrypted encrypted-cache entry if it matches ``cache_key`` and is in-window.r   Nrñ   r^   )rc   rû   rÌ   c           	   3  óœ   •K  — | ]C  }t        j                  t        ‰j                  |d «      «      j	                  d«      d¬«      –— ŒE y­w)Ú rÛ   T)ÚvalidateN)rÜ   Ú	b64decoderŽ   Úgetrí   )Ú.0Úkr	  s     €r   ú	<genexpr>z-_read_encrypted_disk_cache.<locals>.<genexpr>#  sH   øè ø€ ò #MØ'(ô $*×#3Ñ#3´C¸¿¹ÀAÀrÓ8JÓ4K×4RÑ4RÐSZÓ4[Ðfj×#kÐ#kñ #Mùs   ƒA	A)rç   rü   rý   )rþ   rò   r   Úloadsr)   r´   r    Ú
isinstanceÚdictr  r  rï   r   Údecryptrí   rÞ   Útimer÷   rK   )r   rî   Úmax_age_secondsr(   rò   r  rç   rü   rý   rÌ   r  Ú	entry_ager	  s               @r   Ú_read_encrypted_disk_cacher    s%  ø€ ð ˜!ÒØðÝFä—*‘*Ô7¸	ÓB×LÑLÐV]ÐLÓ^Ó_ˆÜ'¨	Ó2ˆÜ˜7¤DÔ)Ø—;‘;˜yÓ)Ô-EÒEØ—;‘;˜uÓ%¨Ò7Øó#MØ,Kô#MÑˆˆe�Zä)¨,¸Ó=ˆÜ"¤4§:¡:Ù�3‹K×Ñ  z°>×3HÑ3HÈÓ3QÓR×YÑYÐZaÓbó$
ó ˆð ˆ=ØÜ—I‘I“K %×"2Ñ"2Ñ2ˆ	Ø  1’}¨	°OÒ(CˆtÐNÈÐNøÜò Ùðús%   ‰A;D% ÂA0D% Ã6,D% Ä#D% Ä%	D1Ä0D1é,  Tr  )ÚbinaryÚcache_ttl_secondsÚ	use_cacheÚ
server_urlr(   Úencrypted_cache_enabledÚ!encrypted_cache_max_stale_secondsc        	   
     ó  ‡ ‡‡‡‡— ‰ st        d«      ‚|st        d«      ‚t        ‰ «      ||xs dfŠdˆ ˆˆfd„Š|r6‰dkD  r1t        j                  ‰‰‰|rˆˆfd„nd¬«      }	|	�|	j                  g fS |xs t        d	¬
«      }
|
€t        d«      ‚	 t        |
‰ ||«      \  }}t)        |t!        j                   «       ¬«      }|rO‰dkD  r|t        j$                  ‰<   |rt+        ‰‰ |‰¬«       ||fS t        j                  j-                  ‰|‰‰«       ||fS # t         $ rå}|rÝt        t        |«      «      t        j                  t        j                  fv r©dx}}|r ‰|«      }d}n1‰dkD  r,t        j                  j                  ‰t        d«      ‰«      }d}|�et        dt!        j                   «       |j"                  z
  «      }|t        j$                  ‰<   |j                  d|› d|› dt'        |«      › d�gfcY d}~S ‚ d}~ww xY w)uq  Pull the secrets for ``project_id`` from BSM â†’ ``(secrets, warnings)``.

    ``server_url``: region / self-hosted instance (empty = US Cloud). With
    ``encrypted_cache_enabled`` fresh entries are written AES-GCM encrypted and a
    last-good entry may be served after NETWORK/TIMEOUT failures for up to
    ``encrypted_cache_max_stale_seconds`` â€” independent of the fresh TTL, so
    ``cache_ttl_seconds: 0`` can coexist with a break-glass offline cache.
    Raises ``RuntimeError`` on fatal conditions (missing binary, auth failure,
    unparseable output); env_loader catches, the setup wizard lets it propagate.
    zBitwarden access token is emptyzBitwarden project_id is emptyr  c                ó"   •— t        ‰‰| ‰¬«      S )N)r   rî   r  r(   )r  )Úmax_agerî   r   r(   s    €€€r   Ú_read_encryptedz0fetch_bitwarden_secrets.<locals>._read_encryptedK  s   ø€ Ü)°IÈLØ:AÈYôXð 	Xr!   r   c                 ó   •—  ‰ ‰«      S r5   rU   )r&  r  s   €€r   rÁ   z)fetch_bitwarden_secrets.<locals>.<lambda>S  s   ø€ ™Ð/@ÓA€ r!   N)Ú	read_diskTr?   uº   bws binary not available â€” auto-install failed and `bws` is not on PATH.  Install manually from https://github.com/bitwarden/sdk-sm/releases or re-run `hermes secrets bitwarden setup`.zstale ENCRYPTED disk cacheÚinfzstale disk cacheç        zbws live fetch failed (z); falling back to z (zs old)rõ   )r   rî   r  r(   )r%  ÚfloatÚreturnúOptional[_CachedFetch])rt   Ú_token_fingerprintr#   Úlookuprö   rQ   Ú_run_bws_listr8   rŽ   r   ÚNETWORKÚTIMEOUTr  rÀ   r+  Úmaxr  r÷   ÚmemoryÚintÚ_CachedFetchr
  Úwrite)rî   Ú
project_idr  r  r  r   r(   r!  r"  ÚcachedrB   rö   ÚwarningsrP   ÚstaleÚlabelÚager  r&  r   s   `  `  `           @@r   Úfetch_bitwarden_secretsr>  4  s(  ü€ ñ  ÜÐ<Ó=Ð=ÙÜÐ:Ó;Ð;ä# LÓ1°:¸zÒ?OÈRÐP€I÷Xñ Ð&¨Ò*ä—‘ØÐ(¨)ÙF]ÕAÐcgð ó 
ˆð ÐØ—>‘> 2Ð%Ð%à
Ò
5”H°Ô5€CØ
€{Üð ?ó @ð 	@ð
Ü)¨#¨|¸ZÈÓTÑˆ�ô,  ´T·Y±Y³[ÔA€EÙØ˜qÒ Ø',ŒF�M‰M˜)Ñ$Ù"Ü'°)È,Ø.3¸yõJð �HÐÐô �K‰K×Ñ˜i¨Ð0AÀ9ÔMØ�HÐÐøô= ò ñ Ô,¬S°«XÓ6¼9×;LÑ;LÌi×N_ÑN_Ð:`Ñ`Ø Ð ˆE�EÙ&Ù'Ð(IÓJ�Ø4‘Ø" QÒ&ÜŸ™×(Ñ(¨´E¸%³LÀ)ÓL�Ø*�ØÐ Ü˜#œtŸy™y›{¨U×-=Ñ-=Ñ=Ó>�Ø+0”—‘˜iÑ(Ø—}‘}Ø-¨c¨UÐ2EÀeÀWÈBÌsÐSVËxÈjÐX^Ð_ð'ð õ ð 	ûð)ús%   ÂD Ä	HÄCG>Ç7HÇ=G>Ç>Hc                ó@  — | j                  dd«      j                  «       }g }|j                  «       D ]U  }|j                  «       }|j                  d«      r n2|dvsŒ+t	        j
                  dd|«      x}sŒE|j                  |«       ŒW |rdj                  |«      S |S )zœReduce a bws (color-eyre) error dump to its numbered cause lines joined with
    ``; `` (dropping ``Location:``/``Backtrace`` on); raw text if unrecognized.úr  )z	Location:zBacktrace omittedz	Run with )r  zError:z^\d+:\s*z; )r_   r¶   rµ   Ú
startswithÚreÚsubÚappendr   )rß   rb   Úcausesr»   ÚstrippedÚcauses         r   Ú_summarize_bws_stderrrH  ‚  s™   € ð �;‰;�v˜rÓ"×(Ñ(Ó*€DØ€FØ—‘Ó!ò !ˆØ—:‘:“<ˆØ×ÑÐNÔOÙØ˜>Ò)¼¿¹¸{ÈBÐPXÓ8YÐ/Y¨uÑ/YØ�M‰M˜%Õ ð!ñ !'ˆ4�9‰9�VÓÐ0¨DÐ0r!   c           	     ó’  — t        | «      dd|ddg}t        «       }||d<   |j                  dd«       |r||d<   t        ||t        d	d
t        › d�¬«      }|j
                  dk7  rEt        |j                  xs |j                  xs d«      }t        d|j
                  › d|d d › �«      ‚|j                  j                  «       }|si dgfS 	 t        j                  |«      }	t        |	t        «      s!t        dt!        |	«      j"                  › �«      ‚i }g }|	D ]€  }t        |t$        «      r"|j'                  d«      |j'                  d«      fnd\  }}t        |t         «      rt        |t         «      sŒ[t)        |«      r|||<   Œl|j+                  d|›d�«       Œ‚ ||fS # t        j                  $ r}
t        d|
› �«      |
‚d }
~
ww xY w)NÚsecretÚlistz--outputr   ÚBWS_ACCESS_TOKENÚNO_COLORÚ1ÚBWS_SERVER_URLrB   zbws timed out after zs fetching secrets)Úenvre   r<  Útimeout_messager   r  zbws exited r£   éÈ   z'bws returned no output (empty project?)zbws returned non-JSON output: zbws returned unexpected shape: rÌ   Úvalue)NNzSkipping secret z: not a valid env-var name)rŽ   r   Ú
setdefaultr   Ú_BWS_RUN_TIMEOUTÚ
returncoderH  rq   rp   rt   r¶   r   r  ÚJSONDecodeErrorr  rK  ÚtypeÚ__name__r  r  Ú_is_valid_env_namerD  )rB   rî   r8  r   ÚcmdrP  ÚprocÚerrrß   r	  rP   rö   r:  ÚitemrÌ   rS  s                   r   r0  r0  �  sÚ  € Üˆs‹8�X˜v z°:¸vÐ
F€Cô Ó
€CØ*€CÐÑØ‡N�N�:˜sÔ#ÙØ *ˆÐÑä�3˜CÔ)9ÀØ%9Ô:JÐ9KÐK]Ð#^ô`€Dð ‡�˜!ÒÜ# D§K¡KÒ$D°4·;±;Ò$DÀ"ÓEˆÜ˜[¨¯©Ð(9¸¸CÀÀ¸I¸;ÐGÓHÐHà
�+‰+×
Ñ
Ó
€CÙØÐ=Ð>Ð>Ð>ðLÜ—*‘*˜S“/ˆô �gœtÔ$ÜÐ<¼TÀ'»]×=SÑ=SÐ<TÐUÓVÐVà €GØ€HØò RˆÜ=GÈÌdÔ=S�d—h‘h˜u“o t§x¡x°Ó'8Ñ9ÐYe‰
ˆˆUÜ˜#œsÔ#¬:°e¼SÔ+AØÜ˜cÔ"Ø ˆG�CŠLà�O‰OÐ.¨s¨gÐ5OÐPÕQðRð �HÐÐøô ×Ñò LÜÐ;¸C¸5ÐAÓBÈÐKûðLús   ÃF ÆGÆ2GÇGc                  ót   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zej                  eej                  eiZdd
„Zdd„Zy)ÚBitwardenSourcezŒBitwarden Secrets Manager as a registered **bulk** source (injects every
    secret in the project, so explicit mapped bindings outrank it).Ú	bitwardenzBitwarden Secrets ManagerÚbulkrB   Úaccess_token_envrL  Tuò   Run `hermes secrets bitwarden token` to paste a fresh access token (create one in the Bitwarden web app: Secrets Manager â†’ Machine accounts â†’ Access tokens).  Wrong region?  Re-run `hermes secrets bitwarden setup` and pick EU/self-hosted.c           
     óN   — dddœdddœdddœdd	dœd
dddœdœdddœdddœdddœdœS )NzMaster switchF)ÚdescriptionÚdefaultz0Env var holding the machine-account access tokenrL  zBSM project UUIDr  z9Fresh disk+memory cache TTL; 0 disables fresh-cache reuser  z6Encrypted last-good cache for network/timeout fallbackr   )ÚenabledÚmax_stale_secondsz&BSM values overwrite .env/shell valuesTz#Auto-download the pinned bws binaryz0Region / self-hosted endpoint (empty = US Cloud))rg  rc  r8  r  Úencrypted_cacheÚoverride_existingÚauto_installr   rU   )Úselfs    r   Úconfig_schemazBitwardenSource.config_schemaÍ  s`   € à'6À5ÑIØ0bØ,>ñ!@à*<ÈÑLØ1lØ-0ñ"2à/gØ7<ÐSTÑ+Uñ Wà1YÐfjÑ!kØ,QÐ^bÑcØ*\ÐikÑlñ
ð 	
r!   c                ó¼  — t        |t        «      r|ni }t        «       }| j                  |«      }t	        «       j                  |d«      j                  «       }|s$|j                  d|› d�t        j                  «      S t        |j                  d«      xs d«      }|s |j                  dt        j                  «      S t        t        |j                  dd«      «      ¬«      }||_        |€ |j                  d	t        j                  «      S |j                  d
«      }t        |t        «      r|ni }	 t        |||t!        |j                  dd«      d«      t        |j                  dd«      xs d«      j                  «       |t        |j                  dd«      «      t!        |j                  dd«      d«      ¬«      \  }	}
|	|_        |j.                  j1                  |
«       |S # t"        $ rn}|j                  t        |«      t%        t        |«      «      «       |j&                  t        j(                  k(  rd|› d|j*                  › d�|_        |cY d }~S d }~ww xY w)Nr  ú&secrets.bitwarden.enabled is true but ú3 is not set.  Run `hermes secrets bitwarden setup`.r8  úMsecrets.bitwarden.project_id is empty.  Run `hermes secrets bitwarden setup`.rk  Tr?   úhbws binary not available and auto-install is disabled.  Run `hermes secrets bitwarden setup` to install.ri  r  r  g     Àr@r   rg  Frh  r   r*  ©rî   r8  r  r  r   r(   r!  r"  z5Bitwarden rejected the machine-account access token (uF   ) â€” it was likely revoked, expired, or belongs to another region.  (ú))r  r  r   Ú	token_envr   r  r¶   Úfailr   ÚNOT_CONFIGUREDrŽ   rQ   ÚboolÚbinary_pathÚBINARY_MISSINGr>  r   rt   r8   Ú
error_kindÚAUTH_FAILEDr«   rö   r:  Úextend)rl  Úcfgr(   Úresultrc  rî   r8  r  Úencrypted_cfgrö   r:  rP   s               r   ÚfetchzBitwardenSource.fetchÜ  s3  € Ü ¤TÔ*‰c°ˆÜ“ˆàŸ>™>¨#Ó.ÐÜ-Ó/×3Ñ3Ð4DÀbÓI×OÑOÓQˆÙØ—;‘;Ð!GÐHXÐGYð ZQð  QÜR[×RjÑRjólð lä˜Ÿ™ Ó.Ò4°"Ó5ˆ
ÙØ—;‘;ÐnÜ(×7Ñ7ó9ð 9ä¬T°#·'±'¸.È$Ó2OÓ-PÔQˆØ#ˆÔØˆ>Ø—;‘;ð  RÜS\×SkÑSkómð mð Ÿ™Ð 1Ó2ˆÜ)3°MÄ4Ô)H™Èbˆð	Ü 7Ø)°jÈÜ".¨s¯w©wÐ7JÈCÓ/PÐRWÓ"XÜ˜sŸw™w |°RÓ8Ò>¸BÓ?×EÑEÓGÐS\Ü(,¨]×->Ñ->¸yÈ%Ó-PÓ(QÜ2>¸}×?PÑ?PÐQdÐfgÓ?hÐjmÓ2nô!ÑˆG�Xð !ˆŒØ�‰×Ñ˜xÔ(Øˆøô ò 	Ø�K‰Kœ˜C›Ô"5´c¸#³hÓ"?Ô@Ø× Ñ ¤I×$9Ñ$9Ò9ð!$Ø$4Ð#5ð 6CØCIÇ<Á<À.ÐPQð!S�”ð �Mûð	ús    Ä2BG$ Ç$	IÇ-A#IÉIÉIN)r,  r  )r~  r  r(   r   r,  r   )rY  Ú
__module__Ú__qualname__Ú__doc__r¹   r<  ÚshapeÚschemeÚtoken_env_keyÚdefault_token_envÚoverride_existing_defaultÚ
_AUTH_HINTr   r|  ÚAUTH_EXPIREDÚremediation_hintsrm  r�  rU   r!   r   r`  r`  ¸  sd   „ ñGð €DØ'€EØ€EØ€FØ&€MØ*Ðð !%Ðð	Dð ð #×.Ñ.°
¸I×<RÑ<RÐT^Ð_Ðó
ô(r!   r`  c                óŒ   — t         j                  | «       	 t        | «      j                  «        y# t        t
        f$ r Y yw xY w)zWDrop in-process AND disk caches (plaintext and encrypted), e.g. after a token rotation.N)r#   r  r)   ÚunlinkÚFileNotFoundErrorrr   r'   s    r   Úclear_cachesr�    s;   € ä
‡L�L�ÔðÜ" 9Ó-×4Ñ4Õ6øÜœwÐ'ò Ùðús   —1 ±AÁArL  )	rc  r8  rj  r  rk  r   r(   r!  r"  c        
   
     óø  — t        «       }
| s|
S t        j                  j                  |d«      j	                  «       }|sd|› d�|
_        |
S |s	d|
_        |
S t        |¬«      }||
_        |€	d|
_        |
S 	 t        ||||||||	¬«      \  }}||
_        |
j                  j                  |«       |j                  «       D ]‘  \  }}||k(  r|
j                  j!                  |«       Œ'|s;t        j                  j                  |«      r|
j                  j!                  |«       Œd|t        j                  |<   |
j"                  j!                  |«       Œ“ |
S # t        $ r}t        |«      |
_        |
cY d}~S d}~ww xY w)	u8  Pull secrets from BSM and set them on ``os.environ``.

    This is the function ``load_hermes_dotenv()`` calls after the .env
    files have loaded.  It is intentionally defensive â€” any failure
    returns a :class:`FetchResult` with ``error`` set; it never raises.

    ``server_url`` selects the Bitwarden region or self-hosted endpoint
    (e.g. ``https://vault.bitwarden.eu`` for EU Cloud).  Empty string
    means use ``bws``'s default (US Cloud).

    Parameters mirror the ``secrets.bitwarden.*`` config keys so the
    caller can just splat the dict in.
    r  ro  rp  rq  r?   Nrr  rs  )r   rE   Úenvironr  r¶   r«   rQ   ry  r>  rt   rŽ   rö   r:  r}  ÚitemsÚskippedrD  Úapplied)rg  rc  r8  rj  r  rk  r   r(   r!  r"  r  rî   r  rö   r:  rP   rÌ   rS  s                     r   Úapply_bitwarden_secretsr–    s…  € ô4 ‹]€FáØˆä—:‘:—>‘>Ð"2°BÓ7×=Ñ=Ó?€LÙà4Ð5EÐ4Fð G>ð >ð 	Œð ˆáð4ð 	Œð ˆä¨Ô6€FØ€FÔØ€~ð?ð 	Œð ˆðÜ3Ø%Ø!ØØ/Ø!ØØ$;Ø.Oô	
Ñˆ�ð €F„NØ
‡O�O×Ñ˜8Ô$à—m‘m“oò #‰
ˆˆUØÐ"Ò"ð �N‰N×!Ñ! #Ô&ØÙ ¤R§Z¡Z§^¡^°CÔ%8Ø�N‰N×!Ñ! #Ô&ØØŒ�
‰
�3‰Ø�‰×Ñ˜cÕ"ð#ð €Møô) ò Ü˜3“xˆŒØ�ûðús   Á6E Å	E9ÅE4Å.E9Å4E9Ú	DiskCache)zagent.secret_sources._cacher—  c                óÌ   — t         j                  | «      }|€t        dt        ›d| ›�«      ‚dd l}ddlm}  |t        | g|¢­Ž  t        |j                  |d   «      |d   «      S )Nzmodule z has no attribute r   )Ú	warn_oncer   )	Ú_PLUGIN_COMPAT_LAZYr  ÚAttributeErrorrY  Ú	importlibÚhermes_cli.plugin_compatr™  ÚgetattrÚimport_module)r¹   r“   rœ  r™  s       r   Ú__getattr__r   w  se   € Ü ×$Ñ$ TÓ*€FØ€~Ü˜w¤x lÐ2DÀTÀHÐMÓNÐNÛÝ2ÙŒh˜Ð&˜vÓ&Ü�9×*Ñ*¨6°!©9Ó5°v¸a±yÓAÐAr!   )r   Ú	_CacheKeyr,  rŽ   r5   )r(   úOptional[Path]r,  r   )r7   rŽ   r,  r   )r,  r   )r@   rx  r,  r¢  )r,  rŽ   )ry   rx  r,  r   )r­   rŽ   r®   r   r,  ÚNone)rº   r   r”   rŽ   r,  rŽ   )rÇ   r   r,  rŽ   )r›   úzipfile.ZipFilerÏ   rŽ   r,  rŽ   )r›   r¤  rœ   rŽ   r×   r   r,  r   )rß   Úbytesr,  rŽ   )rî   rŽ   rç   r¥  r,  r¥  )
r   r¡  rî   rŽ   r  r6  r(   r¢  r,  r£  )
r   r¡  rî   rŽ   r  r+  r(   r¢  r,  r-  )rî   rŽ   r8  rŽ   r  r¢  r  r+  r  rx  r   rŽ   r(   r¢  r!  rx  r"  r+  r,  ú Tuple[Dict[str, str], List[str]])rß   rŽ   r,  rŽ   )r  )
rB   r   rî   rŽ   r8  rŽ   r   rŽ   r,  r¦  )r(   r¢  r,  r£  )rg  rx  rc  rŽ   r8  rŽ   rj  rx  r  r+  rk  rx  r   rŽ   r(   r¢  r!  rx  r"  r+  r,  r   )cr„  Ú
__future__r   rÜ   rÂ   r   ÚloggingrE   rT   rB  rH   rm   r�   r  Úurllib.errorr¤   Úurllib.requestr‰   Úpathlibr   Útypingr   r   r   r   Úagent.secret_sources._cacher	   r6  r
   r   r   r   r.  r   Úagent.secret_sources.baser   r   r   r   r   r   rZ  r   r   r   Ú	getLoggerrY  rL   rl   r…   rƒ   r¨   rU  rŽ   r¡  Ú_DISK_CACHE_BASENAMEr&   r  rë   r    r#   Ú__annotations__r4  Ú_CACHEr  Ú_DISK_CACHErÇ   Ú_disk_cache_pathr)   r2  rz  r|  r1  r6   r8   r>   rQ   rC   rx   rJ   r†   r‡   rˆ   r‹   rŒ   rà   rï   r
  r  r>  rH  r0  r`  r�  Ú_reset_cache_for_testsÚstatr–  rš  r   rU   r!   r   ú<module>r·     s:  ðò	õ #ã Û Û Û Û 	Û Û 	Û Û Û Û Û Û Û Ý ß .Ó .÷÷ ÷÷ õ ð
 
ˆ×	Ñ	˜8Ó	$€ð €ØQÐR^ÐQ_Ð`Ð Ø,¨\¨N¸$Ð?Ð ØÐ ØÐ ð �#�s˜C�-Ñ €	Ø'Ð Ø0Ð ØÐ Ø8Ð óñ "-Ð-AÐR`Ô!a€ÐÓ aà	�‰€Ø�k‰k€Ø×#Ñ#Ð ôOð ×Ñ˜Ð'Ø×ÑÐKÐLØ×Ñð Sð Tà×ÑÐOÐPðÐ ó9ó%ð ,1õ ó BóYð2 "'õ $óNHóVóó$óó&1ó	Qð =AñØ+9ðØEIóð0 <@ñØ*8ðØDZóð@ EIØ"°dÈbØ $ÀeØ/0ñ	KØðKØ&)ðKØ3AðKàðKà/3ðKàHKðKð ðKð @DðKð (-ð	Kð
 &óKó\1ô%ôPL�lô Lô^ð &Ð ó ð
 /ØØ#Ø"ØØØ $Ø$)Ø/0ñVàðVð ðVð ð	Vð
 ðVð ðVð ðVð ðVð ðVð "ðVð (-ðVð óVðt Ð=ðÐ ó
Br!   