# Least-Privilege Connection Presets

chmonitor only reads ClickHouse system tables — it never issues writes, DDL, or schema changes. Running it under a dedicated read-only user follows the principle of least privilege and limits the blast radius if credentials are exposed.

This page shows how to create that user on each supported deployment type and how to wire it into the chmonitor env vars.

---

## Why a dedicated read-only user

- **Principle of least privilege.** chmonitor only needs `SELECT` on `system.*` (and optionally on databases you want to explore). Nothing more.
- **Credential isolation.** A separate `chmonitor` user means a leaked secret cannot be used to drop tables or modify data.
- **Audit trail.** All chmonitor queries appear in `system.query_log` under a distinct `user` value, making it easy to attribute traffic.

---

## ClickHouse OSS / self-managed

Use the SQL console or `clickhouse-client` as an admin user.

### 1. Create a read-only settings profile

```sql
CREATE SETTINGS PROFILE IF NOT EXISTS chmonitor_readonly
SETTINGS readonly = 2,
         max_execution_time = 60,
         allow_ddl = 0,
         allow_introspection_functions = 0;
```

`readonly = 2` blocks all writes and DDL while still letting the client set per-query settings such as `max_execution_time` — which chmonitor requires. (The stricter `readonly = 1` also forbids settings changes, so chmonitor would fail under it; use `readonly = 2`.) `allow_ddl = 0` is redundant under `readonly` but makes the intent explicit.

### 2. Create the user

```sql
CREATE USER IF NOT EXISTS chmonitor
IDENTIFIED BY 'replace-with-a-strong-password'
SETTINGS PROFILE 'chmonitor_readonly';
```

### 3. Grant SELECT on system tables

```sql
GRANT SELECT ON system.* TO chmonitor;
```

If you also want to let chmonitor browse user databases (e.g. via the Explorer page), add grants for those databases:

```sql
-- Optional: grant read access to a specific database
GRANT SELECT ON my_database.* TO chmonitor;
```

Do **not** grant `INSERT`, `ALTER`, `DROP`, `CREATE`, or `SYSTEM` privileges. chmonitor does not need them.

### 4. Verify

```sql
SHOW GRANTS FOR chmonitor;
-- Expected: GRANT SELECT ON system.* TO chmonitor

SELECT * FROM system.users WHERE name = 'chmonitor';
```

---

## Altinity Cloud / Altinity.Cloud Stable

Altinity builds are API-compatible with ClickHouse OSS. The same SQL above applies. Run it via the Altinity console SQL editor or through `clickhouse-client` connecting to your Altinity endpoint.

---

## ClickHouse Cloud

ClickHouse Cloud uses the same SQL RBAC model. Use the SQL Console in the Cloud UI or connect with an admin credential.

```sql
-- 1. Settings profile (same as OSS)
CREATE SETTINGS PROFILE IF NOT EXISTS chmonitor_readonly
SETTINGS readonly = 2,
         max_execution_time = 60,
         allow_ddl = 0;

-- 2. User
CREATE USER IF NOT EXISTS chmonitor
IDENTIFIED BY 'replace-with-a-strong-password'
SETTINGS PROFILE 'chmonitor_readonly';

-- 3. Grant
GRANT SELECT ON system.* TO chmonitor;
```

> **Note on system table access in ClickHouse Cloud:** Some `system.*` tables are restricted at certain service tiers (e.g. `system.zookeeper` is not available on Serverless). See [Platform Support Matrix](/reference/support-matrix) for per-table availability across distributions and versions.

---

## Wiring the user into chmonitor

Set these environment variables in your deployment (`.env`, Cloudflare Worker secrets, Kubernetes secret, or Docker env):

| Variable | Value |
|---|---|
| `CLICKHOUSE_HOST` | HTTP URL of your ClickHouse instance, e.g. `http://ch-host:8123` |
| `CLICKHOUSE_USER` | `chmonitor` |
| `CLICKHOUSE_PASSWORD` | The password you set above |
| `CLICKHOUSE_NAME` | Optional display label, e.g. `Production` |

For multiple hosts, use comma-separated values — position N in each variable maps to host N:

```
CLICKHOUSE_HOST=http://ch-1:8123,http://ch-2:8123
CLICKHOUSE_USER=chmonitor,chmonitor
CLICKHOUSE_PASSWORD=secret-1,secret-2
CLICKHOUSE_NAME=Shard 1,Shard 2
```

See [Environment Variables](/reference/environment-variables) for the full variable reference, and [Multiple Hosts](/advanced/multiple-hosts) for multi-host setup.

---

## What chmonitor never does

chmonitor issues only `SELECT` queries against `system.*` tables and any databases you explicitly grant. It never:

- Inserts, updates, or deletes rows
- Creates or drops tables or databases
- Alters table schemas
- Issues `SYSTEM` commands (flush, reload, etc.)

A `readonly = 2` profile enforces this at the ClickHouse level independently of what the application code does.
