
kviklet v0.9.0
Flujo de revisión/aprobación tipo Pull Request para consultas de base de datos. Para un acceso de Ingeniería a producción que sea conforme pero fluido.
Kviklet
Kviklet.dev | Notas de la versión | Discord
Acceso seguro a entornos de producción sin mermar la productividad de los desarrolladores.

Kviklet (pronunciado Quick-let) aplica el Principio de las Cuatro Ojos al acceso a bases de datos de producción, con un flujo de trabajo de revisión y aprobación similar a una pull request para sentencias SQL individuales o sesiones de base de datos con tiempo limitado. Los ingenieros pueden revisar y aprobar las solicitudes de los demás sin enrutar cada consulta a través de un DBA o un equipo de operaciones.
Kviklet es autoalojado y se ejecuta como un contenedor Docker con una base de datos PostgreSQL para el estado de la aplicación. Su interfaz web permite enviar, revisar y ejecutar solicitudes. Una licencia empresarial opcional desbloquea la autenticación SAML, los requisitos de revisión basados en roles, la sincronización de roles y las claves de API. Solicite una licencia empresarial en kviklet.dev.
Las bases de datos compatibles son Postgres, MySQL, MariaDB, MS SQL Server y MongoDB.
Modelo de acceso
Recomendamos conectar Kviklet a su proveedor de identidad existente. Kviklet admite SSO a través de OIDC (Google, Keycloak, etc.) o SAML (solo empresarial), así como autenticación LDAP (Active Directory, etc.).
Los usuarios crean entonces solicitudes para conexiones que se asignan a un usuario de base de datos específico. Estas solicitudes son:
- Consulta única: una sentencia SQL específica enviada para su revisión.
- Acceso temporal: una sesión con tiempo limitado en la que puede ejecutar múltiples sentencias.
Según la configuración, las solicitudes son revisadas y aprobadas por otros usuarios antes de que Kviklet permita la ejecución.
Kviklet se conecta a la base de datos en nombre del usuario. La contraseña de la base de datos de la conexión nunca se muestra al usuario.
Un administrador puede configurar qué rol tiene acceso a qué conexión y qué puertas de revisión se requieren para la ejecución. El acceso a nivel de base de datos se gestiona mediante los mecanismos RBAC de la base de datos subyacente. Por ejemplo, es posible crear un rol de solo lectura para una conexión de solo lectura y asignarle menos requisitos de revisión que a una conexión de escritura.
Kviklet registra las sentencias ejecutadas y las asocia con el usuario y la solicitud de acceso. Para una cobertura completa del acceso manual a la base de datos, restrinja las conexiones directas y enrute cualquier acceso manual a través de Kviklet. Los ingenieros no necesitan recibir ni compartir las credenciales subyacentes de la base de datos.
Las características empresariales adicionales incluyen:
- SAML: Compatibilidad con autenticación SAML.
- Proxy (Postgres, MariaDB, MySQL): Utilice su cliente de base de datos preferido a través de una sesión de acceso temporal aprobada con una contraseña temporal. Las sentencias ejecutadas se registran en el registro de auditoría de Kviklet.
- Puertas de revisión basadas en roles: Requerir aprobaciones de roles específicos antes de la ejecución.
- Sincronización de roles: Sincronizar automáticamente los roles de usuario desde los grupos de su proveedor de identidad.
- Claves de API: Acceso programático a la API de Kviklet.
Más capturas de pantalla
Solicitudes
Todas las solicitudes de datos residen en un solo lugar. Como PRs abiertas para sus bases de datos de producción:

Sesiones en vivo
Una solicitud de acceso temporal aprobada abre una sesión SQL en vivo directamente en el navegador:

Registro de auditoría
Cada sentencia ejecutada se registra — ya sea que se ejecutara como una consulta única revisada, en una sesión en vivo o a través del proxy de base de datos:

Características por tipo de base de datos/conexión
La mayoría de las características están disponibles para todas las bases de datos (SSO, LDAP, RBAC, flujo de revisión/aprobación, registro de auditoría, etc.). Pero algunas características están restringidas, ya sea porque simplemente aún no se han implementado o porque no tienen sentido para ese propósito específico. La siguiente tabla muestra qué características están disponibles para qué tipo de base de datos:
| Base de datos | Revisión de sentencias | Acceso temporal | Proxy(Beta) | Plan de ejecución |
|---|---|---|---|---|
| Postgres | ✓ | ✓ | ✓ | ✓ |
| MySQL | ✓ | ✓ | ✓ | ✓ |
| MariaDB | ✓ | ✓ | ✓ | ✓ |
| SQL Server | ✓ | ✓ | ✗ | ✓ |
| MongoDB | ✓ | ✓ | ✗ | ✗ |
| Kubernetes | ✓ | ✗ | ✗ | ✗ |
Configuración
Kviklet se distribuye como un contenedor docker simple.
Puede encontrar las versiones disponibles en Releases. Recomendamos actualizar regularmente la versión que utiliza, ya que seguimos desarrollando nuevas características.
La última actualmente es ghcr.io/kviklet/kviklet:0.8.0, también puede usar :main pero podría ocurrir de vez en cuando que fusionemos accidentalmente algo con errores. Aunque intentamos evitarlo.
Inicio rápido
Si solo quiere probar cómo funciona:
-
Aquí tiene un docker-compose.yaml mínimo:
Haga clic para expandir el contenido del compose
``` services: postgres: image: postgres:16 restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres ports: - "5432:5432" volumes: - ./postgres-data:/var/lib/postgresql/data # - ./sample_data.sql:/docker-entrypoint-initdb.d/init.sqlkviklet-postgres: image: postgres:16 restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: kviklet ports: - "5433:5432" volumes: - ./kviklet-postgres-data:/var/lib/postgresql/data
kviklet: image: ghcr.io/kviklet/kviklet:main ports: - "80:8080" environment: - SPRING_DATASOURCE_URL=jdbc:postgresql://kviklet-postgres:5432/kviklet - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=postgres - INITIAL_USER_EMAIL=[email protected] - INITIAL_USER_PASSWORD=admin depends_on: - kviklet-postgres
-
Ejecuta el
docker-compose.ymlmediantedocker-compose up -d. Kviklet se iniciará en el puerto 80, ve alocalhosty prueba. El inicio de sesión de administrador es [email protected] conadmincomo contraseña. -
El docker-compose contiene una base de datos postgres adicional para la cual puedes configurar una conexión en Kviklet. Para que esta base de datos contenga algunos datos, descomenta esta línea: ``` - ./sample_data.sql:/docker-entrypoint-initdb.d/init.sql
Y crea un archivo sample_data.sql:
Haz clic para expandir el contenido de sample_data.sql
```sql CREATE TABLE Locations ( Name VARCHAR(100) NOT NULL, Address VARCHAR(255) NOT NULL, City VARCHAR(100) NOT NULL, Country VARCHAR(100) NOT NULL, PostalCode VARCHAR(20) NOT NULL );alter table public.Locations owner to postgres;
INSERT INTO public.Locations (Name, Address, City, Country, PostalCode) VALUES ('Central Park', '59th to 110th St', 'New York', 'USA', '10022'), ('Eiffel Tower', 'Champ de Mars, 5 Avenue Anatole', 'Paris', 'France', '75007'), ('Colosseum', 'Piazza del Colosseo, 1', 'Rome', 'Italy', '00184'), ('Sydney Opera House', 'Bennelong Point', 'Sydney', 'Australia', '2000'), ('Great Wall of China', 'Huairou District', 'Beijing', 'China', '101405');
</details>
### Configuración de la base de datos
Kviklet necesita su propia base de datos postgres (o al menos un esquema) para guardar metadatos sobre consultas, conexiones, aprobaciones, etc.
Puedes encontrar su imagen oficial aquí: https://hub.docker.com/_/postgres, o usar una versión alojada en la nube por el proveedor de nube que prefieras.
Al iniciar el contenedor de kviklet, deberás configurar estas tres variables de entorno en consecuencia:```
SPRING_DATASOURCE_PASSWORD = password
SPRING_DATASOURCE_USERNAME = username
SPRING_DATASOURCE_URL = jdbc:postgresql://[host]:[port]/[database]?currentSchema=[schema]
Métodos de autenticación alternativos
- IAM Auth:
Es posible usar AWS IAM Auth para la conexión a la base de datos, en cuyo caso simplemente se omite la contraseña y solo se establece el nombre de usuario.
También hay que establecer la variable de entorno: ```
SPRING_DATASOURCE_IAMAUTH=true
Kviklet cargará las credenciales desde los lugares habituales (variables de entorno, roles de instancia, etc.) y generará un token para la conexión.
- Certificados: También puedes usar certificados para la conexión a la base de datos; consulta aquí un ejemplo.
Usuario inicial
Necesitarás un usuario administrador inicial para fines de configuración. Para ello, establece las 2 variables de entorno:
INITIAL_USER_EMAIL y INITIAL_USER_PASSWORD para que puedas iniciar sesión en la interfaz web. Puedes cambiar la contraseña después a través de la UI.
Ejemplo:```
INITIAL_USER_EMAIL=[email protected]
INITIAL_USER_PASSWORD=someverysecurepassword
Publicamos nuestros contenedores en GitHub packages por ahora, así que con todo esto configurado puedes ejecutar `ghcr.io/kviklet/kviklet:main`, no olvides mapear el puerto `8080`, que es el puerto predeterminado en el que Kviklet se inicia.
Un ejemplo de docker run podría verse así:```
docker run \
-e SPRING_DATASOURCE_PASSWORD=postgres \
-e SPRING_DATASOURCE_USERNAME=postgres \
-e SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/Kviklet \
-e [email protected] \
-e INITIAL_USER_PASSWORD=someverysecurepassword \
--network host \
ghcr.io/kviklet/kviklet:main
SSO mediante OIDC / OAuth2
Si deseas configurar SSO para tu instancia de Kviklet (lo cual tiene mucho sentido, ya que de lo contrario tendrías que gestionar contraseñas nuevamente). Necesitas configurar estas 3 variables de entorno:``` KVIKLET_IDENTITYPROVIDER_CLIENTID KVIKLET_IDENTITYPROVIDER_CLIENTSECRET KVIKLET_IDENTITYPROVIDER_TYPE=google
El client id y secret de Google los puedes obtener fácilmente siguiendo las instrucciones de Google aquí:
https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid
Para los URI de redirección válidos, debes configurar: https://[kviklet_host]/api/login/oauth2/code/google
Para los Orígenes Permitidos, simplemente la URL de tu kviklet alojado.
Después de configurar esas variables de entorno, todos en tu organización podrán iniciar sesión con el botón de iniciar sesión con Google. Pero no tendrán ningún permiso por defecto, tendrás que asignarles un rol después de que inicien sesión una vez.
#### Keycloak
Si quieres configurar SSO con Keycloak en su lugar, necesitas configurar estas 4 variables de entorno:```
KVIKLET_IDENTITYPROVIDER_CLIENTID
KVIKLET_IDENTITYPROVIDER_CLIENTSECRET
KVIKLET_IDENTITYPROVIDER_TYPE=keycloak
KVIKLET_IDENTITYPROVIDER_ISSUERURI=http://[host]:[port]/realms/[realm]
Obtienes el client id y el secret cuando creas una aplicación en Keycloak. Para los URI de redirección válidos, debes configurar: https://[kviklet_host]/api/login/oauth2/code/keycloak Para los Orígenes Permitidos, simplemente tu URL de kviklet alojada.
Después de configurar esas variables de entorno, la página de inicio de sesión debería mostrar un botón Login with Keycloak que redirige a tu instancia de keycloak. En la edición enterprise puedes habilitar la sincronización de roles para sincronizar automáticamente los roles desde tu instancia de keycloak a kviklet. Consulta la sección Role Sync para más detalles.
GitHub (Beta)
Beta: La autenticación con GitHub es nueva y no admite role sync todavía — cada nuevo usuario llega con el rol predeterminado y debe asignársele roles manualmente.
GitHub no cumple con OIDC (es OAuth 2.0 puro), por lo que tiene soporte dedicado en Kviklet. Configura estas variables de entorno:``` KVIKLET_IDENTITYPROVIDER_CLIENTID KVIKLET_IDENTITYPROVIDER_CLIENTSECRET KVIKLET_IDENTITYPROVIDER_TYPE=github KVIKLET_IDENTITYPROVIDER_GITHUB_ALLOWEDORGS=your-org,another-org
Crea una GitHub OAuth App en https://github.com/settings/developers y configura:
- Authorization callback URL: `https://[kviklet_host]/api/login/oauth2/code/github`
- Homepage URL: tu URL de Kviklet alojada
`KVIKLET_IDENTITYPROVIDER_GITHUB_ALLOWEDORGS` es **obligatorio** (Kviklet se niega a iniciarse sin él). Las GitHub OAuth Apps no pueden restringir quién completa el flujo OAuth, por lo que Kviklet llama a `/user/orgs` después de la autenticación y rechaza a los usuarios que no son miembros de al menos una organización en la lista de permitidas (sin distinguir mayúsculas y minúsculas, se comprueban las primeras 100 organizaciones).
Para que la comprobación de organización vea la pertenencia de un usuario, este debe hacer clic en **Grant** (o **Request**) junto a cada organización permitida en la pantalla de consentimiento de OAuth. Si la organización tiene habilitado "Restrict third-party OAuth applications", un propietario de la organización también debe aprobar la aplicación OAuth una vez antes de que la pertenencia de cualquier miembro sea visible.
Kviklet solicita los scopes `read:user`, `user:email` y `read:org`. Los correos electrónicos siempre se leen desde `/user/emails` y solo se acepta una entrada `primary && verified`, por lo que los usuarios con direcciones de correo privadas aún pueden iniciar sesión correctamente.
#### Otros proveedores OIDC
Otros proveedores compatibles con OIDC (GitLab, Auth0, Okta, etc.) deberían funcionar de forma similar a Keycloak. Ten en cuenta que el `redirect URI` cambiará según el tipo que elijas, así que si eliges `gitlab` será `https://[kviklet_host]/api/login/oauth2/code/gitlab`.
Si encuentras problemas, no dudes en crear un issue; no hemos probado todos los proveedores OIDC que existen (todavía) y puede haber ligeras diferencias en la implementación que requieran actualizaciones por parte de Kviklet.
### LDAP
Kviklet admite autenticación LDAP. Para habilitar y configurar LDAP, puedes sobrescribir las siguientes variables de entorno:```
LDAP_ENABLED=true
LDAP_URL=ldap://your-ldap-server:389
LDAP_BASE=dc=your,dc=domain,dc=com
LDAP_PRINCIPAL=cn=admin,dc=your,dc=domain,dc=com
LDAP_PASSWORD=your-admin-password
LDAP_UNIQUE_IDENTIFIER_ATTRIBUTE=uid
LDAP_EMAIL_ATTRIBUTE=mail
LDAP_FULL_NAME_ATTRIBUTE=cn
LDAP_USER_OU=people
LDAP_SEARCH_BASE=ou=people
Esto es lo que significa cada configuración:
LDAP_ENABLED: Establecer entruepara habilitar la autenticación LDAP.LDAP_URL: La URL de tu servidor LDAP.LDAP_BASE: El DN base para las búsquedas LDAP.LDAP_PRINCIPAL: El DN del usuario administrador para enlazarse al servidor LDAP.LDAP_PASSWORD: La contraseña del usuario administrador.LDAP_UNIQUE_IDENTIFIER_ATTRIBUTE: El atributo LDAP utilizado como identificador único para los usuarios (predeterminado: "uid").LDAP_EMAIL_ATTRIBUTE: El atributo LDAP que contiene la dirección de correo electrónico del usuario (predeterminado: "mail").LDAP_FULL_NAME_ATTRIBUTE: El atributo LDAP que contiene el nombre completo del usuario (predeterminado: "cn").LDAP_USER_OU: La Unidad Organizativa (OU) donde se almacenan las cuentas de usuario (predeterminado: "people").LDAP_SEARCH_BASE: Permite sobrescribir el DN base para las búsquedas de usuarios (predeterminado: "ou=people"). Si usas FreeIPA es posible que necesites establecer esto en, por ejemplo,cn=users. Si se establece, LDAP_USER_OU se ignora.
Puedes personalizar estos atributos para que coincidan con tu esquema LDAP. Después de configurar LDAP, los usuarios podrán iniciar sesión utilizando sus credenciales LDAP. La primera vez que un usuario LDAP inicie sesión, se creará una cuenta de usuario correspondiente en Kviklet con permisos predeterminados. Un administrador deberá asignar los roles apropiados a estos usuarios después de su primer inicio de sesión.
SAML (solo Enterprise)
Kviklet admite la autenticación SAML 2.0. Para habilitar SAML, establece las siguientes variables de entorno:``` SAML_ENABLED=true SAML_ENTITYID=https://your-identity-provider.com SAML_SSOSERVICELOCATION=https://your-identity-provider.com/sso SAML_VERIFICATIONCERTIFICATE=-----BEGIN CERTIFICATE-----\nMIICmzCCAYMCBgF4...\n-----END CERTIFICATE-----
Detalles de configuración:
- `SAML_ENABLED`: Establecer en `true` para habilitar la autenticación SAML
- `SAML_ENTITYID`: El ID de entidad de tu proveedor de identidad SAML
- `SAML_SSOSERVICELOCATION`: La URL del servicio SSO de tu proveedor de identidad
- `SAML_VERIFICATIONCERTIFICATE`: El certificado X.509 utilizado para verificar las respuestas SAML (incluye las líneas BEGIN/END CERTIFICATE)
Opcionalmente, puedes personalizar las asignaciones de atributos SAML:```
SAML_USERATTRIBUTES_EMAILATTRIBUTE=email
SAML_USERATTRIBUTES_NAMEATTRIBUTE=name
SAML_USERATTRIBUTES_IDATTRIBUTE=nameID
Tu proveedor de identidad debe configurarse con:
- Entity ID:
https://[kviklet_host]/api/saml2/service-provider-metadata/saml - Redirect Uri:
https://[kviklet_host]/api/login/saml2/sso/saml
Después de configurar SAML, los usuarios pueden iniciar sesión a través del proveedor de identidad. En el primer inicio de sesión, se crea una cuenta de usuario con permisos predeterminados.
Si se te redirige correctamente al IDP pero luego recibes un error de cors, puedes añadir el host de tu IDP a los orígenes permitidos en Kviklet mediante:``` CORS_ALLOWEDORIGINS=https://[idp_host]
## Configuración
### Conexiones
Después de iniciar Kviklet, primero debes configurar una conexión a base de datos. Ve a Settings -> Databases -> Add Connection.


Aquí puedes configurar los requisitos de revisión y los límites de ejecución para cada conexión. Consulta [Review Gates](#review-gates) para más detalles.
#### AWS IAM AUTH
Kviklet admite el uso de IAM Auth para conexiones a bases de datos Postgres, MySQL y MariaDB; para ello, elige IAM Auth al crear una nueva conexión.


Esto eliminará la opción de establecer una contraseña y, en su lugar, usará credenciales de AWS para conectarse a la base de datos.
Kviklet usa el `DefaultCredentialsProvider` de AWS para encontrar credenciales y generar el token para la conexión. Esto significa que todos los lugares típicos deberían funcionar (variables de entorno o roles de instancia asociados); el orden exacto está documentado aquí: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html
Además, puedes proporcionar un ARN de rol de AWS que Kviklet asumirá y usará esas credenciales para crear el token temporal de la base de datos. Esto es particularmente útil para conectarse a bases de datos que no están en la misma cuenta de AWS que Kviklet. Para usar esta función, simplemente introduce el ARN del rol en el campo designado al crear o editar una conexión IAM Auth. Dejar el campo vacío usará el proveedor de credenciales predeterminado (sin asunción de rol).
La región de AWS a usar durante la generación del token se infiere de la URL de tu conexión, por lo que no hay opción para configurarla.
Para aprender cómo configurar IAM Auth para tu base de datos, sigue la documentación oficial de AWS: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
Los dos puntos principales son:
- Crear un usuario de base de datos con la opción de autenticación IAM y los permisos correctos
- Crear una política de IAM que permita a la entidad de AWS generar tokens para este usuario
### Review Gates
Por defecto, Kviklet permite una configuración simple del número de revisiones. Puedes configurar cuántas aprobaciones necesitan las solicitudes en una conexión específica antes de poder ejecutarse.
El estado de aprobación de una solicitud se calcula en función de la última acción de cada revisor. Si un revisor aprueba y luego solicita cambios, solo cuenta la solicitud de cambios: su aprobación anterior se elimina. Editar una solicitud siempre restablece todas las aprobaciones previas, lo que garantiza que ningún cambio pueda ejecutarse sin ser revisado primero. De forma similar, si una ejecución falla (por ejemplo, debido a un error de sintaxis SQL), las aprobaciones se restablecen para que la solicitud pueda corregirse y volver a aprobarse sin tener que crear una nueva.
También puedes configurar un límite de **ejecuciones máximas** por conexión para controlar con qué frecuencia se puede ejecutar una única solicitud aprobada. El valor predeterminado es 1. Establecerlo en 0 permite ejecuciones ilimitadas. Las ejecuciones fallidas no cuentan para este límite.
#### Requisitos de revisión basados en roles (Enterprise)
Con una licencia de Kviklet Enterprise puedes configurar conexiones individuales para que requieran aprobaciones de usuarios con roles específicos. Esto te permite, por ejemplo, exigir la aprobación del equipo que mantiene una base de datos determinada o restringir conexiones sensibles tras aprobaciones de DBA o de la dirección.
**Cómo funciona:**
Cada conexión tiene un recuento de **revisiones totales requeridas** (`numTotalRequired`) que actúa como mínimo: el número mínimo de aprobaciones distintas necesarias independientemente de los roles. Además de eso, puedes añadir **requisitos de rol** que especifiquen cuántas aprobaciones deben provenir de usuarios con un rol concreto (por ejemplo, "1 de DBA, 1 de Security").
Una solicitud solo se aprueba cuando se cumplen **ambas** condiciones:
- El número total de aprobaciones distintas alcanza `numTotalRequired`
- Cada requisito de rol se satisface individualmente
Si un usuario pertenece a varios roles, una sola aprobación de ese usuario cuenta para todos los requisitos de rol coincidentes. Sin embargo, sigue contando solo como una aprobación para el recuento total.
**Ejemplo:** Una conexión requiere 3 aprobaciones totales, incluyendo 1 de un DBA y 1 de Security. Un usuario que tiene tanto el rol DBA como el de Security aprueba: esto satisface ambos requisitos de rol, pero solo cuenta como 1 de las 3 aprobaciones totales necesarias. Todavía se requieren dos aprobaciones más de cualquier usuario.
Si tu licencia enterprise caduca, los requisitos de revisión basados en roles existentes siguen aplicándose, pero ya no se pueden modificar. Solo puedes eliminarlos para volver a la configuración simple de revisiones totales.
### Roles
Kviklet incluye 3 roles: Default, Admins y Developers.
- El rol default proporciona acceso de lectura a todas las conexiones y a las Requests. Este rol se asigna a todos los usuarios y no se puede eliminar. Sin embargo, puedes modificar los permisos de este rol como quieras.
- Los Admins tienen permiso para crear y editar conexiones, así como para añadir nuevos usuarios y establecer sus permisos.
- Los Developers pueden crear Requests, así como aprobarlas y comentarlas y, por supuesto, ejecutar las sentencias reales.
Puedes personalizar los Roles y, por ejemplo, dar a un rol acceso solo a una conexión específica o a un grupo de conexiones de base de datos.
Esto es útil, por ejemplo, si tienes distintos equipos con distintas bases de datos y quieres controlar el acceso a ellas de forma más granular.
#### Crear un nuevo rol
Crear un nuevo rol funciona de la siguiente manera. Ve a Settings -> Roles -> Add Role.


La configuración predeterminada no es muy relevante para la mayoría de los roles y puedes simplemente dar acceso User Read y RoleView y dejarlo así.
Más interesante es añadir permisos individuales para Connections. Aquí primero añades un selector para seleccionar conexiones específicas. Puede ser un id específico o puedes usar comodines con `*` para coincidir con varias conexiones. Por ejemplo, si quieres tener un rol que tenga acceso a todas las bases de datos de desarrollo (en caso de que también gestiones el acceso a ellas con kviklet), usarías un selector como `dev-*` y te asegurarías de que los ids de las conexiones estén configurados correctamente.
Por supuesto, también puedes crear un sistema propio que uses para tus distintos equipos dentro de tu organización.
### Sincronización de roles (Enterprise)
Sincroniza automáticamente los roles de usuario desde los grupos de tu proveedor de identidad. Esta función requiere una licencia enterprise.
La **configuración** se realiza en Settings > Role Sync:
- **Enable Role Sync**: Activa/desactiva la sincronización
- **Sync Mode**:
- **Full Sync** - Los roles de usuario coinciden exactamente con sus asignaciones de grupos del IdP (más el rol predeterminado)
- **Additive** - Los grupos del IdP añaden roles pero no eliminan los existentes
- **First Login Only** - Los roles se sincronizan solo en el primer inicio de sesión; los cambios manuales se conservan después
- **Groups Attribute**: El atributo del IdP que contiene las pertenencias a grupos (predeterminado: `groups`)
- **Role Mappings**: Asigna nombres de grupos del IdP (por ejemplo, `engineering`) a roles de Kviklet
#### Configuración de OIDC
Configura tu proveedor de OIDC para incluir un claim `groups` en el token de ID:
- **Keycloak**:
Keycloak no incluye grupos en los tokens de forma predeterminada, por lo que necesitarás añadir un mapper al cliente.
1. Navega a **Clients** en el menú izquierdo
2. Selecciona tu cliente de Kviklet
3. Ve a la pestaña **Client scopes**
4. Haz clic en el scope dedicado (por ejemplo, `kviklet-dedicated`)
5. Ve a la pestaña **Mappers**
6. Haz clic en **Add mapper** → **By configuration**
7. Selecciona **Group Membership**
8. Configura el mapper:
| Setting | Value |
| ------------------- | -------- |
| Name | `groups` |
| Token Claim Name | `groups` |
| Full group path | **OFF** |
| Add to ID token | **ON** |
| Add to access token | **ON** |
| Add to userinfo | **ON** |
9. Haz clic en **Save**
> **Importante:** El "Token Claim Name" debe coincidir con el "Groups Attribute" configurado en los ajustes de Role Sync de Kviklet (predeterminado: `groups`).
- **Otros proveedores de OIDC**: Añade un mapper/claim de grupos que incluya las pertenencias a grupos del usuario en el token de ID. Esto normalmente se hace en la interfaz de administración del proveedor.
Si tienes problemas, no dudes en crear una issue; no hemos probado todos los proveedores de OIDC que existen (todavía) y puede haber ligeras diferencias en la implementación que requieran actualizaciones por parte de Kviklet.
#### Configuración de LDAP
La sincronización de roles por LDAP usa el atributo `memberOf`:
1. Asegúrate de que tu servidor LDAP tenga habilitado el overlay `memberOf`
2. Establece **Groups Attribute** en `memberOf` en Kviklet
3. Los nombres de los grupos se extraen entonces del atributo `memberOf` en los atributos del usuario.
#### Configuración de SAML
Configura tu IdP SAML para incluir grupos en la aserción:
1. Añade una declaración de atributo que asigne las pertenencias a grupos del usuario
2. Establece el **Groups Attribute** en Kviklet para que coincida con el nombre de tu atributo SAML
3. Los nombres de los grupos se extraen entonces del atributo SAML en los atributos del usuario.
### Notificaciones
Puedes configurar Kviklet para enviar notificaciones a un canal de Slack o Teams. Esto es útil para notificar a tu equipo sobre nuevas solicitudes que necesitan revisión. Puedes configurarlo en Settings -> General -> Notification Settings.
#### Slack
Para configurar las notificaciones de Slack necesitas crear una Slack App y habilitar webhooks para ella. Puedes seguir las instrucciones aquí: https://api.slack.com/messaging/webhooks
#### Teams
Las notificaciones de Teams usan un webhook de **Workflow** de Power Automate. Kviklet envía una Adaptive Card, que la plantilla del webhook publica en tu canal.
**Recomendado: usar la plantilla de workflow**
1. En Teams, abre el canal en el que quieres recibir notificaciones, haz clic en **...** junto al nombre del canal y elige **Workflows** (o añade la aplicación **Workflows**).
2. Busca y crea la plantilla **"Send webhook alerts to a channel"**.
3. Inicia sesión cuando se te solicite, luego selecciona el Team y el Channel de destino y crea el workflow.
4. Abre el paso del trigger y copia la **HTTP POST URL** generada.
5. Pega la URL en Kviklet en Settings -> General -> Notification Settings y haz clic en guardar.
**Alternativa: crear el workflow manualmente**
Si prefieres crear el flujo tú mismo (o la plantilla no está disponible):
1. Canal **...** -> **Workflows** -> crea un flujo con el trigger **"When a Teams webhook request is received"**.
2. Añade la acción **Microsoft Teams -> "Post card in a chat or channel"**.
3. Establece el campo **Adaptive Card** de la acción en la expresión `string(triggerBody())` para que publique la tarjeta que envía Kviklet.
4. Selecciona el Team y el Channel de destino, **Save**, y luego copia la **HTTP POST URL** del paso del trigger.
Actualmente hay notificaciones para:
- Nuevas Requests que necesitan aprobaciones
- Nuevas aprobaciones en solicitudes
#### Configuración de la URL base
Cuando Kviklet se ejecuta detrás de un proxy inverso o un Ingress de Kubernetes, los enlaces de notificación pueden usar la dirección IP interna en lugar de tu dominio público. Kviklet intenta rastrear la URL correcta observando las solicitudes entrantes, pero algunos proxies inversos no establecen correctamente las cabeceras Forwarded. Para solucionarlo, establece la URL base explícitamente:```
KVIKLET_BASE_URL=https://kviklet.example.com
Esto garantiza que todos los enlaces de notificación apunten a la URL pública correcta.
Telemetría
Kviklet informa estadísticas de uso anónimas para ayudarnos a entender qué funciones se utilizan y dónde ocurren errores. Para desactivarlo, configure:``` KVIKLET_TELEMETRY_ENABLED=false
Kviklet registra una línea al iniciar indicando si la telemetría está activada.
**Qué se envía.** Cada evento lleva un id de instancia aleatorio (generado una vez y almacenado en la base de datos de Kviklet), la URL base desde la que se accede a Kviklet (ver arriba; a menudo un nombre de host interno) y la versión de Kviklet. Los usuarios se identifican únicamente mediante un id opaco con alcance a la instancia, por lo que se pueden contar usuarios únicos, pero nunca se envían direcciones de correo electrónico ni nombres. Los eventos exactos y sus propiedades se definen en `backend/src/main/kotlin/dev/kviklet/kviklet/telemetry/TelemetryEvent.kt`.
**Qué nunca se envía.** Consultas, sentencias, resultados, salida de comandos, mensajes de error, nombres de conexión, nombres de host, credenciales, títulos o descripciones de solicitudes, comentarios y nombres de usuario o de rol.
### Registro
Por defecto, Kviklet escribe logs legibles por humanos (pretty) en stdout, lo cual resulta cómodo al leerlos directamente o mediante `docker logs`.
Si envías los logs a un sistema central (Elasticsearch, Loki, Datadog, CloudWatch, …) puedes cambiar a **logs JSON** estructurados, que son más fáciles de indexar y consultar. Configura el formato mediante una variable de entorno:```
# One of: ecs (Elastic Common Schema), logstash, gelf (Graylog)
LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs
Cifrado
Si no quieres que las credenciales se almacenen en texto plano en la base de datos, se recomienda habilitar el cifrado de la base de datos en el propio postgres de Kviklet. Para la mayoría de los proveedores alojados, esto es una simple casilla de verificación que se debe marcar. No obstante, si la base de datos de Kviklet se ve comprometida de alguna manera, esto es un enorme riesgo de seguridad. Ya que contiene las credenciales de la base de datos para potencialmente todos tus almacenes de datos de producción. Así que puedes habilitar el cifrado de las credenciales en reposo.
Para hacer esto, simplemente establece las dos variables de entorno.``` ENCRYPTION_ENABLED=true ENCRYPTION_KEY_CURRENT=some-secret
Kviklet cifrará todas tus credenciales existentes al iniciar, y usará el secreto para futuras conexiones que crees.
### Rotación de claves
Si deseas rotar la clave, simplemente puedes agregar otra variable para la clave anterior y cambiar la actual:```
ENCRYPTION_KEY_PREVIOUS=some-secret
ENCRYPTION_KEY_CURRENT=another-secret
Kviklet volverá a cifrar todas las conexiones al iniciarse, de modo que luego puedas reiniciar el contenedor con la clave anterior eliminada.
Claves de API
Kviklet admite claves de API para el acceso programático al sistema. Esta es una función exclusiva de la versión enterprise y requiere una licencia válida. Puedes crear claves de API en la sección Settings -> API Keys.

Úsalo así:```bash
curl --location '[kviklet_host]/api/connections/'
--header 'Authorization: Bearer your-api-key'
Las claves de API heredan los permisos del usuario que las crea. Actualmente solo los administradores pueden gestionar claves de API y todas las acciones realizadas con una clave de API se atribuyen al usuario que creó la clave.
Puedes encontrar documentación rudimentaria de la API en `[kviklet_host]/api/swagger-ui/index.html`. Pero ten en cuenta que esto es un trabajo en progreso y la API podría cambiar en futuras versiones.
Al final la verdad está en el código, así que siempre puedes consultar el controlador para ver cómo está definida la API. Si tienes alguna pregunta, no dudes en abrir un issue.
## Funcionalidades experimentales
Actualmente hay dos funcionalidades experimentales. Fueron construidas principalmente a partir de los comentarios de la comunidad. No dudes en probarlas y dejar cualquier comentario que puedas tener. Esperamos seguir desarrollándolas en el futuro y hacer que funcionen bien con el flujo de aprobación principal.
### Kubernetes Exec
Si quieres usar la funcionalidad Kubernetes Exec tienes que crear una conexión de kubernetes separada. Kviklet usará el usuario del pod desplegado para ejecutar el comando. Así que asegúrate de que el usuario tenga los permisos necesarios para ejecutar comandos en los pods a los que quieres acceder.
Kviklet también usa /bin/sh para ejecutar el comando, por lo que tendrás que asegurarte de que tus pods tengan un shell o al menos un enlace simbólico en /bin/sh. Si esto te molesta, no dudes en abrir un issue, potencialmente podemos hacer esto configurable o encontrar otra solución.
Los comandos de Kubernetes solo esperan 5 segundos por la salida; si el comando tarda más que eso, Kviklet esperará hasta una hora antes de agotar el tiempo de espera del comando. Esta es una solución provisional, estamos investigando websockets para hacer esto más receptivo y potencialmente habilitar sesiones de terminal.
### Proxy - Postgres, MariaDB, MySQL (Enterprise)
Si creas solicitudes para acceso temporal, puedes - en lugar de usar la interfaz web - ejecutar tus consultas a través de un proxy gestionado por kviklet y usar el cliente de base de datos de tu elección.
El proxy es una funcionalidad enterprise: requiere una licencia válida, y además un administrador tiene que activarlo en Settings -> General -> Database Proxy.
Para esto el contenedor escucha en puertos estables (5432 y 3306 por defecto, configurables mediante `kviklet.proxy.postgres.port` y `kviklet.proxy.mysql.port`), por lo que necesitas exponer esos puertos.
Los usuarios pueden entonces crear una solicitud de acceso temporal, y hacer clic en "Start Proxy" una vez que haya sido aprobada. Cada solicitud obtiene un nombre de usuario y contraseña temporales; Kviklet enruta cada conexión a su solicitud mediante el nombre de usuario. Con estos pueden conectarse a la base de datos. Kviklet valida el usuario y la contraseña temporales y hace proxy de todas las solicitudes al usuario subyacente en la base de datos. Cualquier sentencia ejecutada se registra en el registro de auditoría como si se hubiera ejecutado a través de la interfaz web.
Nota: El proxy actualmente no soporta el seguimiento de resultados. Así que las sentencias ejecutadas se registran pero no los resultados ni si una sentencia tiene éxito o falla.


#### Proxy - TLS
Kviklet termina la conexión TLS hacia la base de datos. Eso significa que por defecto cualquier tráfico desde y hacia el propio proxy no está cifrado.
Si quieres que kviklet recifre el tráfico puedes darle a Kviklet un certificado TLS y una clave para el proxy estableciendo las siguientes variables de entorno:```
PROXY_TLS_CERTIFICATE_SOURCE=env
PROXY_TLS_CERTIFICATE_CERT=your-certificate
PROXY_TLS_CERTIFICATE_KEY=your-key
alternativamente puedes usar archivos:``` PROXY_TLS_CERTIFICATE_SOURCE=file PROXY_TLS_CERTIFICATE_CERT_FILE=path/to/cert.pem PROXY_TLS_CERTIFICATE_KEY_FILE=path/to/key.pem
De cualquier manera, el certificado y la clave deben almacenarse en [formato pem](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail).
## ¿Preguntas? ¿Contribuciones?
Si tienes alguna pregunta, quieres dar tu opinión o necesitas ayuda con la configuración, únete a nuestra [comunidad de Discord](https://discord.gg/7SmPJfeP6e). También puedes crear un [issue en GitHub](https://github.com/kviklet/kviklet/issues) para informar de errores y solicitar nuevas funcionalidades.
Si quieres contribuir, no dudes en hacer un fork y crear PRs para cosas pequeñas. Si planeas funcionalidades más grandes, agradecería algo de discusión previa en un issue de GitHub o en Discord.
También puedes contactarme en [email protected].