A web interface for ClickHouse with built-in RBAC
Features β’ Architecture β’ Quick Start β’ Deployment β’ Configuration
CHouse UI is a web interface for managing ClickHouse databases with server-side credential management and Role-Based Access Control (RBAC). Credentials are stored encrypted on the server, and access is controlled through a permission system.
CHouse UI provides security and access control features for teams that need:
| Feature | CHouse UI |
|---|---|
| Credential Management | Encrypted server-side storage (never in browser) |
| Architecture | Secure backend proxy (no direct browser-to-ClickHouse) |
| Access Control | Full RBAC with granular permissions |
| Multi-Connection | Manage multiple ClickHouse servers |
| Audit Trail | Audit logging |
Note: Other ClickHouse tools serve different use cases well. CHouse UI is designed specifically for teams requiring centralized credential management, role-based access control, and audit capabilities.
- RBAC System - Role-based permissions (Super Admin, Admin, Developer, Analyst, Viewer, Guest)
- ClickHouse User Management - Create and manage ClickHouse users with native grants (Developer, Analyst, Viewer roles)
- Encrypted Credentials - AES-256-GCM encryption for ClickHouse connection passwords
- Password Hashing - Argon2id for user passwords
- JWT Authentication - Secure token-based sessions with access and refresh tokens
- Data Access Rules - Granular database/table permissions per user or role
- Audit Logging - Track all user actions and query history
- AI-Powered Analysis - Built-in query optimizer and debugger to improve performance and security
- Multi-Connection Support - Manage multiple ClickHouse servers
- Database Explorer - Tree view with schema inspection
- Database Operations - Create and drop databases
- Table Management - Create, alter, and drop tables with various engines (MergeTree, ReplicatedMergeTree, etc.)
- File Upload - Upload CSV, TSV, or JSON files to existing tables
- Data Preview - Sample data with pagination
- SQL Editor - Monaco editor with syntax highlighting and auto-completion
- Query Execution - Run queries with execution statistics
- Query History - View and filter query logs with auto-refresh
- Saved Queries - Persist frequently used queries
- Data Export - CSV, JSON, TSV formats
- Real-time Metrics - System monitoring dashboard with charts
- Overview Dashboard - System stats, recent queries, and quick actions (admin only)
- Modern UI - Glassmorphism design with dark theme
- Responsive - Works on desktop and tablet
- Connection Selector - Quick server switching
- Keyboard Shortcuts - Power user support
| Analytics | Optimization | Debugging | Visualization |
![]() |
![]() |
![]() |
![]() |
- Bun v1.0+ (or Node.js 18+)
- A ClickHouse server (or use Docker Compose)
Successfully tested with:
- ClickHouse: Version 25
- PostgreSQL: Version 18 (for RBAC database)
- SQLite: Version 3.51.0 (via Bun, for RBAC database)
# Clone the repository
git clone https://github.com/daun-gatal/chouse-ui.git
cd chouse-ui
# Install dependencies
bun install
# Start development servers
bun run devThis starts:
- Frontend: http://localhost:5173
- Backend: http://localhost:5521
On first run, an admin user is created:
- Email:
admin@localhost - Username:
admin - Password:
admin123!
β οΈ Change this password immediately in production!
# Clone the repository
git clone https://github.com/daun-gatal/chouse-ui.git
cd chouse-ui
# Run with Docker Compose
docker-compose up -dAccess at http://localhost:5521
For production, we recommend using an external highly-available PostgreSQL database for RBAC storage. See the Configuration section for details on how to configure RBAC_POSTGRES_URL.
CHouse UI can be configured using environment variables (.env file) or through a grouped YAML configuration file.
You can set all configuration options via a hierarchical YAML file. To use this, set the CHOUSE_CONFIG_PATH environment variable pointing to your YAML file:
CHOUSE_CONFIG_PATH=./config.yaml bun run packages/server/src/index.tsThe YAML keys map directly to the environment variables by converting the nested paths to uppercase and joining with underscores. For example:
port: 5521
node_env: production
rbac:
db_type: sqlite
sqlite_path: ./data/rbac.db
encryption:
key: your-secret-key
ai:
provider: openai| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 5521 |
NODE_ENV |
Environment (development/production) |
development |
CORS_ORIGIN |
Allowed CORS origins (comma-separated or *) |
* |
STATIC_PATH |
Path to frontend build | ./dist |
LOG_LEVEL |
Server log level: debug, info, warn, or error (JSON logs via Pino) |
info (production), debug (development) |
CHOUSE_CONFIG_PATH |
Path to optional YAML configuration file | - |
| Variable | Description | Default |
|---|---|---|
RBAC_DB_TYPE |
Database type (sqlite/postgres) |
sqlite |
RBAC_SQLITE_PATH |
SQLite file path | ./data/rbac.db |
RBAC_POSTGRES_URL |
PostgreSQL connection URL (or use DATABASE_URL) |
- |
RBAC_POSTGRES_POOL_SIZE |
Connection pool size for PostgreSQL | 10 |
PostgreSQL Permissions: When using PostgreSQL, the database user specified in RBAC_POSTGRES_URL must have the following permissions:
CREATEDBprivilege to create the database if it doesn't exist- Or the database must already exist and the user must have
CONNECTandCREATEprivileges on it
The application will automatically create the database if it doesn't exist. To grant the required permissions:
-- Grant CREATEDB privilege (allows creating databases)
ALTER USER your_user WITH CREATEDB;
-- Or if the database already exists, grant privileges on it
GRANT CONNECT, CREATE ON DATABASE your_database TO your_user;| Variable | Description | Default |
|---|---|---|
JWT_SECRET |
JWT signing secret | Required |
JWT_ACCESS_EXPIRY |
Access token expiry (e.g., 15m, 4h) |
4h |
JWT_REFRESH_EXPIRY |
Refresh token expiry (e.g., 7d) |
7d |
RBAC_ADMIN_EMAIL |
Initial admin email | admin@localhost |
RBAC_ADMIN_USERNAME |
Initial admin username | admin |
RBAC_ADMIN_PASSWORD |
Initial admin password | admin123! |
| Variable | Description | Default |
|---|---|---|
RBAC_ENCRYPTION_KEY |
AES-256 key for passwords (32-byte hex) | Required |
RBAC_ENCRYPTION_SALT |
Salt for key derivation (32-byte hex) | Required |
# Generate JWT secret
openssl rand -base64 32
# Generate encryption key
openssl rand -hex 32
# Generate strong password
openssl rand -base64 16CHouse UI has its own permission system that controls access to the web interface.
Two separate things:
-
CHouse UI RBAC (for the web interface):
- Controls who can use CHouse UI and what they can do
- Stored in CHouse UI's own database
- All queries are checked against these permissions before reaching ClickHouse
-
ClickHouse User Management (optional feature):
- CHouse UI can create ClickHouse users with native grants
- These are actual ClickHouse users (not CHouse UI users)
- Useful if you want to manage ClickHouse users through the web interface
In simple terms: CHouse UI's RBAC controls access to the web interface. It can also optionally create ClickHouse users, but that's a separate feature.
| Role | Description | Key Permissions |
|---|---|---|
| Super Admin | Full system access | All permissions |
| Admin | Server management | Users, roles, connections |
| Developer | Write access | Insert, update, DDL |
| Analyst | Read access | Select, export |
| Viewer | Read-only | Select only |
| Guest | Read-only access | View all tabs, read-only queries, system tables access |
Control access to specific databases and tables:
Rule: Allow "analyst" role to access "analytics.*"
Rule: Deny "viewer" role from "system.*"
Rule: Allow user "john" to access "sales.orders"
Features:
- Wildcards:
*matches any database/table - Patterns: Regex support for complex rules
- Deny Rules: Explicit denials take precedence
- Priority: Higher priority rules evaluated first
- User Management: Create, update, delete users
- Role Management: Manage roles and permissions
- Connection Management: Add/edit ClickHouse connections
- Query Operations: Execute queries, DML, DDL
- Table Operations: Select, insert, update, delete
- System: Audit logs, settings
CHouse UI is a monorepo with two main packages:
- Frontend (
src/) β React 19 + Vite SPA with Zustand stores, TanStack Query, and shadcn/ui - Backend (
packages/server/) β Bun + Hono API server with RBAC, ClickHouse proxy, and AI optimizer
graph TB
subgraph Browser["Browser (React 19 SPA)"]
UI["Vite 7 + React Router v7"]
Stores["Zustand 4 Stores"]
RQ["TanStack Query v5"]
ApiClient["ApiClient (fetch)"]
end
subgraph Server["Bun Server (packages/server)"]
Hono["Hono v4"]
MW["Middleware: CORS, Rate Limit, SQL Parser, Data Access"]
Routes["API Routes: query, explorer, metrics, saved-queries, live-queries, upload, ai-chat"]
Services["Services: ClickHouse proxy, AI Optimizer, Query Analyzer, AI Chat, Chat History, AI Config"]
RBAC["RBAC: Auth, Users, Roles, Connections, Audit, ClickHouse Users, Data Access, User Preferences, AI Providers, AI Models"]
end
subgraph External["External"]
CH["ClickHouse"]
AI["AI Provider (OpenAI, Anthropic, Google, etc.)"]
DB["SQLite / PostgreSQL"]
end
UI --> Stores --> ApiClient
UI --> RQ --> ApiClient
ApiClient -->|"/api/*"| Hono
Hono --> MW --> Routes --> Services
Routes --> RBAC
Services -->|"@clickhouse/client"| CH
Services -->|"AI SDK v6"| AI
RBAC -->|"Drizzle ORM"| DB
π Full architecture documentation β β Detailed diagrams for frontend layers, backend services, RBAC subsystem, data flows, permissions catalog, and complete file structure with sizes.
If you discover a security vulnerability, please see SECURITY.md for information on how to report it responsibly.
- Generate unique
JWT_SECRET(min 32 bytes) - Generate unique
RBAC_ENCRYPTION_KEY(32 bytes hex) - Generate unique
RBAC_ENCRYPTION_SALT(32 bytes hex) - Change default admin password
- Set
CORS_ORIGINto your domain - Use PostgreSQL for multi-instance deployments
- Enable HTTPS via reverse proxy
- Configure firewall rules
- Set up regular backups
| Feature | Description |
|---|---|
| No Browser Credentials | ClickHouse passwords never reach the frontend |
| Encrypted Storage | AES-256-GCM for ClickHouse connection passwords |
| Password Hashing | Argon2id for user passwords |
| JWT Tokens | Short-lived access tokens, long-lived refresh tokens |
| RBAC Enforcement | Every request checked against permissions |
| Query Validation | SQL parsed and validated against data access rules |
| Audit Logging | All actions logged with user context |
Migrations run automatically on server startup. No manual intervention required.
Server Start
β
βΌ
initializeRbac()
β
βββ Check current DB version
βββ Run pending migrations (if any)
βββ Seed defaults (first run only)
| Scenario | What Happens |
|---|---|
| Fresh install | Creates full schema β Seeds roles, permissions, admin user |
| Version upgrade | Detects version diff β Applies only pending migrations |
| Normal restart | Version matches β No migrations needed |
For advanced scenarios (pre-flight checks, debugging), use CLI tools:
cd packages/server
# Check current status and pending migrations
bun run rbac:status
# Output example:
# Current version: 1.1.0
# Target version: 1.2.0
# Pending migrations:
# - 1.2.0: user_data_access_rules
# Run migrations manually
bun run rbac:migrate
# Check version only
bun run rbac:version
# Seed default data (if missing)
bun run rbac:seed
# Reset database (β οΈ DESTRUCTIVE - deletes all data!)
CONFIRM_RESET=yes bun run rbac:reset# 1. Pull latest version
docker pull ghcr.io/daun-gatal/chouse-ui:latest
# 2. Restart container - migrations run automatically
docker-compose up -d
# 3. Check logs for migration status
docker logs chouse-ui | grep RBACExpected output on upgrade:
[RBAC] ========================================
[RBAC] Initializing RBAC system...
[RBAC] Database type: sqlite
[RBAC] App version: 1.2.0
[RBAC] ========================================
[RBAC] Current DB version: 1.1.0
[RBAC] Running migration: 1.2.0 - user_data_access_rules
[RBAC] Migration complete
RBAC system ready
| Issue | Solution |
|---|---|
| Migration fails | Check logs, ensure DB is accessible |
| Wrong permissions | Ensure volume/file ownership matches container user |
| PostgreSQL connection | Verify RBAC_POSTGRES_URL is correct |
| PostgreSQL permission denied | Ensure user has CREATEDB privilege or database exists with CONNECT/CREATE privileges |
| Reset needed | Use CONFIRM_RESET=yes bun run rbac:reset |
We welcome contributions! Please see CONTRIBUTING.md for guidelines on how to contribute to this project.
If you're using AI coding assistants to help with contributions, please see the Using AI Tools section in CONTRIBUTING.md for guidelines on following the project's coding rules.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
This project was initially based on CH-UI by Caio Ricciuti. While significant modifications and additions have been made, we acknowledge the original work and maintain attribution as required by the Apache License 2.0.
CH-UI by Caio Ricciuti - This project was inspired by CH-UI's design and user experience.
- ClickHouse - Analytics database
- Bun - JavaScript runtime
- Hono - Web framework
- React - UI library
- Vite - Build tool
- Drizzle ORM - Database ORM
- Monaco Editor - SQL editor
- AG Grid - Data grid
- shadcn/ui - UI components
- Tailwind CSS - Styling
- Zustand - State management
- TanStack Query - Data fetching
This project was developed with significant assistance from AI coding tools:
- Cursor - AI-powered code editor (fork of VS Code)
- Google Antigravity - AI-native IDE with multi-agent support







