feat(infra): auto-commit con 88 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
---
|
||||
name: pass_get_secret
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def pass_get_secret(path: str, *, line: int = 1, timeout_s: float = 10.0) -> dict"
|
||||
description: "Lee un secreto del gestor de contrasenas pass (passwordstore.org) ejecutando `pass show <path>` como subproceso (lista de args, nunca shell=True). Devuelve la linea solicitada (1-indexed): line=1 es la contrasena por convencion de pass, line=N es metadata multilinea (usuario, URL, notas). El valor es sensible y la funcion NUNCA lo logea. Maneja errores sin lanzar: pass no instalado, entry inexistente, linea fuera de rango. Solo usa stdlib (subprocess)."
|
||||
tags: [pass, secret, credential, infra, flow-replay]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: [subprocess]
|
||||
params:
|
||||
- name: path
|
||||
desc: "ruta del secreto dentro del store (p.ej. 'gitea/dataforge-git-token'). Es el argumento que recibiria `pass show <path>`."
|
||||
- name: line
|
||||
desc: "numero de linea a devolver, 1-indexed. line=1 (default) = primera linea = contrasena por convencion de pass. line=N = linea N para metadata multilinea."
|
||||
- name: timeout_s
|
||||
desc: "timeout del subproceso `pass show` en segundos. Default 10.0."
|
||||
output: "dict. En exito: {status: 'ok', value: str} con la linea pedida sin el salto de linea final. En error (sin lanzar): {status: 'error', error: str} para pass no instalado ('pass not installed'), entry inexistente o fallo de pass (stderr stripeado), o linea fuera de rango ('line N out of range')."
|
||||
tested: true
|
||||
tests:
|
||||
- "test_line_1_devuelve_la_password"
|
||||
- "test_line_2_devuelve_metadata"
|
||||
- "test_returncode_distinto_de_cero_es_error"
|
||||
- "test_pass_no_instalado_es_error"
|
||||
- "test_linea_fuera_de_rango_es_error"
|
||||
- "test_timeout_es_error"
|
||||
test_file_path: "python/functions/infra/pass_get_secret_test.py"
|
||||
file_path: "python/functions/infra/pass_get_secret.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.insert(0, "python/functions")
|
||||
from infra.pass_get_secret import pass_get_secret
|
||||
|
||||
# Primera linea = la contrasena/token (convencion de pass).
|
||||
res = pass_get_secret("gitea/dataforge-git-token")
|
||||
print(res) # {"status": "ok", "value": "ghp_..."} -- NO logear el value en prod
|
||||
|
||||
# Linea 2 = metadata (p.ej. el usuario), si el entry es multilinea.
|
||||
user = pass_get_secret("apis/licenseplatedata", line=2)
|
||||
print(user) # {"status": "ok", "value": "user: neo"}
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando necesites resolver un secreto de `pass` para inyectarlo en una config,
|
||||
un header HTTP, una variable de entorno o un body de request sin hardcodearlo en
|
||||
el codigo. Es el lector de secretos del registry en Python: el caller pide la
|
||||
ruta del store y recibe el valor en `value`, listo para enchufar donde haga
|
||||
falta. line=1 para la password; line=N para metadata (usuario, URL, notas).
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Requiere `pass` instalado y el GPG agent desbloqueado.** Si `pass` no esta en
|
||||
el PATH devuelve `{"status": "error", "error": "pass not installed"}`. Si el
|
||||
agente GPG esta bloqueado, `pass show` puede colgarse hasta el `timeout_s`.
|
||||
- **El valor es un secreto: no lo logees.** La funcion nunca lo imprime ni lo
|
||||
registra. Trata el campo `value` como sensible aguas arriba (no `print` en
|
||||
produccion, no persistir en claro).
|
||||
- **line=1 es la contrasena.** Por convencion de pass la primera linea es el
|
||||
secreto principal; las lineas siguientes son metadata 1-indexed.
|
||||
- **No usa shell.** Ejecuta `["pass", "show", path]` como lista de args, nunca
|
||||
`shell=True`, asi que `path` no puede inyectar comandos.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
v1.0.0 — version inicial. Lector de secretos `pass` para Python, base de la
|
||||
resolucion `pass:` en hoppscotch_set_environment.
|
||||
Reference in New Issue
Block a user