Saltar al contenido principal Saltar a navegación Saltar al pie de página
Tiempo limitado: Programa Design Partner. Plan BUSINESS gratis de por vida.

Gestión de Secrets

Coloca las credenciales de despliegue en un lugar al que los forks no pueden acceder. Solo escritura por diseño.

Gestión de Secrets

Esto es lo importante sobre los forks: son copias byte a byte de la imagen cifrada, credenciales incluidas. Una clave live de Stripe, una contraseña de base de datos, un token de API en el repo? El fork los hereda. Tu sandbox termina cobrando a clientes reales.

El lugar correcto es rdc repo secret. Dos modos de entrega, solo escritura por diseño, y el fork parte sin nada. En este tutorial configuramos ambos tipos, desplegamos una app que los consume, probamos que los valores llegan de verdad al contenedor y luego vemos cómo un fork no puede arrancar porque los secrets se negaron a seguirlo.

Ver el tutorial

La trampa: .env en el repo

Un archivo .env dentro de la imagen del repo es clonado por cada fork

La mayoría de los equipos ponen .env en el repo. Es el movimiento obvio.

Luego hacen un fork.

El fork es una copia byte a byte de la imagen del padre. Lo que esté en .env también está en el .env del fork. Los contenedores del fork arrancan. Leen la misma clave de Stripe. Llaman a la misma API de Stripe con credenciales de producción. Desde el lado de Stripe, esa llamada eres .

Ese es un mal día. Sé de qué hablo.

Paso 1: Establecer un secret en modo env

rdc repo secret set --name my-app --key DB_HOST --value postgres.internal --mode env

Primero, establece un secreto en modo env. El valor llega como una variable de entorno dentro del container. Las primeras escrituras no requieren ningún trámite, es sobrescribir un secreto existente lo que requiere verificación.

--mode env hace que el valor llegue como variable de entorno dentro del contenedor. Las primeras escrituras no requieren ningún trámite; es sobreescribir un secret existente lo que exige demostrar el valor actual.

Paso 2: Establecer un secret en modo file

rdc repo secret set --name my-app --key STRIPE_KEY --value sk_test_xxx --mode file

Ahora establece un secreto en modo file. El modo file nunca expone el valor a través del entorno del container; escribe el valor en un archivo bajo /run/secrets usando el mecanismo estándar de secretos de Docker. Prefiere el modo file para cualquier cosa sensible.

El modo file nunca pone el valor en el entorno del contenedor. Lo escribe en /run/secrets/stripe_key usando el mecanismo estándar de Docker. Prefiere esto para cualquier cosa sensible.

Paso 3: Listar lo que tienes

rdc repo secret list --name my-app

Listemos lo que tenemos. Solo nombres y modos. La lista nunca muestra valores, sin importar quién pregunte.

Ves nombres y modos. Sin valores. La lista nunca muestra valores, sin importar quién pregunte.

Conéctalo al compose

Abre docker-compose.yml. Referencia ambos modos:

services:
  api:
    image: myapp:latest
    environment:
      DATABASE_HOST: ${REDIACC_SECRET_DB_HOST}
    secrets:
      - stripe_key

secrets:
  stripe_key:
    file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_KEY

${REDIACC_SECRET_DB_HOST} es el modo env: el wrapper de compose de renet lo expande desde tu almacén de secrets al momento del despliegue.

El bloque secrets: es el modo file, usando el mecanismo estándar de Docker. La ruta del host usa ${REDIACC_NETWORK_ID} para que el mismo compose funcione tanto para repos padre como para forks. Cada fork tiene su propio network ID.

Nunca puedes leerlo de vuelta

Modelo solo-escritura: get devuelve un digest, nunca el valor

Aquí está la parte que sorprende a la gente la primera vez, a mí incluido.

Paso 4: Get devuelve un digest

rdc repo secret get --name my-app --key STRIPE_KEY

El comando secret get devuelve un digest, no el valor, y no existe ningún flag para recuperar el texto plano. Esto sigue el modelo de GitHub Actions: los secretos son de solo escritura por diseño.

Obtienes un digest. No el valor. No hay ningún flag que haga que devuelva el valor. No existe ningún comando en ningún lado que te dé el texto en claro.

Ese es el modelo de GitHub Actions: solo escritura. Puedes demostrar que conoces un secret pasando --current <valor> y viendo que la precondición se cumple. No puedes pedirle a Rediacc que te diga cuál es.

Paso 5: Rota cuando olvidas

¿Perdiste el valor? No intentes leerlo. Rótalo.

rdc repo secret set --name my-app --key STRIPE_KEY --value sk_test_new --mode file --rotate-secret

Si pierdes el rastro del valor de un secreto, rótalo en lugar de intentar recuperarlo. El flag rotate-secret omite la verificación de precondición y el registro de auditoría registra el cambio como una rotación deliberada.

--rotate-secret omite la precondición. El log de auditoría lo marca como una rotación: explícito, deliberado.

Si recuerdas el valor anterior, demuéstralo en cambio con --current <old-value>. Ese es el camino más seguro. Más de una vez me ha salvado cuando estaba en la terminal o máquina equivocada.

Despliega y comprueba la entrega

Los secrets que nunca llegan a la app son solo una base de datos elegante. Despliega y comprueba ambas rutas de entrega.

Paso 6: Desplegar con ambos secrets

rdc repo up --name my-app --machine <machine-name>

Despliega el repo. El archivo compose consume ambos secretos: el valor env mediante interpolación, el valor file mediante un montaje de secretos de Docker.

Paso 7: El secret env llega

rdc term connect --machine <machine-name> --repository my-app --command 'docker exec app printenv DB_HOST'

Imprime la variable dentro del container: postgres.internal. El secreto en modo env llegó a la app en el momento del despliegue.

El contenedor imprime postgres.internal. La app recibió el valor de verdad, expandido en su entorno al momento del despliegue.

Paso 8: El secret file llega

rdc term connect --machine <machine-name> --repository my-app --command 'docker exec app cat /run/secrets/stripe_key'

Lee /run/secrets/stripe_key dentro del container: el valor rotado está montado allí. La app obtiene el texto plano; solo la CLI se niega a mostrarlo.

Y ahí está el valor rotado, leído desde /run/secrets/stripe_key dentro del contenedor. Solo escritura aplica a las personas y al CLI; tu app obtiene el texto en claro real donde Docker lo promete.

El remate del fork

Después del fork, la lista de secrets está vacía

¿Recuerdas la trampa? Haz fork del repo y mira.

Paso 9: Hacer fork del repo

rdc repo fork --parent my-app --tag test --machine <machine-name>

Haz un fork del repo. El fork es una copia byte a byte de la imagen cifrada del padre.

Paso 10: El fork lista vacío

rdc repo secret list --name my-app:test

Listar los secretos del fork devuelve un conjunto vacío: sin clave Stripe, sin contraseña de base de datos, sin token de API. El fork no puede hacerse pasar por el padre, que es lo que hace que clonar producción sea seguro.

Vacío.

El fork no tiene clave de Stripe. Sin contraseña de base de datos. Sin token de API. Los contenedores del fork no pueden interpolar ${REDIACC_SECRET_STRIPE_KEY}. El archivo en /var/run/rediacc/secrets/<fork-id>/STRIPE_KEY no existe.

El fork no puede hacerse pasar por ti.

Paso 11: El fork ni siquiera puede arrancar

rdc repo up --name my-app:test --machine <machine-name>

Iniciar el fork con el compose del padre falla: el archivo de secreto no existe bajo el ID de red del fork, por lo que Docker rechaza el montaje bind. Las credenciales de producción nunca siguen a un fork.

El despliegue falla a propósito: bind source path does not exist: /var/run/rediacc/secrets/<fork-id>/STRIPE_KEY. El archivo de secret vive bajo el network ID del padre, no del fork, así que Docker rechaza el montaje. El fallo es la demo: las credenciales de producción nunca siguen a un fork, ni siquiera por accidente.

Si quieres secrets en el fork para pruebas, configúralos explícitamente en el fork con valores de sandbox, por ejemplo rdc repo secret set --name my-app:test --key STRIPE_KEY --value sk_sandbox_yyy --mode file. Ahora el fork habla con el sandbox de Stripe y arranca limpiamente. Las credenciales de producción nunca salieron de producción.

Resumen

  • rdc repo secret coloca tus credenciales fuera de la imagen del repo.
  • Ambos modos llegan realmente al contenedor: interpolación de env y /run/secrets.
  • get devuelve un digest, nunca el valor. Rota cuando olvidas; no intentes leerlo.
  • El fork lista vacío y ni siquiera puede arrancar el compose del padre.

Secrets que el fork no puede seguir.


Siguiente: Backup y restauración.