La seguridad en MySQL se basa en un sistema de privilegios que controla qué puede hacer cada usuario en el servidor. SHOW GRANTS es el comando que te permite ver exactamente qué privilegios tiene un usuario, desde el acceso global al servidor hasta los permisos sobre tablas y columnas específicas. Es una herramienta esencial para auditar la seguridad, diagnosticar problemas de acceso y verificar que los permisos están correctamente configurados.

Ver los privilegios del usuario actual

La forma más simple de SHOW GRANTS muestra los privilegios del usuario con el que estás conectado:

SHOW GRANTS;
+-------------------------------------------------------------------+
| Grants for admin@localhost                                         |
+-------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO `admin`@`localhost` WITH GRANT OPTION |
+-------------------------------------------------------------------+

La salida es una o más sentencias GRANT que, si se ejecutaran, recrearían exactamente los privilegios del usuario. Esto hace que SHOW GRANTS sea no solo una herramienta de consulta, sino también una forma de documentar y replicar configuraciones de seguridad.

También puedes usar la forma explícita:

SHOW GRANTS FOR CURRENT_USER;

Ver los privilegios de otro usuario

Para ver los privilegios de un usuario específico, usa la cláusula FOR:

SHOW GRANTS FOR 'app_web'@'10.0.1.%';
+--------------------------------------------------------------+
| Grants for app_web@10.0.1.%                                  |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_web`@`10.0.1.%`                  |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `tienda_online`.* TO |
|   `app_web`@`10.0.1.%`                                      |
+--------------------------------------------------------------+

La primera línea (GRANT USAGE ON *.*) indica que el usuario puede conectarse al servidor pero no tiene privilegios globales. La segunda línea muestra que tiene privilegios de lectura y escritura específicamente en la base de datos tienda_online.

Es importante especificar tanto el nombre de usuario como el host, ya que en MySQL un usuario se identifica por la combinación de ambos. 'app_web'@'10.0.1.%' y 'app_web'@'localhost' son usuarios diferentes con privilegios potencialmente distintos.

Interpretar la salida

Los privilegios en MySQL se organizan en niveles jerárquicos. Entender esta jerarquía es clave para interpretar correctamente la salida de SHOW GRANTS.

Nivel global (ON *.*): aplican a todas las bases de datos y tablas del servidor.

SHOW GRANTS FOR 'dba_admin'@'localhost';
+-------------------------------------------------------------------+
| Grants for dba_admin@localhost                                     |
+-------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO `dba_admin`@`localhost`            |
|   WITH GRANT OPTION                                                |
+-------------------------------------------------------------------+

ALL PRIVILEGES significa que tiene todos los privilegios posibles. WITH GRANT OPTION significa que puede otorgar privilegios a otros usuarios.

Nivel de base de datos (ON database.*): aplican a todas las tablas de una base de datos.

SHOW GRANTS FOR 'analista'@'%';
+--------------------------------------------------------------+
| Grants for analista@%                                        |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `analista`@`%`                         |
| GRANT SELECT ON `erp_produccion`.* TO `analista`@`%`         |
| GRANT SELECT ON `analytics`.* TO `analista`@`%`              |
+--------------------------------------------------------------+

Este usuario solo puede leer datos (SELECT) en dos bases de datos específicas. No puede insertar, actualizar ni eliminar registros.

Nivel de tabla (ON database.table): aplican a una tabla específica.

SHOW GRANTS FOR 'api_catalogo'@'%';
+----------------------------------------------------------------------+
| Grants for api_catalogo@%                                             |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `api_catalogo`@`%`                             |
| GRANT SELECT ON `tienda_online`.`productos` TO `api_catalogo`@`%`    |
| GRANT SELECT ON `tienda_online`.`categorias` TO `api_catalogo`@`%`   |
+----------------------------------------------------------------------+

Este usuario solo puede leer dos tablas específicas, lo cual sigue el principio de mínimo privilegio.

Privilegios con roles (MySQL 8.0)

MySQL 8.0 introdujo los roles, que son colecciones nombradas de privilegios que se pueden asignar a usuarios. SHOW GRANTS muestra los roles asignados:

SHOW GRANTS FOR 'dev_maria'@'%';
+------------------------------------------------------------+
| Grants for dev_maria@%                                      |
+------------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev_maria`@`%`                      |
| GRANT `rol_lectura`@`%`, `rol_reportes`@`%` TO             |
|   `dev_maria`@`%`                                          |
+------------------------------------------------------------+

Para ver qué privilegios incluye cada rol:

SHOW GRANTS FOR 'rol_lectura'@'%';
+--------------------------------------------------------------+
| Grants for rol_lectura@%                                      |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rol_lectura`@`%`                      |
| GRANT SELECT ON `erp_produccion`.* TO `rol_lectura`@`%`      |
| GRANT SELECT ON `tienda_online`.* TO `rol_lectura`@`%`       |
+--------------------------------------------------------------+

Para ver los privilegios efectivos de un usuario incluyendo los que hereda de sus roles, usa la cláusula USING:

SHOW GRANTS FOR 'dev_maria'@'%' USING 'rol_lectura'@'%', 'rol_reportes'@'%';

Esto expande los roles y muestra todos los privilegios reales que el usuario tiene disponibles.

Caso práctico: auditoría de seguridad

Antes de una auditoría, necesitas generar un informe completo de todos los usuarios y sus privilegios. Puedes obtener la lista de usuarios del servidor:

SELECT
  User,
  Host,
  account_locked AS bloqueado,
  password_expired AS pwd_expirada,
  password_last_changed AS ultimo_cambio_pwd
FROM mysql.user
WHERE User NOT IN ('mysql.sys', 'mysql.session',
                   'mysql.infoschema', 'root')
ORDER BY User;
UserHostbloqueadopwd_expiradaultimo_cambio_pwd
analista%NN2025-01-15 10:30:00
api_catalogo%NN2025-02-01 14:00:00
app_web10.0.1.%NN2025-03-01 09:00:00
dba_adminlocalhostNN2025-03-10 08:00:00
etl_usr10.0.1.8NN2024-12-20 16:00:00

Luego, para cada usuario, generas los privilegios:

-- Generar un script de SHOW GRANTS para todos los usuarios
SELECT
  CONCAT('SHOW GRANTS FOR ''', User, '''@''', Host, ''';')
    AS comando
FROM mysql.user
WHERE User NOT LIKE 'mysql.%'
  AND User != 'root'
ORDER BY User;
comando
SHOW GRANTS FOR 'analista'@'%';
SHOW GRANTS FOR 'api_catalogo'@'%';
SHOW GRANTS FOR 'app_web'@'10.0.1.%';
SHOW GRANTS FOR 'dba_admin'@'localhost';
SHOW GRANTS FOR 'etl_usr'@'10.0.1.8';

Ejecutar estos comandos te da el mapa completo de permisos del servidor. Los hallazgos típicos de una auditoría incluyen usuarios con privilegios excesivos (ALL PRIVILEGES cuando solo necesitan SELECT), usuarios con host % que deberían estar restringidos a IPs específicas, y contraseñas que no se han cambiado en mucho tiempo.

Caso práctico: diagnosticar un problema de acceso

Cuando un usuario reporta que no puede acceder a una tabla, SHOW GRANTS es tu primera herramienta de diagnóstico:

SHOW GRANTS FOR 'app_web'@'10.0.1.%';
+--------------------------------------------------------------+
| Grants for app_web@10.0.1.%                                  |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_web`@`10.0.1.%`                  |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `tienda_online`.* TO |
|   `app_web`@`10.0.1.%`                                      |
+--------------------------------------------------------------+

Si el usuario intenta ejecutar CREATE TABLE en tienda_online, fallará porque solo tiene SELECT, INSERT, UPDATE y DELETE. La solución depende de si realmente necesita ese privilegio:

-- Si necesita crear tablas
GRANT CREATE ON tienda_online.* TO 'app_web'@'10.0.1.%';
FLUSH PRIVILEGES;
 
-- Verificar
SHOW GRANTS FOR 'app_web'@'10.0.1.%';
+-----------------------------------------------------------------------+
| Grants for app_web@10.0.1.%                                           |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_web`@`10.0.1.%`                           |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `tienda_online`.* TO  |
|   `app_web`@`10.0.1.%`                                               |
+-----------------------------------------------------------------------+

Otro problema frecuente es cuando la conexión viene de un host diferente al esperado. Si el usuario se conecta desde 10.0.1.20 pero solo tiene privilegios para localhost, el acceso será denegado incluso si la contraseña es correcta. SHOW GRANTS junto con el análisis del host de conexión te lleva a la raíz del problema.

SHOW GRANTS es una herramienta indispensable para mantener la seguridad y resolver problemas de acceso en MySQL. Dominar su uso te permite verificar rápidamente que cada usuario tiene exactamente los privilegios que necesita, ni más ni menos. En la siguiente sección veremos la gestión de usuarios, donde aprenderemos a crear, modificar y eliminar las cuentas que acabamos de auditar.

Escrito por Eduardo Lázaro