Credenciales de nube
Los connectors de AWS y GCP necesitan credenciales de nube para leer. Hay dos modos, y son ortogonales al secret store: aquel decide dónde viven los secretos, este decide cómo se resuelven las credenciales de nube.
RUNNER_AWS_CRED_MODE=static # defaultRUNNER_AWS_CRED_MODE=chain
RUNNER_GCP_CRED_MODE=static # defaultRUNNER_GCP_CRED_MODE=chainstatic: el modo por defecto
Sección titulada «static: el modo por defecto»Lee AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY y, opcionalmente, AWS_SESSION_TOKEN del secret
store y los inyecta explícitamente en el cliente.
Sirve a quien recibe claves ya hechas o las guarda en Vault o en Secrets Manager. Es el modo por defecto por retrocompatibilidad.
chain: workload identity
Sección titulada «chain: workload identity»No inyecta ninguna clave. La resuelve la cadena de credenciales por defecto del SDK: IRSA en EKS, task role en ECS, instance profile en EC2, variables de entorno o la caché de SSO.
Es el modo correcto cuando el runner corre dentro de AWS, y es lo que mantiene las claves estáticas fuera de circulación.
RUNNER_AWS_CRED_MODE=chainAWS_PROFILE=my-profile # in development, with aws sso loginUna sutileza que provoca un connector invisible
Sección titulada «Una sutileza que provoca un connector invisible»El served set es secret-aware: un connector al que le faltan las claves obligatorias sale del conjunto
anunciado. Pero en el modo chain la credencial no viene del secret store, así que, sin un
tratamiento especial, el runner no anunciaría las operaciones aws.* aunque funcionaran perfectamente.
Por eso el runtime marca el connector aws como siempre servido en el modo chain. Vale la pena
saber que existe este caso especial, para que la diferencia de comportamiento entre los dos modos no te
sorprenda.
Varias cuentas
Sección titulada «Varias cuentas»El modo chain es de una sola cuenta por construcción. Para varias cuentas de AWS, ejecuta un
runner por cuenta, cada uno con su propia identidad IRSA. El grafo se fusiona del lado del
control-plane.
Contexto derivado en el boot
Sección titulada «Contexto derivado en el boot»Con RUNNER_CONNECTORS=real, el runner hace un sondeo best-effort de STS en el boot para descubrir
la cuenta y la región, y lo reporta en el handshake. Es lo que permite al control-plane resolver el
contexto de AWS del tenant a partir del runner vivo, en lugar de configuración manual.
El sondeo nunca lanza excepciones. Si falla, la información simplemente no se envía, y el control-plane usa su fallback.
El diseño es el hermano exacto del lado de AWS.
static: el modo por defecto
Sección titulada «static: el modo por defecto»Lee la clave JSON de la service account (GCP_SA_KEY, el JSON en una sola línea) del secret store y
construye los clientes con ella.
chain: Application Default Credentials
Sección titulada «chain: Application Default Credentials»No inyecta ninguna clave. La resuelve ADC: Workload Identity en GKE, metadata en GCE, el archivo al
que apunta GOOGLE_APPLICATION_CREDENTIALS, o gcloud.
Con chain, no hace falta GCP_SA_KEY.
RUNNER_GCP_CRED_MODE=chainGCP_PROJECT_ID=my-projectTambién es de un solo proyecto: para varios proyectos, un runner por proyecto, cada uno con su propia GSA de Workload Identity.
Magalu Cloud
Sección titulada «Magalu Cloud»Aquí el diseño no es hermano de los otros dos, y la diferencia es de postura, no de conveniencia.
MGC se autentica con una API key (header X-API-Key). No hay un análogo de cadena de credenciales
(nada equivalente a IRSA en AWS o a Workload Identity en GCP), así que no existe
RUNNER_MGC_CRED_MODE: solo la clave estática, leída del secret manager del cliente. Inventar un modo
que no existe sería peor que la ausencia.
MGC_API_KEY=…MGC_REGION=br-se1 # optional; the region lives in the URL, one runner serves one regionMGC_TENANT_ID=… # optional; saves one call at bootMGC_S3_ACCESS_KEY=… # object storage; the `key_pair_id` of the SAME keyMGC_S3_SECRET_KEY=… # object storage; the `key_pair_secret` of the SAME keyLos alcances son el control, y son inmutables
Sección titulada «Los alcances son el control, y son inmutables»Una API key de MGC lleva tres componentes: api_key (lo que WhyStack envía en el header
X-API-Key), key_pair_id y key_pair_secret, que juntos son la credencial S3 de Object Storage
y se convierten en los MGC_S3_ACCESS_KEY/MGC_S3_SECRET_KEY de arriba.
Crear la clave desde la consola con “todo” marcado genera unos 160 alcances sobre toda la cuenta,
billing e IAM incluidos. Créala desde la CLI con --scopes explícitos y concede acceso de solo
lectura, un alcance de lectura por cada producto que WhyStack va a leer:
| Producto | Qué se lee |
|---|---|
Virtual machine (virtual-machine.read) |
instancias y sus IPs |
Network (network.read) |
VPCs, subnets, security groups, IPs públicas, NAT, load balancers |
Object storage (object-storage.read) |
buckets y postura de exposición |
| Block storage | volúmenes, asociación y cifrado |
| DBaaS | instancias, clústeres y réplicas de bases de datos |
| Kubernetes (MKE) | clústeres, node pools y quién puede alcanzar el API server |
| Container registry | registries, repositorios e imágenes |
| Auditoría | quién hizo qué, cuándo y sobre qué recurso |
Los identificadores de los cuatro últimos salen de la propia lista de alcances de la consola/CLI. No los
adivines a partir de los tres primeros. Una clave sin el alcance de un producto no rompe WhyStack:
solo las lecturas de ese producto vuelven con auth_error, y el resto del connector sigue sirviendo. En
la práctica, el producto simplemente se vuelve invisible sin hacer ruido, así que vale la pena comparar la
tabla de arriba con lo que esperas ver.
Eso es mejor de lo que parece: la postura de solo lectura de WhyStack pasa a estar aplicada en la credencial, no solo en el código. El connector rechaza escrituras, y la clave ni siquiera las permite. Los alcances no se pueden editar después: si la necesidad cambia, vuelve a crear la clave.
Contexto derivado en el boot
Sección titulada «Contexto derivado en el boot»El análogo de “cuenta” en MGC es el tenant_id, que aparece en VPCs, security groups e IPs
públicas. No existe “proyecto”.
A diferencia de GCP, no sale gratis: la API key es opaca, y no hay metadata server de workload identity.
Por eso el runner usa MGC_TENANT_ID cuando está definido y, si no, lo deriva de un listado de VPCs
(best-effort). Sin clave, sin VPC o con la llamada fallando, no se anuncia ninguna cuenta y el
control-plane recurre a la configuración. Nunca inventa un id: anunciar una cuenta inexistente enviaría
lecturas a un lugar que no responde.
Variables relacionadas
Sección titulada «Variables relacionadas»| Variable | Notas |
|---|---|
AWS_REGION |
La usan los connectors de AWS y es obligatoria para la atestación aws-sts. |
MGC_API_KEY |
API key de Magalu Cloud. Créala con alcances de lectura, uno por cada producto que WhyStack va a leer (ver la tabla de arriba). |
MGC_REGION |
br-se1 (por defecto) o br-ne1. Vive en la URL: un runner atiende una región. |
MGC_TENANT_ID |
Evita la llamada de descubrimiento en el boot. Recomendado en producción. |
MGC_S3_ACCESS_KEY |
El key_pair_id de la misma API key. Object storage habla S3 (SigV4) contra otro host: otra credencial, mismo dueño. Opcional: sin ella, los buckets quedan invisibles, sin error en el boot. |
MGC_S3_SECRET_KEY |
El key_pair_secret de la misma API key. Lo que autoriza las lecturas de buckets es el alcance object-storage.read de MGC_API_KEY, no este par. |
EKS_CLUSTER |
Sin ella, el health check de EKS responde skipped: no cluster configured. El connector aparece como no configurado en la Flota, que es distinto de roto e igual de ciego. |
GCP_PROJECT_ID |
Proyecto de destino. |
GCP_REGION |
Región de destino. |
GCP_BILLING_EXPORT_TABLE |
Tabla de billing export de BigQuery. Sin ella, la operación de costos de GCP falla de forma explícita. |