Saltar al contenido principal

Gestión de secretos

La configuración del backend incluye credenciales de alto impacto. Esta página describe cómo tratarlas.

Qué hay en el .env​

Toda la configuración vive en docker-compose.yml, escrita literalmente. Lo único que llega del entorno son estas claves, y por eso el .env es el único archivo que nunca se versiona.

Sin ellas el stack no arranca — pero se generan solas​

SecretoImpacto si se filtra
DB_PASSWORDAcceso total a la base de datos.
JWT_SECRETClave maestra. Falsifica sesiones, descifra las claves privadas guardadas y las credenciales de Datadis, y deriva carteras. Ver API de Zertipower.

Opcionales — el stack arranca sin ellas​

ClaveQué se pierde
GOOGLE_CLIENT_ID y GOOGLE_CLIENT_SECRETEl botón «Iniciar sesión con Google» del Panel deja de funcionar; se entra con usuario y contraseña. Van en pareja: con una sola tampoco funciona. El secreto lo es de verdad; el ID no — ver Acceso con Google, paso a paso.
ZERTIAUTH_APP_SECRETNo se puede derivar la cartera, así que falla el primer acceso con Google de cada usuario. Los que ya tengan cuenta entran igual. Sigue siendo una clave maestra: quien la tenga deriva la cartera de cualquiera.
PKNo se firma nada on-chain: la capa blockchain queda inerte. El instalador genera una al azar, así que rara vez falta — pero la generada es una cartera vacía. Sigue siendo un secreto: quien tenga la de verdad controla la cartera y sus fondos.
STRIPE_SECRET_KEYDejan de funcionar los endpoints /stripe: no se pueden comprar EKW desde el Contador. Sigue siendo un secreto — en local, siempre sk_test_….
GOOGLE_MAPS_API_KEYEl mapa no carga y la geocodificación responde REQUEST_DENIED.
SOLAR_API_AUTH_CODELa predicción de producción solar devuelve error.
La de Maps no es realmente un secreto

Es una clave de navegador: acaba dentro del HTML que se sirve, así que no se puede ocultar. Se protege restringiéndola por dominio en Google Cloud Console, no manteniéndola en secreto. Está aquí porque conviene no regalarla, no porque ocultarla sirva de algo.

Cómo rellenarlas​

Al ejecutar ./setup.sh o setup.bat sin un .env presente, el instalador escribe uno completo sin preguntar nada… salvo las dos claves de Google, que son lo único que no puede deducir. El secreto no se muestra al teclear; el client ID sí, porque no es secreto y así se ve una errata al pegarlo.

DB_PASSWORD, JWT_SECRET y PK se generan al azar, en hexadecimal. No hay que elegirlas, y el hexadecimal evita que un carácter especial rompa la cadena de conexión a la base de datos.

Las demás —ZERTIAUTH_APP_SECRET, STRIPE_SECRET_KEY, GOOGLE_MAPS_API_KEY, SOLAR_API_AUTH_CODE— quedan escritas y vacías en el .env, cada una con un comentario que explica qué se pierde sin ella. Para ponerlas, se edita el archivo.

Las de Google no se saltan pulsando INTRO​

Dejarlas en blanco era lo cómodo, y salía caro: la instalación parecía terminada y nadie podía entrar con Google, con el fallo apareciendo mucho después y lejos de su causa.

Ahora el instalador insiste. Si las dejas vacías, explica que faltan y las vuelve a pedir. Se puede instalar sin ellas, pero hay que decirlo a propósito escribiendo SALTAR; a la tercera ronda continúa igualmente, para no dejar una instalación colgada.

Si sales sin ponerlas, se entra con admin / admin123, y cuando tengas el cliente de OAuth basta con añadirlas al .env y reiniciar el backend:

./dev.sh up -d backend

Cómo crear el cliente: Acceso con Google, paso a paso.

Ninguna clave impide ya arrancar

Las únicas dos que el compose exige sin valor por defecto, DB_PASSWORD y JWT_SECRET, las genera el instalador, así que siempre están. Todo lo demás puede quedarse vacío: el sistema arranca y sólo se pierde la función que dependa de esa clave.

DB_PASSWORD, JWT_SECRET y PK no se preguntan: se generan al azar en hexadecimal. Esto último importa —ver la regla 6 más abajo.

ZERTIAUTH_APP_SECRET no se genera nunca

Es la excepción a lo anterior, y la razón por la que no se generan todas. Vacía es segura: la derivación lanza un error claro y no crea ninguna cartera. Un valor inventado no falla — deriva carteras distintas de las reales, sin avisar, y el usuario pierde el acceso a lo que tuviera on-chain.

Por eso el instalador la pregunta y la deja en blanco si no la sabes, en vez de rellenarla con algo. Sale de la columna secret de la tabla apps de Zertiauth.

La PK generada no sirve para firmar

DB_PASSWORD y JWT_SECRET se pueden generar porque cualquier valor aleatorio es correcto: el instalador configura los dos lados a la vez. PK no funciona así. Su contraparte —la cartera que ya posee los contratos— existe fuera del sistema y no se reconfigura, de modo que la clave generada corresponde a una cartera nueva y vacía: sin gas y sin permisos.

Sirve para que el sistema arranque sin preguntar nada. Para usar la blockchain de verdad hay que sustituirla en el .env por la clave real. El archivo que genera el instalador lleva un comentario que lo recuerda.

Si el .env ya existe pero está incompleto​

Es el caso más habitual al heredar una instalación. El instalador repasa el archivo y completa lo que falte, sin tocar lo que ya hay:

  • DB_PASSWORD y JWT_SECRET, si faltan, se generan al azar. No se preguntan nunca. PK igual.
  • Las demás, si ni siquiera están escritas en el archivo, se preguntan una vez y se escriben aunque las dejes en blanco, para no volver a preguntarlas en cada ejecución. Una clave escrita y vacía es una decisión tomada, y se respeta: sólo se recuerda qué se pierde sin ella.
  • Lo que el archivo ya tiene no se toca, comentarios incluidos.
  • Una clave vacía se rellena en su sitio; una que no estuviera se añade al final.
  • Antes de modificar nada deja una copia en .env.backup-<fecha>, que está cubierta por .gitignore.
  • En modo --desatendido no puede preguntar: genera las que sabe generar y avisa de las que quedan vacías, pero no se detiene, porque ya ninguna impide arrancar.

Las opcionales no detienen nada. De las que ni siquiera estén escritas en el archivo te pregunta una vez, y las escribe aunque las dejes en blanco: así no vuelve a preguntártelas en cada ejecución. Una clave escrita y vacía es una decisión tomada, y se respeta.

Las dos claves de Google van juntas

Los dos son opcionales y el instalador los pide juntos, porque van en pareja: un secreto con el ID de otro cliente da invalid_client, y el ID solo tampoco sirve. Si pones uno y el otro no, avisa.

Reglas​

  1. El .env nunca se versiona. Debe estar en .gitignore. Lo que se versiona es .env.example, sólo con marcadores de posición.
  2. Los secretos no van en la documentación. Esta documentación es un artefacto compartible: describe el procedimiento, no los valores.
  3. Nada de credenciales en la línea de comandos. Quedan en el historial del shell y en la lista de procesos. Usa un archivo de opciones (ver Volcado remoto).
  4. En local, claves de test. Stripe en modo test; nunca claves sk_live_.
  5. Copias mínimas. Cada copia adicional de un secreto es una superficie de fuga más. Borra los volcados y archivos temporales cuando dejen de hacer falta.
  6. DB_PASSWORD, sólo letras y dígitos. Se interpola tal cual dentro de la URL de conexión, sin codificar, así que un #, /, @, :, ? o % la parte y el backend no arranca — con un error que despista mucho, invalid port number in database URL. Genérala con openssl rand -hex 32; no con -base64, cuyo alfabeto incluye / y +.
  7. Entrecomilla los valores con comillas simples. En un .env, Compose interpreta el símbolo de dólar incluso entre comillas dobles, y una almohadilla precedida de espacio abre un comentario. Las comillas simples evitan ambas cosas.

Comprobar que no se ha filtrado nada​

Antes de hacer commit, comprueba que ningún secreto real ha entrado en archivos versionados:

git grep -nE "sk_live_|BEGIN PRIVATE KEY|password=" -- . ':!*.example'

Y confirma que Git ignora efectivamente el .env:

git check-ignore -v zertipower-zertibuilder/backend/.env

Si el comando no devuelve nada, el archivo no está ignorado: corrígelo antes de seguir.

Rotación​

Si un secreto se expone (se pega en un chat, se sube por error, se comparte en una captura), la única respuesta correcta es rotarlo, no borrar el mensaje. En particular la clave PK y la contraseña de producción.