
kviklet v0.8.0
类似 Pull Request 的数据库查询审批/批准流程,用于合规但顺畅的工程人员访问生产环境。
Kviklet
Kviklet.dev | 发布说明 | Discord
在不影响开发者生产力的情况下安全访问生产环境。

Kviklet(发音为 Quick-let)将四眼原则应用于生产数据库访问,为单条 SQL 语句或限时数据库会话提供类似拉取请求的审查和批准工作流。工程师可以相互审查和批准彼此的请求,而无需将每个查询都通过 DBA 或运维团队。
Kviklet 是自托管的,作为 Docker 容器运行,并使用 PostgreSQL 数据库存储应用程序状态。其 Web 界面允许你提交、审查和执行请求。可选的企业许可证可解锁 SAML 身份验证、基于角色的审查要求、角色同步和 API 密钥。请在 kviklet.dev 申请企业许可证。
支持的数据库包括 Postgres、MySQL、MariaDB、MS SQL Server 和 MongoDB。
访问模型
我们建议将 Kviklet 连接到您现有的身份提供商。Kviklet 支持通过 OIDC(Google、Keycloak 等)或 SAML(仅限企业版)进行 SSO,以及 LDAP 身份验证(Active Directory 等)。 用户随后为映射到特定数据库用户的连接创建请求。这些请求可以是:
- 单条查询:提交审查的特定 SQL 语句。
- 临时访问:限时会话,您可以在其中运行多条语句。
根据配置,请求在 Kviklet 允许执行之前会由其他用户审查和批准。
Kviklet 代表用户连接到数据库。连接的数据库密码永远不会向用户显示。
管理员可以配置哪个角色有权访问哪个连接,以及执行需要哪些审查关卡。数据库级别的访问通过底层数据库的 RBAC 机制进行管理。例如,可以为只读连接创建只读角色,并为其分配比写入连接更少的审查要求。
Kviklet 记录已执行的语句,并将其与用户和访问请求关联。为了全面覆盖手动数据库访问,请限制直接连接,并将任何手动访问都通过 Kviklet 进行路由。工程师无需接收或共享底层数据库凭据。
额外的企业版功能包括:
- SAML:支持 SAML 身份验证。
- 代理(Postgres、MariaDB、MySQL):通过已批准的临时访问会话,使用临时密码,使用您首选的数据库客户端。已执行的语句会记录在 Kviklet 的审计日志中。
- 基于角色的审查关卡:要求在执行前获得特定角色的批准。
- 角色同步:自动从您的身份提供商组同步用户角色。
- API 密钥:以编程方式访问 Kviklet API。
更多截图
请求
所有数据请求都集中在一个地方。就像您生产数据库的开放 PR:

实时会话
已批准的临时访问请求会直接在浏览器中打开一个实时 SQL 会话:

审计日志
每条已执行的语句都会被记录——无论是作为已审查的单条查询运行、在实时会话中运行,还是通过数据库代理运行:

按数据库/连接类型划分的功能
大多数功能适用于所有数据库(SSO、LDAP、RBAC、审查/批准流程、审计日志等)。但某些功能受到限制,要么是因为尚未构建,要么是因为对该特定用途没有意义。下表显示了哪些功能适用于哪种数据库类型:
| Database | Statement Review | Temporary Access | Proxy(Beta) | Explain Plan |
|---|---|---|---|---|
| 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 up -d运行docker-compose.yml。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 数据库(或至少是 schema)来保存关于查询、连接、审批等的元数据。
你可以在这里找到官方镜像: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 身份验证:
可以使用 AWS IAM 身份验证进行数据库连接,在这种情况下,只需省略密码并设置用户名即可。
你还必须设置环境变量: ```
SPRING_DATASOURCE_IAMAUTH=true
Kviklet 将从常见位置(环境变量、实例角色等)加载凭据,并为连接生成令牌。
- 证书: 你也可以使用证书进行数据库连接,示例见此处。
初始用户
你需要一个初始管理员用户来进行配置。为此,请设置两个环境变量:
INITIAL_USER_EMAIL 和 INITIAL_USER_PASSWORD,以便你可以登录 Web 界面。之后你可以通过 UI 更改密码。
示例:```
INITIAL_USER_EMAIL=[email protected]
INITIAL_USER_PASSWORD=someverysecurepassword
我们目前将容器发布到 GitHub packages,因此完成所有设置后,你可以运行 `ghcr.io/kviklet/kviklet:main`,别忘了映射端口 `8080`,这是 Kviklet 默认启动的端口。
一个 docker run 示例可能如下所示:```
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
通过 OIDC / OAuth2 实现 SSO
如果你想为你的 Kviklet 实例设置 SSO(这非常合理,否则你又得管理密码了)。 你需要设置这 3 个环境变量:``` KVIKLET_IDENTITYPROVIDER_CLIENTID KVIKLET_IDENTITYPROVIDER_CLIENTSECRET KVIKLET_IDENTITYPROVIDER_TYPE=google
你可以按照 Google 的说明轻松获取 google client id 和 secret:
https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid
对于有效的重定向 URI,你应该配置:https://[kviklet_host]/api/login/oauth2/code/google
对于允许的来源,只需填写你托管的 kviklet url。
设置这些环境变量后,你组织中的每个人都可以通过“使用 Google 登录”按钮登录。但默认情况下他们没有任何权限,你需要在他们首次登录后为其分配角色。
#### Keycloak