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.
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:
mysql --versionmysql Ver 8.4 ...On macOS, install a missing client with Homebrew:
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:
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:
alma version --clientClient Version: v2026.1.0+<build>If the command is not found, install it:
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:
alma login --proxy=almaforge.example.com:443alma statusIn the status output, confirm that:
Clusternames the cluster you intend to configure.Logged in asshows your account.Rolesincludesadmin.
Step 1. Create AlmaForge join token
On your computer, create an AlmaForge join token. The database agent uses it to join your AlmaForge cluster:
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:
curl -fL https://get.almaforge.com/install.sh | shalmad versionAlmaForge v2026.1.0+<build>Open the agent configuration:
sudoedit /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:
sudo chown root:root /etc/almaforge/almad.envsudo chmod 0600 /etc/almaforge/almad.envCreate 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.
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.keyEnable TLS in TiDB
On the TiUP control machine, open the cluster topology:
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.
# 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:
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:
sudoedit /etc/tidb/init.sqlPaste the following SQL, then save and close the editor:
-- 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');
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:
sudo cat /etc/tidb/server.crt-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----Create the target registration file:
sudo install -d -o root -g root -m 0700 /etc/almaforge/almad.dsudoedit /etc/almaforge/almad.d/tidb.yamlPaste 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.
# 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:
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 almadactiveStep 3. Grant access
On your computer, confirm the database is registered:
alma get dbHost Name Protocol URI Labels Version---------------- --------------- -------------- ------------------- ------------------ --------<database-host> tidb mysql 127.0.0.1:4000 db=tidb ... 2026.1.0Download and apply the access role:
# 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:
alma apply -f tidb-access.yamlrole 'tidb-access' has been createdCreating the role does not assign it to anyone. To grant it to an SSO group, list your connectors:
alma get oidcKind Name------------- -----------OIDCConnector company-ssoFind the connector your team uses to sign in. Replace <connector-name>
with its name from the output, then open it in your text editor:
alma edit oidc/<connector-name># Your text editor opens. After saving your changes:oidc connector "<connector-name>" has been updatedUnder 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:
alma logoutalma login --proxy=almaforge.example.com:443alma statusConfirm Roles includes tidb-access. Then connect with alma db connect:
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:
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.
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:
sudo journalctl -u almad -n 50 --no-pagerAccess 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
demouser. - AlmaForge does not enforce
databaseNamesrestrictions for MySQL-protocol databases. Use TiDB SQL grants to restrict databases and tables.
References
- Database access overview: architecture and supported databases.
- MySQL access guide: MySQL-protocol configuration.
- RBAC reference: database access fields on a role.
- Declarative configuration: the
DatabaseTargetschema.