Skip to main content

Secure TiDB Access with SSO, TLS, and Auditing

Secure TiDB access with SSO while keeping databases off the public internet, authenticating with short-lived client certificates, and recording every query in the audit log.

Setup takes four steps: create a join token, configure the TiDB server, grant access through AlmaForge RBAC, and connect with native mysql or GUI clients.

info

Running MySQL? See the MySQL database access guide. Running MariaDB? See the MariaDB database access guide.

Prerequisites​

MySQL CLI​

On your computer, check that a MySQL client is installed:

Terminal
mysql --versionmysql  Ver 8.4 ...

On macOS, install a missing client with Homebrew:

Terminal
brew install mysql-client...export PATH="$(brew --prefix mysql-client)/bin:$PATH"mysql --versionmysql  Ver ...

A mariadb client also works.

TiDB server​

This guide uses an existing self-managed TiDB cluster deployed with TiUP, the TiDB cluster management tool. On the TiUP control machine, find the cluster and check its TiDB nodes:

Terminal
tiup cluster listtiup cluster display <cluster-name>

Confirm that the TiDB nodes are Up. The commands use port 4000 and the TiUP deployment user and group tidb. Substitute your deployment user and group if they differ. You need access to the TiUP control machine and sudo on the database hosts.

Install the AlmaForge agent on the TiDB node you want to register. Configure TLS on every TiDB SQL node before enabling the cluster-wide secure-transport requirement below.

AlmaForge CLI​

On your computer, check whether alma is installed:

Terminal
alma version --clientClient Version: v2026.1.0+<build>

If the command is not found, install it:

Terminal
curl -fL https://get.almaforge.com/install.sh | sh...==> AlmaForge installed successfullyalma version --clientClient Version: v2026.1.0+<build>

The installer supports Linux and macOS on both amd64 and arm64.

AlmaForge Cluster​

On your computer, sign in to your cluster and check your permissions:

Terminal
alma login --proxy=almaforge.example.com:443alma status

In the status output, confirm that:

  • Cluster names the cluster you intend to configure.
  • Logged in as shows your account.
  • Roles includes admin.

Step 1. Create AlmaForge join token​

On your computer, create an AlmaForge join token. The database agent uses it to join your AlmaForge cluster:

Terminal
alma create token --services=databaseToken created.  client_id:     <client-id>  client_secret: <client-secret>

Copy client_id and client_secret into the agent configuration in Step 2. They are valid for 30 minutes.

Step 2. Configure the TiDB server​

Install and configure the agent​

The agent is almad with its Database Service enabled.

On the TiDB server, install almad if missing:

Terminal
curl -fL https://get.almaforge.com/install.sh | shalmad versionAlmaForge v2026.1.0+<build>

Open the agent configuration:

Terminal
sudoedit /etc/almaforge/almad.env

almad.env:

/etc/almaforge/almad.env
# Database Service agent on the TiDB host.
# Install at /etc/almaforge/almad.env as root:root with mode 0600.
ALMA_PROXY=almaforge.example.com:443

# Printed by `alma create token --services=database`.
ALMA_CLIENT_ID=paste-client-id-here
ALMA_CLIENT_SECRET=paste-client-secret-here

ALMA_DATABASE_SERVICE=true
ALMA_SSH_SERVICE=false

# Agent labels, separate from the database's labels.
ALMA_LABELS=env=demo

Save the file and restrict permissions:

Terminal
sudo chown root:root /etc/almaforge/almad.envsudo chmod 0600 /etc/almaforge/almad.env

Create the TLS certificates​

On each TiDB SQL node, download the public database CA from your cluster and create a server certificate for local connections. If the node already serves TLS clients, keep its existing server certificate and key, and add the AlmaForge CA to its trusted client CA bundle. Use those existing paths in the TiUP configuration below.

Terminal
curl -fsS -o almaforge-db-ca.pem 'https://almaforge.example.com:443/api/v1/auth/export?type=db'# No output on success.openssl x509 -in almaforge-db-ca.pem -noout# No output means the file contains a valid certificate.sudo install -d -o tidb -g tidb -m 0700 /etc/tidbsudo install -o tidb -g tidb -m 0644 almaforge-db-ca.pem /etc/tidb/ca.pemsudo openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \    -subj '/CN=localhost' \    -addext 'subjectAltName=DNS:localhost,IP:127.0.0.1' \    -keyout /etc/tidb/server.key -out /etc/tidb/server.crtsudo chown tidb:tidb /etc/tidb/server.key /etc/tidb/server.crtsudo chmod 0600 /etc/tidb/server.key

Enable TLS in TiDB​

On the TiUP control machine, open the cluster topology:

Terminal
tiup cluster edit-config <cluster-name>

Merge these settings into the existing server_configs.tidb section. Preserve the other settings and node definitions. If a node overrides these keys in its own config section, update those values too.

tiup-tls.yaml:

examples/databases/tidb/auth/tiup-tls.yaml
# Merge into the topology opened by tiup cluster edit-config.
# Install the certificate files on every TiDB SQL node before reloading.
server_configs:
tidb:
security.ssl-ca: /etc/tidb/ca.pem
security.ssl-cert: /etc/tidb/server.crt
security.ssl-key: /etc/tidb/server.key

Save the topology, then apply it to the TiDB nodes:

Terminal
tiup cluster reload <cluster-name> -R tidbtiup cluster display <cluster-name>

The reload updates the generated configuration and restarts the TiDB nodes. Confirm that every TiDB node returns to Up before continuing.

Create the database account and sample data​

Connect to TiDB as the administrator over TLS and run the setup SQL to create the demo database, certificate-authenticated user, and sample table. The SQL also enables require_secure_transport, which persists across restarts and requires TLS for all TCP clients. Configure any existing clients to use TLS before enabling this setting.

On the TiDB node with the agent, create the setup SQL file:

Terminal
sudoedit /etc/tidb/init.sql

Paste the following SQL, then save and close the editor:

init.sql:

/etc/tidb/init.sql
-- Create sample database, user, and data for AlmaForge access.
SET GLOBAL require_secure_transport = ON;
CREATE DATABASE IF NOT EXISTS demo;
CREATE USER IF NOT EXISTS 'demo'@'%' REQUIRE SUBJECT '/CN=demo';
GRANT ALL ON demo.* TO 'demo'@'%';
CREATE TABLE IF NOT EXISTS demo.demo (id INT PRIMARY KEY, name VARCHAR(100));
INSERT IGNORE INTO demo.demo VALUES (1, 'alice'), (2, 'bob'), (3, 'carol');
Terminal
sudo chown root:root /etc/tidb/init.sqlsudo chmod 0600 /etc/tidb/init.sqlsudo sh -c 'mysql -h 127.0.0.1 -P 4000 -u root -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/tidb/server.crt < /etc/tidb/init.sql'

Use the MySQL 8 client on the database server for this command. Enter the database administrator's password when prompted. The privileged shell opens the SQL file inside the protected directory, and the client verifies the server certificate before sending credentials or SQL.

Register TiDB with the agent​

On the TiDB node with the agent, print the server certificate:

Terminal
sudo cat /etc/tidb/server.crt-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----

Create the target registration file:

Terminal
sudo install -d -o root -g root -m 0700 /etc/almaforge/almad.dsudoedit /etc/almaforge/almad.d/tidb.yaml

Paste the example below. Replace the caCert placeholder with the complete server certificate, including the BEGIN and END lines, and preserve the indentation under caCert: |. If you kept an existing server certificate, use its issuing CA certificate and the corresponding file path instead.

target.yaml.in:

/etc/almaforge/almad.d/tidb.yaml
# TiDB target for an agent running on the database server.
# Replace caCert with the complete server certificate or its issuing CA.
apiVersion: almaforge.com/v1
kind: DatabaseTarget
metadata:
name: tidb
labels:
db: tidb
env: demo
spec:
protocol: mysql
uri: 127.0.0.1:4000
tls:
caCert: |
<paste the complete server certificate here>

Save the file, restrict it to root, and restart the agent:

Terminal
sudo chown root:root /etc/almaforge/almad.d/tidb.yamlsudo chmod 0600 /etc/almaforge/almad.d/tidb.yamlsudo systemctl enable --now almadsudo systemctl restart almadsystemctl is-active almadactive

Step 3. Grant access​

On your computer, confirm the database is registered:

Terminal
alma get dbHost             Name            Protocol       URI                 Labels             Version---------------- --------------- -------------- ------------------- ------------------ --------<database-host>  tidb            mysql          127.0.0.1:4000      db=tidb ...        2026.1.0

Download and apply the access role:

tidb-access.yaml:

tidb-access.yaml
# Access to the TiDB target as the shared demo user.
apiVersion: almaforge.com/v1
kind: Role
metadata:
name: tidb-access
spec:
allow:
databaseLabels:
db: tidb
databaseUsers:
- demo

Apply it:

Terminal
alma apply -f tidb-access.yamlrole 'tidb-access' has been created

Creating the role does not assign it to anyone. To grant it to an SSO group, list your connectors:

Terminal
alma get oidcKind          Name------------- -----------OIDCConnector company-sso

Find the connector your team uses to sign in. Replace <connector-name> with its name from the output, then open it in your text editor:

Terminal
alma edit oidc/<connector-name># Your text editor opens. After saving your changes:oidc connector "<connector-name>" has been updated

Under spec.claimsToRoles, find the entry for the group that should have TiDB access. Add tidb-access to that entry's roles list. Preserve the existing roles and mappings, then save and close the editor.

Step 4. Connect​

On your computer, refresh your credentials:

Terminal
alma logoutalma login --proxy=almaforge.example.com:443alma status

Confirm Roles includes tidb-access. Then connect with alma db connect:

Terminal
alma db connect --db-user=demo --db-name=demo tidb...mysql> SELECT CURRENT_USER(), DATABASE();+----------------+------------+| CURRENT_USER() | DATABASE() |+----------------+------------+| demo@%         | demo       |+----------------+------------+mysql> SELECT name FROM demo WHERE id = 1;+-------+| name  |+-------+| alice |+-------+

Type exit to disconnect.

Advanced configuration​

GUI clients and scripts​

Open an authenticated tunnel for GUI clients or scripts:

Terminal
alma proxy db --tunnel --db-user=demo --db-name=demo tidbStarted authenticated tunnel for the TiDB database "tidb" in cluster "almaforge.example.com" on 127.0.0.1:54321.

Connect your client to 127.0.0.1:54321 over plain TCP. The tunnel authenticates to AlmaForge, and the agent presents the user certificate to TiDB.

Architecture​

The database agent runs beside TiDB and opens an outbound tunnel to the AlmaForge Proxy. TiDB listens on port 4000 and trusts the agent's client certificates.

TiDB database access topology

Troubleshooting​

Database is missing or has no host​

Check /etc/almaforge/almad.d/tidb.yaml and ALMA_DATABASE_SERVICE=true in /etc/almaforge/almad.env on the database server. Inspect the agent log:

Terminal
sudo journalctl -u almad -n 50 --no-pager

Access is denied​

Run alma status and verify tidb-access appears in your roles. Ensure the role's databaseLabels match the target labels.

Limitations​

  • TiDB does not support MySQL stored procedures, so AlmaForge cannot dynamically provision database accounts per login. All connections authenticate as the shared certificate-authenticated demo user.
  • AlmaForge does not enforce databaseNames restrictions for MySQL-protocol databases. Use TiDB SQL grants to restrict databases and tables.

References​