
kviklet v0.9.0
Процесс рецензирования/утверждения запросов к базе данных по аналогии с Pull Request. Для соответствующего требованиям, но при этом беспрепятственного доступа инженеров к продакшену.
Kviklet
Kviklet.dev | Release Notes | Discord
Безопасный доступ к production-средам без ущерба для продуктивности разработчиков.

Kviklet (произносится «Квиклет») применяет принцип четырёх глаз к доступу к production-базам данных, с рабочим процессом проверки и утверждения, похожим на pull request, для отдельных SQL-запросов или сессий доступа к базе данных с ограничением по времени. Инженеры могут проверять и утверждать запросы друг друга, не направляя каждый запрос через DBA или команду эксплуатации.
Kviklet разворачивается самостоятельно и работает как Docker-контейнер с базой данных PostgreSQL для хранения состояния приложения. Его веб-интерфейс позволяет отправлять, проверять и выполнять запросы. Опциональная корпоративная лицензия открывает аутентификацию SAML, требования к проверке на основе ролей, синхронизацию ролей и API-ключи. Запросить корпоративную лицензию можно на kviklet.dev.
Поддерживаемые базы данных: Postgres, MySQL, MariaDB, MS SQL Server и MongoDB.
Модель доступа
Мы рекомендуем подключить Kviklet к вашему существующему провайдеру идентификации. Kviklet поддерживает SSO через OIDC (Google, Keycloak и т. д.) или SAML (только для корпоративной версии), а также аутентификацию LDAP (Active Directory и т. д.).
Затем пользователи создают запросы для подключений, которые сопоставлены с конкретным пользователем базы данных. Эти запросы бывают двух типов:
- Одиночный запрос: конкретный SQL-запрос, отправленный на проверку.
- Временный доступ: сессия с ограничением по времени, в рамках которой можно выполнить несколько запросов.
В зависимости от конфигурации запросы проверяются и утверждаются другими пользователями, прежде чем Kviklet разрешит выполнение.
Kviklet подключается к базе данных от имени пользователя. Пароль подключения к базе данных никогда не показывается пользователю.
Администратор может настроить, какая роль имеет доступ к какому подключению и какие этапы проверки требуются для выполнения. Доступ на уровне базы данных управляется через механизмы RBAC самой базы данных. Например, можно создать роль только для чтения для подключения только для чтения и назначить для него меньше требований к проверке, чем для подключения с записью.
Kviklet записывает выполненные запросы и связывает их с пользователем и запросом на доступ. Для полного охвата ручного доступа к базе данных ограничьте прямые подключения и направьте любой ручной доступ через Kviklet. Инженерам не нужно получать или передавать учётные данные базовой базы данных.
Дополнительные корпоративные функции включают:
- SAML: Поддержка аутентификации SAML.
- Прокси (Postgres, MariaDB, MySQL): Используйте предпочитаемый клиент базы данных через утверждённую сессию временного доступа с временным паролем. Выполненные запросы записываются в журнал аудита Kviklet.
- Этапы проверки на основе ролей: Требовать утверждения от определённых ролей перед выполнением.
- Синхронизация ролей: Автоматическая синхронизация ролей пользователей из групп вашего провайдера идентификации.
- API-ключи: Программный доступ к API Kviklet.
Больше скриншотов
Запросы
Все запросы на доступ к данным находятся в одном месте. Как открытые PR для ваших production-баз данных:

Живые сессии
Утверждённый запрос на временный доступ открывает живую SQL-сессию прямо в браузере:

Журнал аудита
Каждый выполненный запрос записывается — независимо от того, был ли он выполнен как проверенный одиночный запрос, в живой сессии или через прокси базы данных:

Функции по типу базы данных/подключения
Большинство функций доступны для всех баз данных (SSO, LDAP, RBAC, процесс проверки/утверждения, журнал аудита и т. д.). Но некоторые функции ограничены — либо потому, что они ещё просто не реализованы, либо потому, что они не имеют смысла для конкретного назначения. Следующая таблица показывает, какие функции доступны для какого типа базы данных:
| База данных | Проверка запросов | Временный доступ | Прокси (Beta) | План выполнения |
|---|---|---|---|---|
| Postgres | ✓ | ✓ | ✓ | ✓ |
| MySQL | ✓ | ✓ | ✓ | ✓ |
| MariaDB | ✓ | ✓ | ✓ | ✓ |
| SQL Server | ✓ | ✓ | ✗ | ✓ |
| MongoDB | ✓ | ✓ | ✗ | ✗ |
| Kubernetes | ✓ | ✗ | ✗ | ✗ |
Установка
Kviklet поставляется как простой docker-контейнер.
Доступные версии можно найти в разделе Releases. Мы рекомендуем регулярно обновлять используемую версию, так как мы продолжаем добавлять новые функции.
Последняя на данный момент — ghcr.io/kviklet/kviklet:0.8.0, также можно использовать :main, но иногда может случиться, что мы случайно смёржим что-то с багами. Хотя мы стараемся этого избегать.
Быстрый старт
Если вы просто хотите попробовать, как это работает:
-
Вот минимальный docker-compose.yaml:
Нажмите, чтобы развернуть содержимое 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
-
Запустите
docker-compose.ymlчерезdocker-compose up -d. Kviklet запустится на порту 80, перейдите наlocalhostи попробуйте. Логин администратора — [email protected] с паролемadmin. -
В docker-compose есть дополнительная база данных postgres, для которой вы можете настроить подключение в Kviklet. Чтобы наполнить эту базу данных данными, раскомментируйте эту строку: ``` - ./sample_data.sql:/docker-entrypoint-initdb.d/init.sql
И создайте файл sample_data.sql:
Нажмите, чтобы развернуть содержимое 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>
### Настройка базы данных
Kviklet нуждается в собственной базе данных postgres (или как минимум схеме) для хранения метаданных о запросах, подключениях, одобрениях и т. д.
Официальный образ можно найти здесь: https://hub.docker.com/_/postgres, или использовать облачную версию, предоставляемую вашим облачным провайдером.
При запуске контейнера kviklet вам нужно будет соответствующим образом задать эти три переменные окружения:```
SPRING_DATASOURCE_PASSWORD = password
SPRING_DATASOURCE_USERNAME = username
SPRING_DATASOURCE_URL = jdbc:postgresql://[host]:[port]/[database]?currentSchema=[schema]
Альтернативные методы аутентификации
- IAM Auth:
Можно использовать AWS IAM Auth для подключения к базе данных, в этом случае вы просто опускаете пароль и указываете только имя пользователя.
Также необходимо задать переменную окружения: ```
SPRING_DATASOURCE_IAMAUTH=true
Kviklet загрузит учётные данные из обычных мест (переменные окружения, роли экземпляра и т. д.) и сгенерирует токен для подключения.
- Сертификаты: Вы также можете использовать сертификаты для подключения к базе данных, см. здесь пример.
Начальный пользователь
Вам понадобится начальный пользователь-администратор для целей настройки. Для этого задайте 2 переменные окружения:
INITIAL_USER_EMAIL и INITIAL_USER_PASSWORD, чтобы вы могли войти в веб-интерфейс. Вы можете изменить пароль позже через UI.
Пример:```
INITIAL_USER_EMAIL=[email protected]
INITIAL_USER_PASSWORD=someverysecurepassword
Мы публикуем наши контейнеры в GitHub packages на данный момент, так что со всеми этими настройками вы можете запустить `ghcr.io/kviklet/kviklet:main`, не забудьте сопоставить порт `8080`, который является портом по умолчанию, на котором запускается Kviklet.
Пример запуска docker может выглядеть так:```
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 через OIDC / OAuth2
Если вы хотите настроить SSO для вашего экземпляра Kviklet (что имеет большой смысл, поскольку иначе вам снова придётся управлять паролями). Вам нужно настроить эти 3 переменные окружения:``` KVIKLET_IDENTITYPROVIDER_CLIENTID KVIKLET_IDENTITYPROVIDER_CLIENTSECRET KVIKLET_IDENTITYPROVIDER_TYPE=google
Google client id и secret можно легко получить, следуя инструкциям Google здесь:
https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid
Для допустимых redirect URI следует настроить: https://[kviklet_host]/api/login/oauth2/code/google
Для Allowed Origins — просто URL вашего размещённого kviklet.
После настройки этих переменных окружения все в вашей организации смогут войти с помощью кнопки sign in with google. Но по умолчанию у них не будет никаких разрешений — вам нужно будет назначить им роль после того, как они войдут один раз.
#### Keycloak
Если вы хотите настроить SSO с Keycloak вместо этого, вам нужно задать эти 4 переменные окружения:```
KVIKLET_IDENTITYPROVIDER_CLIENTID
KVIKLET_IDENTITYPROVIDER_CLIENTSECRET
KVIKLET_IDENTITYPROVIDER_TYPE=keycloak
KVIKLET_IDENTITYPROVIDER_ISSUERURI=http://[host]:[port]/realms/[realm]
Идентификатор клиента и секрет вы получаете при создании приложения в Keycloak. Для допустимых URI перенаправления следует настроить: https://[kviklet_host]/api/login/oauth2/code/keycloak Для разрешённых источников (Allowed Origins) — просто URL вашего размещённого kviklet.
После настройки этих переменных окружения на странице входа должна появиться кнопка «Войти через Keycloak», которая перенаправляет в ваш экземпляр Keycloak. В корпоративной редакции вы можете включить синхронизацию ролей, чтобы автоматически синхронизировать роли из вашего экземпляра Keycloak с kviklet. Подробнее см. раздел Role Sync.
GitHub (Beta)
Beta: Аутентификация через GitHub является новой и пока не поддерживает синхронизацию ролей — каждый новый пользователь получает роль по умолчанию, и роли необходимо назначать вручную.
GitHub не соответствует требованиям OIDC (это чистый OAuth 2.0), поэтому в Kviklet для него реализована отдельная поддержка. Задайте следующие переменные окружения:``` KVIKLET_IDENTITYPROVIDER_CLIENTID KVIKLET_IDENTITYPROVIDER_CLIENTSECRET KVIKLET_IDENTITYPROVIDER_TYPE=github KVIKLET_IDENTITYPROVIDER_GITHUB_ALLOWEDORGS=your-org,another-org
Создайте GitHub OAuth App на https://github.com/settings/developers и настройте:
- Authorization callback URL: `https://[kviklet_host]/api/login/oauth2/code/github`
- Homepage URL: URL вашего размещённого Kviklet
`KVIKLET_IDENTITYPROVIDER_GITHUB_ALLOWEDORGS` **обязателен** (Kviklet отказывается запускаться без него). GitHub OAuth Apps не могут ограничить, кто завершает OAuth-поток, поэтому Kviklet вызывает `/user/orgs` после аутентификации и отклоняет пользователей, которые не являются членами хотя бы одной организации из списка разрешённых (без учёта регистра, проверяются первые 100 организаций).
Чтобы проверка организаций увидела членство пользователя, пользователь должен нажать **Grant** (или **Request**) рядом с каждой организацией из списка разрешённых на экране согласия OAuth. Если в организации включено "Restrict third-party OAuth applications", владелец организации также должен один раз одобрить OAuth-приложение, прежде чем членство любого участника станет видимым.
Kviklet запрашивает области `read:user`, `user:email` и `read:org`. Адреса электронной почты всегда читаются из `/user/emails`, и принимается только запись `primary && verified`, поэтому пользователи с приватными адресами электронной почты всё равно успешно входят в систему.
#### Другие OIDC-провайдеры
Другие OIDC-совместимые провайдеры (GitLab, Auth0, Okta и т. д.) должны работать аналогично Keycloak. Обратите внимание, что `redirect URI` будет меняться в зависимости от выбранного типа, поэтому если вы выберете `gitlab`, он будет `https://[kviklet_host]/api/login/oauth2/code/gitlab`.
Если вы столкнётесь с проблемами, не стесняйтесь создать issue — мы ещё не пробовали все существующие OIDC-провайдеры (пока что), и могут быть небольшие различия в реализации, которые могут потребовать обновлений на стороне Kviklet.
### LDAP
Kviklet поддерживает LDAP-аутентификацию. Чтобы включить и настроить LDAP, вы можете переопределить следующие переменные окружения:```
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
Вот что означает каждая настройка:
LDAP_ENABLED: Установитеtrue, чтобы включить аутентификацию LDAP.LDAP_URL: URL вашего LDAP-сервера.LDAP_BASE: Базовый DN для поиска в LDAP.LDAP_PRINCIPAL: DN администратора для привязки к LDAP-серверу.LDAP_PASSWORD: Пароль администратора.LDAP_UNIQUE_IDENTIFIER_ATTRIBUTE: Атрибут LDAP, используемый в качестве уникального идентификатора пользователей (по умолчанию: "uid").LDAP_EMAIL_ATTRIBUTE: Атрибут LDAP, содержащий адрес электронной почты пользователя (по умолчанию: "mail").LDAP_FULL_NAME_ATTRIBUTE: Атрибут LDAP, содержащий полное имя пользователя (по умолчанию: "cn").LDAP_USER_OU: Организационное подразделение (OU), в котором хранятся учётные записи пользователей (по умолчанию: "people").LDAP_SEARCH_BASE: Позволяет переопределить базовый DN для поиска пользователей (по умолчанию: "ou=people"). Если вы используете FreeIPA, возможно, потребуется установить это значение, например,cn=users. Если задано, LDAP_USER_OU игнорируется.
Вы можете настроить эти атрибуты в соответствии с вашей схемой LDAP. После настройки LDAP пользователи смогут входить в систему, используя свои учётные данные LDAP. При первом входе пользователя LDAP в Kviklet будет создана соответствующая учётная запись пользователя с правами по умолчанию. Администратору потребуется назначить соответствующие роли этим пользователям после их первого входа.
SAML (только для Enterprise)
Kviklet поддерживает аутентификацию SAML 2.0. Чтобы включить SAML, установите следующие переменные окружения:``` 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-----
Детали конфигурации:
- `SAML_ENABLED`: Установите `true`, чтобы включить аутентификацию SAML
- `SAML_ENTITYID`: Идентификатор сущности вашего поставщика удостоверений SAML
- `SAML_SSOSERVICELOCATION`: URL-адрес службы SSO вашего поставщика удостоверений
- `SAML_VERIFICATIONCERTIFICATE`: Сертификат X.509, используемый для проверки ответов SAML (включите строки BEGIN/END CERTIFICATE)
При необходимости вы можете настроить сопоставления атрибутов SAML:```
SAML_USERATTRIBUTES_EMAILATTRIBUTE=email
SAML_USERATTRIBUTES_NAMEATTRIBUTE=name
SAML_USERATTRIBUTES_IDATTRIBUTE=nameID
Ваш поставщик удостоверений должен быть настроен со следующими параметрами:
- Entity ID:
https://[kviklet_host]/api/saml2/service-provider-metadata/saml - Redirect Uri:
https://[kviklet_host]/api/login/saml2/sso/saml
После настройки SAML пользователи могут входить через поставщика удостоверений. При первом входе создаётся учётная запись пользователя с разрешениями по умолчанию.
Если вас корректно перенаправляет на IDP, но затем возникает ошибка CORS, вы можете добавить хост вашего IDP в список разрешённых источников в Kviklet через:``` CORS_ALLOWEDORIGINS=https://[idp_host]
## Конфигурация
### Подключения
После запуска Kviklet сначала необходимо настроить подключение к базе данных. Перейдите в Settings -> Databases -> Add Connection.


Здесь вы можете настроить требования к проверке и лимиты выполнения для каждого подключения. Подробности см. в разделе [Review Gates](#review-gates).
#### AWS IAM AUTH
Kviklet поддерживает использование IAM Auth для подключений к базам данных Postgres, MySQL и MariaDB. Для этого выберите IAM Auth при создании нового подключения.


Это уберёт возможность задать пароль и вместо этого будет использовать учётные данные AWS для подключения к базе данных.
Kviklet использует `DefaultCredentialsProvider` от AWS для поиска учётных данных и генерации токена для подключения. Это означает, что все типичные места должны работать (переменные окружения или связанные роли экземпляра). Точный порядок задокументирован здесь: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html
Дополнительно вы можете указать ARN роли AWS, которую Kviklet будет принимать, и использовать эти учётные данные для создания временного токена БД. Это особенно полезно для подключения к базам данных, которые находятся не в том же аккаунте AWS, что и Kviklet. Чтобы использовать эту функцию, просто введите ARN роли в соответствующее поле при создании или редактировании подключения IAM Auth. Если оставить поле пустым, будет использоваться провайдер учётных данных по умолчанию (без принятия роли).
Регион AWS, используемый при генерации токена, определяется из URL вашего подключения, поэтому возможности задать его вручную нет.
Чтобы узнать, как настроить IAM Auth для вашей базы данных, обратитесь к официальной документации AWS: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
Основные два момента:
- Создайте пользователя БД с опцией IAM auth и правильными разрешениями
- Создайте политику IAM, которая позволяет сущности AWS генерировать токены для этого пользователя
### Review Gates
По умолчанию Kviklet позволяет использовать простую конфигурацию количества проверок. Вы можете настроить, сколько одобрений требуется для запросов на конкретном подключении, прежде чем они могут быть выполнены.
Статус одобрения запроса рассчитывается на основе последнего действия каждого проверяющего. Если проверяющий одобряет, а затем запрашивает изменения, учитывается только запрос на изменение — его предыдущее одобрение удаляется. Редактирование запроса всегда сбрасывает все предыдущие одобрения, гарантируя, что никакие изменения не могут быть выполнены без предварительной проверки. Аналогично, если выполнение завершается неудачей (например, из-за синтаксической ошибки SQL), одобрения сбрасываются, чтобы запрос можно было исправить и повторно одобрить без необходимости создавать новый.
Вы также можете настроить лимит **max executions** для каждого подключения, чтобы контролировать, как часто один одобренный запрос может быть выполнен. По умолчанию — 1. Установка значения 0 разрешает неограниченное количество выполнений. Неудачные выполнения не учитываются в этом лимите.
#### Требования к проверке на основе ролей (Enterprise)
С лицензией Kviklet Enterprise вы можете настроить отдельные подключения так, чтобы они требовали одобрения от пользователей с определёнными ролями. Это позволяет, например, требовать одобрения от команды, которая обслуживает данную базу данных, или ограничивать доступ к чувствительным подключениям одобрением DBA или руководства.
**Как это работает:**
Каждое подключение имеет **общее количество требуемых проверок** (`numTotalRequired`), которое действует как минимум — минимальное количество различных одобрений, необходимых независимо от ролей. В дополнение к этому вы можете добавить **требования к ролям**, которые указывают, сколько одобрений должно поступить от пользователей с определённой ролью (например, «1 от DBA, 1 от Security»).
Запрос одобряется только тогда, когда выполнены **оба** условия:
- Общее количество различных одобрений соответствует `numTotalRequired`
- Каждое требование к роли удовлетворено отдельно
Если пользователь принадлежит к нескольким ролям, одно одобрение от этого пользователя учитывается для всех соответствующих требований к ролям. Однако оно всё равно считается только одним одобрением в общем количестве.
**Пример:** Для подключения требуется 3 общих одобрения, включая 1 от DBA и 1 от Security. Пользователь, имеющий одновременно роли DBA и Security, одобряет — это удовлетворяет оба требования к ролям, но считается только как 1 из 3 необходимых общих одобрений. Всё ещё требуются два дополнительных одобрения от любых пользователей.
Если срок действия вашей корпоративной лицензии истекает, существующие требования к проверке на основе ролей продолжают применяться, но их больше нельзя изменять. Вы можете только удалить их, чтобы вернуться к простой конфигурации общего количества проверок.
### Роли
Kviklet поставляется с 3 ролями: Default, Admins и Developers.
- Роль по умолчанию предоставляет доступ на чтение ко всем подключениям и запросам. Эта роль назначается каждому пользователю и не может быть удалена. Однако вы можете изменять разрешения этой роли по своему усмотрению.
- Admins имеют разрешение создавать и редактировать подключения, а также добавлять новых пользователей и настраивать их разрешения.
- Developers могут создавать запросы, а также одобрять их и комментировать, и, конечно же, выполнять сами операторы.
Вы можете настраивать роли и, например, дать роли доступ только к конкретному подключению или группе подключений к БД.
Это полезно, например, если у вас есть разные команды с разными базами данных и вы хотите более гранулярно контролировать доступ к ним.
#### Создание новой роли
Создание новой роли работает следующим образом. Перейдите в Settings -> Roles -> Add Role.


Настройки по умолчанию не так важны для большинства ролей, и вы можете просто дать User Read и RoleView Access и на этом остановиться.
Более интересно добавление отдельных разрешений для подключений. Здесь вы сначала добавляете селектор для выбора конкретных подключений. Это может быть либо конкретный id, либо вы используете подстановочные знаки с `*` для сопоставления нескольких подключений. Например, если вы хотите иметь роль с доступом ко всем dev-базам данных (в случае, если вы также управляете доступом к ним с помощью kviklet), вы бы использовали селектор вроде `dev-*` и убедились, что id подключений заданы правильно.
Вы, конечно, также можете придумать систему, которую используете для своих разных команд внутри вашей организации.
### Синхронизация ролей (Enterprise)
Автоматически синхронизируйте роли пользователей из групп вашего провайдера идентификации. Эта функция требует корпоративной лицензии.
**Конфигурация** выполняется в Settings > Role Sync:
- **Enable Role Sync**: Включение/выключение синхронизации
- **Sync Mode**:
- **Full Sync** — роли пользователей точно соответствуют их сопоставлениям групп IdP (плюс роль по умолчанию)
- **Additive** — группы IdP добавляют роли, но не удаляют существующие
- **First Login Only** — роли синхронизируются только при первом входе, ручные изменения сохраняются впоследствии
- **Groups Attribute**: Атрибут IdP, содержащий членство в группах (по умолчанию: `groups`)
- **Role Mappings**: Сопоставление имён групп IdP (например, `engineering`) с ролями Kviklet
#### Настройка OIDC
Настройте вашего провайдера OIDC так, чтобы он включал claim `groups` в ID-токен:
- **Keycloak**:
Keycloak по умолчанию не включает группы в токены, поэтому вам нужно добавить mapper к клиенту.
1. Перейдите в **Clients** в левом меню
2. Выберите ваш клиент Kviklet
3. Перейдите на вкладку **Client scopes**
4. Нажмите на выделенный scope (например, `kviklet-dedicated`)
5. Перейдите на вкладку **Mappers**
6. Нажмите **Add mapper** → **By configuration**
7. Выберите **Group Membership**
8. Настройте 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. Нажмите **Save**
> **Важно:** «Token Claim Name» должен совпадать с «Groups Attribute», настроенным в настройках Role Sync Kviklet (по умолчанию: `groups`).
- **Другие провайдеры OIDC**: Добавьте mapper/claim групп, который включает членство пользователя в группах в ID-токен. Обычно это делается в административном интерфейсе провайдера.
Если вы столкнётесь с проблемами, не стесняйтесь создать issue — мы ещё не пробовали каждый существующий провайдер OIDC (пока), и могут быть небольшие различия в реализации, которые могут потребовать обновлений на стороне Kviklet.
#### Настройка LDAP
Синхронизация ролей LDAP использует атрибут `memberOf`:
1. Убедитесь, что на вашем сервере LDAP включён overlay `memberOf`
2. Установите **Groups Attribute** в `memberOf` в Kviklet
3. Имена групп затем извлекаются из атрибута `memberOf` в атрибутах пользователей.
#### Настройка SAML
Настройте вашего провайдера SAML IdP так, чтобы он включал группы в assertion:
1. Добавьте attribute statement, который сопоставляет членство пользователя в группах
2. Установите **Groups Attribute** в Kviklet в соответствии с именем вашего атрибута SAML
3. Имена групп затем извлекаются из атрибута SAML в атрибутах пользователей.
### Уведомления
Вы можете настроить Kviklet для отправки уведомлений в канал в Slack или Teams. Это полезно для уведомления вашей команды о новых запросах, требующих проверки. Вы можете настроить это в Settings -> General -> Notification Settings.
#### Slack
Чтобы настроить уведомления Slack, вам нужно создать Slack App и включить для него webhooks. Вы можете следовать инструкциям здесь: https://api.slack.com/messaging/webhooks
#### Teams
Уведомления Teams используют webhook **Workflow** Power Automate. Kviklet отправляет Adaptive Card, которую шаблон webhook публикует в вашем канале.
**Рекомендуется: использовать шаблон workflow**
1. В Teams откройте канал, в который хотите получать уведомления, нажмите **...** рядом с именем канала и выберите **Workflows** (или добавьте приложение **Workflows**).
2. Найдите и создайте шаблон **«Send webhook alerts to a channel»**.
3. Войдите в систему, когда будет предложено, затем выберите целевые Team и Channel и создайте workflow.
4. Откройте шаг trigger и скопируйте сгенерированный **HTTP POST URL**.
5. Вставьте URL в Kviklet в разделе Settings -> General -> Notification Settings и нажмите save.
**Альтернатива: создать workflow вручную**
Если вы предпочитаете создать flow самостоятельно (или шаблон недоступен):
1. Channel **...** -> **Workflows** -> создайте flow с триггером **«When a Teams webhook request is received»**.
2. Добавьте действие **Microsoft Teams -> «Post card in a chat or channel»**.
3. Установите поле **Adaptive Card** действия в выражение `string(triggerBody())`, чтобы оно публиковало карточку, которую отправляет Kviklet.
4. Выберите целевые Team и Channel, **Save**, затем скопируйте **HTTP POST URL** из шага trigger.
В настоящее время есть уведомления для:
- Новых запросов, требующих одобрения
- Новых одобрений запросов
#### Настройка Base URL
При запуске Kviklet за обратным прокси или Kubernetes Ingress ссылки в уведомлениях могут использовать внутренний IP-адрес вместо вашего публичного домена. Kviklet пытается отслеживать правильный URL, анализируя входящие запросы, но некоторые обратные прокси не устанавливают заголовки Forwarded корректно. Чтобы исправить это, задайте base URL явно:```
KVIKLET_BASE_URL=https://kviklet.example.com
Это гарантирует, что все ссылки в уведомлениях указывают на правильный публичный URL.
Телеметрия
Kviklet отправляет анонимную статистику использования, чтобы помочь нам понять, какие функции используются и где возникают ошибки. Чтобы отключить её, установите:``` KVIKLET_TELEMETRY_ENABLED=false
Kviklet записывает одну строку при запуске, сообщая, включена ли телеметрия.
**Что отправляется.** Каждое событие содержит случайный идентификатор экземпляра (генерируется один раз и хранится в базе данных Kviklet), базовый URL, по которому доступен Kviklet (см. выше; часто это внутреннее имя хоста), и версию Kviklet. Пользователи идентифицируются только по непрозрачному идентификатору в пределах экземпляра, что позволяет подсчитывать уникальных пользователей, но адреса электронной почты или имена никогда не отправляются. Точные события и их свойства определены в `backend/src/main/kotlin/dev/kviklet/kviklet/telemetry/TelemetryEvent.kt`.
**Что никогда не отправляется.** Запросы, инструкции, результаты, вывод команд, сообщения об ошибках, имена подключений, имена хостов, учётные данные, заголовки или описания запросов, комментарии, а также имена пользователей или ролей.
### Логирование
По умолчанию Kviklet записывает удобочитаемые (pretty) логи в stdout, что удобно
при чтении их напрямую или через `docker logs`.
Если вы отправляете логи в централизованную систему (Elasticsearch, Loki, Datadog, CloudWatch, …), вы
можете переключиться на структурированные **JSON-логи**, которые проще индексировать и запрашивать. Задайте
формат через переменную окружения:```
# One of: ecs (Elastic Common Schema), logstash, gelf (Graylog)
LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs
Шифрование
Если вы не хотите, чтобы учётные данные хранились в базе данных в открытом виде, рекомендуется включить шифрование базы данных в самом postgres DB Kviklet. Для большинства хостинг-провайдеров это простая галочка, которую нужно установить. Тем не менее, если база данных Kviklet каким-либо образом скомпрометирована, это огромный риск для безопасности. Поскольку она содержит учётные данные базы данных потенциально для всех ваших production-хранилищ данных. Поэтому вы можете включить шифрование учётных данных при хранении.
Для этого просто установите две переменные окружения.``` ENCRYPTION_ENABLED=true ENCRYPTION_KEY_CURRENT=some-secret
Kviklet зашифрует все ваши существующие учётные данные при запуске и будет использовать секрет для будущих подключений, которые вы создаёте.
### Ротация ключей
Если вы хотите выполнить ротацию ключа, вы можете просто добавить ещё одну переменную для предыдущего ключа и изменить текущий:```
ENCRYPTION_KEY_PREVIOUS=some-secret
ENCRYPTION_KEY_CURRENT=another-secret
Kviklet повторно зашифрует все соединения при запуске, чтобы затем можно было перезапустить контейнер с удалённым предыдущим ключом.
API-ключи
Kviklet поддерживает API-ключи для программного доступа к системе. Это функция только для корпоративной версии и требует действующей лицензии. Вы можете создавать API-ключи в разделе Settings -> API Keys.

Используйте это так:```bash
curl --location '[kviklet_host]/api/connections/'
--header 'Authorization: Bearer your-api-key'
API-ключи наследуют разрешения пользователя, который их создаёт. В настоящее время только администраторы могут управлять API-ключами, и все действия, выполняемые с помощью API-ключа, приписываются пользователю, создавшему этот ключ.
Некоторую базовую документацию по API можно найти по адресу `[kviklet_host]/api/swagger-ui/index.html`. Но имейте в виду, что это находится в разработке, и API может измениться в будущих версиях.
В конечном счёте истина — в коде, поэтому вы всегда можете посмотреть на контроллер, чтобы увидеть, как определён API. Если у вас есть вопросы, не стесняйтесь открыть issue.
## Экспериментальные функции
В настоящее время существует две экспериментальные функции. Они были созданы в основном на основе отзывов сообщества. Не стесняйтесь попробовать их и оставить любые свои замечания. Мы надеемся развивать их дальше в будущем и обеспечить хорошую совместимость с основным процессом одобрения.
### Kubernetes Exec
Если вы хотите использовать функцию Kubernetes Exec, вам необходимо создать отдельное подключение к Kubernetes. Kviklet будет использовать пользователя развёрнутого пода для выполнения команды. Поэтому убедитесь, что у этого пользователя есть необходимые разрешения для выполнения команд на подах, к которым вы хотите получить доступ.
Kviklet также использует /bin/sh для выполнения команды, поэтому вам нужно убедиться, что в ваших подах есть оболочка или хотя бы символическая ссылка в /bin/sh. Если это вас не устраивает, не стесняйтесь открыть issue — мы потенциально можем сделать это настраиваемым или найти другое решение.
Команды Kubernetes ожидают вывода только 5 секунд; если команда выполняется дольше, Kviklet будет ждать до часа, прежде чем прервать команду по тайм-ауту. Это временное решение; мы изучаем возможность использования websockets, чтобы сделать это более отзывчивым и потенциально включить терминальные сессии.
### Прокси — Postgres, MariaDB, MySQL (Enterprise)
Если вы создаёте запросы на временный доступ, вы можете — вместо использования веб-интерфейса — выполнять свои запросы через управляемый kviklet прокси и использовать DB-клиент на ваш выбор.
Прокси является функцией уровня enterprise: для него требуется действующая лицензия, и администратор дополнительно должен включить его в разделе Settings -> General -> Database Proxy.
Для этого контейнер прослушивает стабильные порты (по умолчанию 5432 и 3306, настраиваются через `kviklet.proxy.postgres.port` и `kviklet.proxy.mysql.port`), поэтому вам нужно открыть эти порты.
Затем пользователи могут создать запрос на временный доступ и нажать «Start Proxy» после его одобрения. Каждый запрос получает временное имя пользователя и пароль; Kviklet направляет каждое подключение к его запросу по имени пользователя. С ними они могут подключиться к базе данных. Kviklet проверяет временного пользователя и пароль и проксирует все запросы к нижележащему пользователю в базе данных. Любые выполненные операторы регистрируются в журнале аудита так, как если бы они были выполнены через веб-интерфейс.
Примечание: в настоящее время прокси не поддерживает отслеживание результатов. Поэтому выполненные операторы регистрируются, но не результаты и не то, успешно ли выполнен оператор или нет.


#### Прокси — TLS
Kviklet завершает TLS-соединение с базой данных. Это означает, что по умолчанию любой трафик от прокси и к нему не шифруется.
Если вы хотите, чтобы kviklet повторно шифровал трафик, вы можете передать Kviklet TLS-сертификат и ключ для прокси, задав следующие переменные окружения:```
PROXY_TLS_CERTIFICATE_SOURCE=env
PROXY_TLS_CERTIFICATE_CERT=your-certificate
PROXY_TLS_CERTIFICATE_KEY=your-key
в качестве альтернативы можно использовать файлы:``` PROXY_TLS_CERTIFICATE_SOURCE=file PROXY_TLS_CERTIFICATE_CERT_FILE=path/to/cert.pem PROXY_TLS_CERTIFICATE_KEY_FILE=path/to/key.pem
В любом случае сертификат и ключ должны быть сохранены в [формате pem](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail).
## Вопросы? Вклад?
Если у вас есть вопросы, вы хотите оставить отзыв или вам нужна помощь с настройкой, присоединяйтесь к нашему [сообществу в Discord](https://discord.gg/7SmPJfeP6e). Вы также можете создать [issue на GitHub](https://github.com/kviklet/kviklet/issues) для сообщений об ошибках и запросов новых функций.
Если вы хотите внести свой вклад, не стесняйтесь форкать и создавать PR для небольших изменений. Если вы планируете более крупные функции, я буду признателен за предварительное обсуждение в issue на GitHub или в Discord.
Вы также можете связаться со мной по адресу [email protected].