This walks a DBA through creating a read-only MySQL user in about ten minutes. Every query climpt runs is a SELECT, transit is TLS-encrypted, and the credentials are held in Google Secret Manager.
What your auditor will ask
- Read-only — enforced by MySQL grants, not by climpt’s behaviour. The account holds
SELECTand nothing else. - TLS in transit —
sslMode=REQUIRED, TLS 1.2 or 1.3. Plaintext connections are refused on our side. - Server certificate verification is not performed today. Transit is encrypted but we do not pin your server certificate. VERIFY_CA support is on the roadmap.
- One egress IP to allow — our Trino query VM, a dedicated GCE host.
- Auditability — every query appears in your own general and slow query logs.
Credentials
- Host
- DNS name or IP, for example
mysql.example.com. - Port
3306unless you have changed it.- Database
- Optional. Sets the default schema in the interface — what is actually visible is decided by the user’s grants, not by this field.
- Username
climpt_readonly, the user created below.- Password
- Encrypted at rest in Google Secret Manager.
You do not need to supply a CA certificate, a client certificate or a JDBC URL — those are configured on our side.
Setup
- Allow our query engine on port 3306. Your climpt contact will give you a single static IPv4 address. That address is our Trino query VM, not the climpt web application. Replace
<CLIMPT_IP>with it throughout. The connection is inbound to your database, outbound from our VM. - Create a dedicated read-only user. The syntax below follows the version you select.
- Grant SELECT on the databases you want analysed. Repeat per database. Add
SHOW VIEWonly if your schema uses views. - Cap resource usage so a runaway query cannot affect production.
- Confirm TLS is on — nearly always already true on managed MySQL.
- Test from outside your VPC before handing over the credentials.
Creating the user
Not sure? Run SELECT VERSION(); on the server. The 8.x block also works on MySQL 8.4.
CREATE USER 'climpt_readonly'@'<CLIMPT_IP>'
IDENTIFIED BY 'strong_password_here'
REQUIRE SSL;No auth plugin is pinned on purpose. MySQL 8.0 defaults to caching_sha2_password and 8.4 ships with mysql_native_password disabled, so pinning either one breaks on the other. Because we connect with sslMode=REQUIRED, the encrypted channel covers the caching-sha2 handshake and there is no public-key-retrieval problem. REQUIRE SSL is valid inline on every 8.x release.
Some hardened configurations require it. Use IDENTIFIED WITH caching_sha2_password on 8.4, and IDENTIFIED WITH mysql_native_password only on 8.0. Tell us which version you are on and we will confirm.
Grants
Identical on both versions.
GRANT SELECT ON analytics.* TO 'climpt_readonly'@'<CLIMPT_IP>';
-- Only if your schema uses views:
GRANT SHOW VIEW ON analytics.* TO 'climpt_readonly'@'<CLIMPT_IP>';
FLUSH PRIVILEGES;Do not grant ALL, SUPER, PROCESS, FILE or RELOAD. climpt does not use any of them.
Resource limits
ALTER USER 'climpt_readonly'@'<CLIMPT_IP>'
WITH MAX_USER_CONNECTIONS 50
MAX_QUERIES_PER_HOUR 5000;Schema discovery opens several connections in parallel, so keep MAX_USER_CONNECTIONS at 50 or above. A MAX_QUERIES_PER_HOUR below 1,000 will interrupt an analysis mid-conversation.
Verifying before you hand over credentials
SHOW VARIABLES LIKE 'have_ssl'; -- expect YES
SHOW VARIABLES LIKE 'tls_version'; -- expect TLSv1.2 or TLSv1.3Then check the account from outside your database VPC — a laptop on a cellular tether works — because that is how our VM reaches you. A returned row means the climpt form will work.
mysql -h <your_host> -P 3306 -u climpt_readonly -p --ssl-mode=REQUIRED -e "SELECT VERSION(), CURRENT_USER();"Managed MySQL by platform
- AWS RDS — security group inbound rule, TCP 3306 from
<CLIMPT_IP>/32. TLS is on by default. - Google Cloud SQL — add
<CLIMPT_IP>/32under Authorized Networks and enable “Allow only SSL connections”. New instances default to MySQL 8.4, wheremysql_native_passwordis disabled, so use the 8.x block above unchanged. The Cloud SQL Auth Proxy is not supported. - Azure Database for MySQL — add an inbound firewall rule for
<CLIMPT_IP>. “Allow Azure services” on its own is not enough. - Private-only databases behind PrivateLink, a bastion or VPC peering — talk to us before going further and we will arrange a private endpoint or a read replica.
Behaviour worth knowing
- Character set. If your tables are
latin1rather thanutf8mb4, some tools garble non-ASCII data. We negotiate UTF-8 on the wire, so Turkish, Arabic and other scripts render correctly. - Time zone. An unrecognised
@@time_zonemakes timestamp conversion fail.UTCor a numeric offset like+03:00is safest. TINYINT(1)columns come back as 0 and 1, not booleans. If you use them as flags, that is expected.- Host scope.
'climpt_readonly'@'<CLIMPT_IP>'is the production setting.'%'is fine while testing, but lock it to the IP before go-live — an auditor will flag the wildcard.