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
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 tú.
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
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
¿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 secretcoloca tus credenciales fuera de la imagen del repo.- Ambos modos llegan realmente al contenedor: interpolación de env y
/run/secrets. getdevuelve 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.