Saltar al contenido principal

El Impuesto Oculto de Snowflake RBAC: Los Patrones de Permisos que Sí Funcionan

Snowflake RBAC consumió 17–26 horas de ingeniería en los primeros dos meses de nuestro proyecto. Aquí están los patrones de roles — future grants, separación funcional/acceso, aislamiento por desarrollador — que eliminaron la mayor parte.

AC
Arturo Cárdenas
Fundador y Chief Data Analytics & AI Officer
20 de marzo de 2026 · Actualizado 20 de marzo de 2026 · 10 min de lectura
El Impuesto Oculto de Snowflake RBAC: Los Patrones de Permisos que Sí Funcionan

Punto Clave

En un proyecto de analítica de seguridad en la nube de 5 meses, los bloqueos por permisos promediaron varios por semana en los primeros dos meses — 17–26 horas de ingeniería perdidas antes de terminar la migración. Este post desglosa los patrones de jerarquía de roles, configuración de future grants y aislamiento por desarrollador que eliminaron el impuesto recurrente.

Eran las 8pm de un viernes. Nuestro ingeniero de infra acababa de otorgar la tercera ronda de permisos para el role de servicio de dbt.

"Órale, dime cuál es el siguiente error."

Spoiler: sí hubo siguiente error.


La versión corta

Snowflake RBAC es poderoso y doloroso a partes iguales. La "jerarquía de roles simple" que describen los docs se convierte en un ciclo de troubleshooting de varias horas en el momento en que agregas un service account, un pipeline de CI/CD y un equipo de desarrolladores que todos necesitan accesos ligeramente distintos. El costo no está en la arquitectura — el costo está en el tiempo: los loops de error → pídele al admin → espera → reintenta que nadie registra y todos pagan.

Este post habla de ese costo, y de los patrones de roles que eliminan la mayor parte de él.


"Jerarquía de roles simple" dice la documentación

Revisemos esa frase.

La guía oficial de Snowflake muestra un diagrama limpio: SYSADMIN posee objetos, SECURITYADMIN posee roles, USERADMIN administra usuarios, los roles funcionales se acomodan ordenadamente debajo de ellos. Se ve como cuatro cajas y tres flechas. Da la impresión de que es trabajo de una tarde.

Lo que pasa en un proyecto real:

  • Un desarrollador necesita acceso a un schema nuevo → le falta USAGE en la base de datos
  • El role de servicio corre un modelo de dbt → le falta USAGE en el warehouse
  • El pipeline de CI/CD arranca → le falta CREATE TABLE en el schema destino
  • Deployment a producción → le falta MODIFY en el schema al que tiene acceso el role de dev
  • Sigma intenta hacer un query → le falta SELECT en los modelos nuevos que el role de servicio acaba de construir

Cada uno de estos es un ticket separado, un ping de Slack separado, una interrupción separada para quien al que le toca el rol de SECURITYADMIN. En un proyecto de 5 meses migrando una empresa de seguridad en la nube a un stack moderno de analítica (dbt + Snowflake + Sigma), le dimos seguimiento a estas interrupciones. Los bloqueos por permisos promediaron varios por semana en los primeros dos meses.

El impuesto oculto no es ningún incidente individual. Es la sobrecarga acumulada de una estructura de roles que no fue diseñada para cómo trabaja el equipo en la realidad.


Los patrones que sí funcionan

Esto es a lo que llegamos después de suficientes otorgamientos de permisos a altas horas de la noche como para tener opiniones formadas.

Separa los roles funcionales de los roles de acceso

El principio central: nunca otorgues privilegios directamente a usuarios. Otórgaselos a roles, otorga roles a usuarios, y mantén los roles funcionales (lo que la gente hace) separados de los roles de acceso (lo que pueden ver).

-- Access roles: what you can see
CREATE ROLE db_analytics_read;
CREATE ROLE db_analytics_readwrite;

-- Functional roles: who you are
CREATE ROLE developer;
CREATE ROLE analyst;
CREATE ROLE reporter;

-- Wire them together
GRANT ROLE db_analytics_read TO ROLE reporter;
GRANT ROLE db_analytics_readwrite TO ROLE analyst;
GRANT ROLE db_analytics_readwrite TO ROLE developer;

-- Grant privileges to access roles, not to functional roles
GRANT USAGE ON DATABASE analytics TO ROLE db_analytics_read;
GRANT USAGE ON ALL SCHEMAS IN DATABASE analytics TO ROLE db_analytics_read;
GRANT SELECT ON ALL TABLES IN DATABASE analytics TO ROLE db_analytics_read;

Esto te da un solo lugar donde hacer cambios cuando agregas un schema nuevo: el role de acceso. Los roles funcionales no cambian. Los usuarios no cambian.

Los service accounts necesitan su propia jerarquía de roles

El service account de dbt es la fuente más común de fallas a deshoras los viernes. Necesita un conjunto específico y reproducible de privilegios — y esos privilegios deben sobrevivir un cambio de schema, un modelo nuevo, un ambiente nuevo.

-- Create a dedicated service role for dbt
CREATE ROLE dbt_service_role;

-- Warehouse access
GRANT USAGE ON WAREHOUSE transform_wh TO ROLE dbt_service_role;

-- Database + schema access
GRANT USAGE ON DATABASE analytics TO ROLE dbt_service_role;
GRANT USAGE ON DATABASE analytics_dev TO ROLE dbt_service_role;

-- Schema-level create/modify for dbt to build models
GRANT CREATE SCHEMA ON DATABASE analytics_dev TO ROLE dbt_service_role;
GRANT USAGE ON ALL SCHEMAS IN DATABASE analytics TO ROLE dbt_service_role;
GRANT CREATE TABLE ON ALL SCHEMAS IN DATABASE analytics_dev TO ROLE dbt_service_role;
GRANT CREATE VIEW ON ALL SCHEMAS IN DATABASE analytics_dev TO ROLE dbt_service_role;

-- Future grants: this is the one people forget
GRANT SELECT ON FUTURE TABLES IN DATABASE analytics TO ROLE dbt_service_role;
GRANT SELECT ON FUTURE VIEWS IN DATABASE analytics TO ROLE dbt_service_role;

Ese último bloque — GRANT ... ON FUTURE TABLES — es lo que evita que el ciclo de revisión de accesos se repita cada vez que agregas un modelo. Sin future grants, cada tabla o vista nueva que construye tu job de dbt es invisible para los roles que necesitan leerla. Esta es la fuente más común de tickets "¿por qué Sigma no puede ver el modelo nuevo?"

Schemas de desarrollo aislados por desarrollador, seguros para producción

En este proyecto corrimos bases de datos de desarrollo por desarrollador: DBT_DEV__ALICE, DBT_DEV__BOB, y así. Cada desarrollador tenía derechos completos de CREATE TABLE / VIEW / SCHEMA en su propia base de datos y ningún derecho en producción más que SELECT en la capa de staging.

-- Developer role: full rights in dev, read-only in prod staging
CREATE ROLE developer_user;

GRANT USAGE ON DATABASE dbt_dev__user TO ROLE developer_user;
GRANT CREATE SCHEMA ON DATABASE dbt_dev__user TO ROLE developer_user;
GRANT ALL PRIVILEGES ON ALL SCHEMAS IN DATABASE dbt_dev__user TO ROLE developer_user;

-- Read-only in prod staging for reference
GRANT USAGE ON DATABASE analytics TO ROLE developer_user;
GRANT USAGE ON SCHEMA analytics.staging TO ROLE developer_user;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics.staging TO ROLE developer_user;

-- Assign to user
GRANT ROLE developer_user TO USER dev_user;

El aislamiento significa que un dbt run accidental en el target equivocado (algo que previenes en código con un macro validate_dev_target — ver Corriendo dbt Nativamente en Snowflake) golpea tu propia base de datos de dev, no producción. RBAC como segunda capa de seguridad.

Database roles: el comportamiento del bundle 2024_08

Snowflake introdujo los database roles como una forma de limitar los GRANT dentro de una sola base de datos — útil para arquitecturas multi-tenant o cuando quieres permisos de lectura específicos para Sigma sin hacer crecer desmesuradamente la jerarquía de roles de cuenta.

Hay un cambio de comportamiento que vale la pena conocer: el BCR bundle 2024_08 cambió cómo interactúa GRANT ... ON ALL SCHEMAS con los schemas futuros. Si tu cuenta de Snowflake se integró al bundle 2024_08 (o fue inscrita automáticamente), un GRANT que antes cubría schemas nuevos puede ya no hacerlo. Verifica tu cuenta con:

SELECT system$bcr_bundle_status('2024_08');

Si el resultado es ENABLED, audita tus GRANTs ON FUTURE SCHEMAS. El cambio fue sutil y rompió revisiones de acceso para equipos que no sabían dónde buscar.


El query real para troubleshooting

Cuando un role de servicio de dbt no puede acceder a algo, el diagnóstico suele tomar más tiempo que la corrección. Esto lo acelera:

-- What can a role actually do?
SHOW GRANTS TO ROLE dbt_service_role;

-- What roles does a user have?
SHOW GRANTS TO USER service_user;

-- What privileges exist on a specific object?
SHOW GRANTS ON SCHEMA analytics.marts;

-- Who owns what (useful when grants look right but still fail)
SELECT table_schema, table_name, table_owner
FROM information_schema.tables
WHERE table_schema = 'MARTS'
ORDER BY table_name;

El query de table_owner es el que resuelve el caso confuso: una tabla que aparece en SHOW GRANTS pero que sigue lanzando un error de acceso. Si la tabla fue creada por el role incorrecto, el ownership determina lo que el GRANT realmente permite. La corrección es GRANT OWNERSHIP ON TABLE ... TO ROLE dbt_service_role, no otro GRANT SELECT.


El impuesto que ya estás pagando

Pongámosle un número aproximado.

Por ingeniero, un error de permisos que requiere un admin cuesta: ~5 minutos para diagnosticar y reportar, ~15-30 minutos de tiempo de espera para que el admin responda (asumiendo que está disponible), ~5 minutos para verificar y continuar. Digamos 30-40 minutos por incidente.

En este proyecto de 5 meses, los primeros dos meses promediaron dos o tres bloqueos relacionados con permisos por semana entre un equipo de cuatro ingenieros. Eso es aproximadamente 30-45 incidentes solo en la primera fase. A 35 minutos cada uno: 17-26 horas de ingeniería perdidas en gestión de permisos antes de que el equipo hubiera terminado siquiera la migración inicial.

Y eso sin contar el costo del cambio de contexto. Un ingeniero esperando un GRANT de permisos no se queda sin hacer nada — cambia de contexto a otra cosa, y luego vuelve a cambiar cuando llega el GRANT. La investigación sobre recuperación de interrupciones estima el costo de re-enfoque en 15-20 minutos por cambio de contexto. El número real es más alto que el tiempo de espera bruto.

La corrección no es gratuita: configurar una jerarquía de roles limpia con future grants toma medio día dedicado al inicio del proyecto. Pero es una inversión de una sola vez contra un impuesto recurrente. Las matemáticas son obvias en cuanto empiezas a contarlo.


Qué haríamos diferente

Invertir el medio día antes del primer deployment. Pasamos los primeros dos meses pagando el impuesto antes de que la jerarquía de roles estuviera bien. Un sprint de RBAC de 4 horas al inicio del proyecto habría recuperado la mayor parte de ese tiempo en el primer mes.

Documentar la jerarquía de roles como documentas el schema. Eventualmente agregamos una sección de RBAC al CLAUDE.md del proyecto — qué roles existen, quién posee qué, qué cubre el setup de future grants. Cuando una nueva integración (Sigma OAuth, Streamlit, Cortex Analyst) necesitaba acceso, el ingeniero podía autoservirse de la documentación en lugar de pingear al equipo de infra.

Usar la interacción de Okta + políticas de red como input para el diseño de roles. Cuando Okta SSO está en juego — cubierto a fondo en nuestro post sobre el baile de auth entre Okta y Snowflake — las políticas de red interactúan con los GRANTs de roles de formas no obvias. Las IPs de los desarrolladores son dinámicas. Los service accounts necesitan un tratamiento de políticas de red diferente al de los usuarios humanos. Esto es un input de diseño para RBAC, no solo una configuración de seguridad.


Lecciones aprendidas

Los docs de Snowflake RBAC muestran la arquitectura. No te muestran qué pasa cuando un job de dbt corre a las 2am y al role de servicio le falta MODIFY en el schema que se recreó en el último deployment.

El impuesto oculto del RBAC es real, es medible, y se multiplica a lo largo de un proyecto de varios meses. La cura es aburrida y va al frente: roles funcionales, future grants, aislamiento por desarrollador, ownership documentado. Nada de esto es brillante. Todo ahorra los pings del viernes por la noche.

"Dime cuál es el siguiente error" es un chiste gracioso cuando tu ingeniero de infra lo dice a las 8pm. Es menos gracioso cuando es la tercera vez esta semana.

Temas

mejores prácticas Snowflake RBACjerarquía roles Snowflakepermisos dbt service rolefuture grants Snowflakegestión permisos SnowflakeRBAC ingeniería analíticaSnowflake SECURITYADMINcontrol acceso dbt Snowflakeaislamiento desarrollador SnowflakeGRANT FUTURE TABLES Snowflake
Compartir este artículo:
AC

Arturo Cárdenas

Fundador y Chief Data Analytics & AI Officer

Arturo es un consultor senior en analítica e IA que ayuda a empresas medianas y grandes a eliminar el caos de datos para desbloquear claridad, velocidad y ROI medible.

¿Listo para convertir datos en decisiones?

Hablemos de cómo lograr ROI medible en meses.