ManagementGuideService ExamplesDatabases
Zero Trust Access to MySQL with SSO

Octelium provides unified, seamless, zero trust, secretless access, for both HUMAN and WORKLOAD Users (read more about Users here), to any private/internal on-prem MySQL-based database behind NAT as well as to any publicly protected SaaS MySQL-based database (read more about MYSQL Services here) without having to share and manage passwords (read more about secretless access here). Octelium provides the following:

  • Secretless access for all Users to all MySQL-based databases without sharing and distributing the database passwords to your Users.
  • Identity-based, context-aware dynamic routing to different database hosts, users and passwords representing different contexts and privileges.
  • Centralized identity-based, application-layer (L7) aware access control (read more about access control here).
  • Enforce dynamic SSO, Hardware-based FIDO2 Passkey/WebAuthn authentication for your Users to access sensitive/production databases.
  • OpenTelemetry-native, identity-based, L7 aware visibility and auditing that captures requests and responses including serialized JSON body content.
  • Seamless horizontal scalability and availability since Octelium operates on top of Kubernetes (read more about how Octelium works here).
  • GitOps-friendly declarative, programmable management (read more here).

A Simple Example

In this guide we are going to provide access to an internal MySQL database (check out an example guide for a SaaS MySQL-based database such as PlanetScale here). First, we need to create a Secret for the MySQL database's password as follows:

octeliumctl create secret mysql-db-password

Now we create the Service for our database as follows:

1
kind: Service
2
metadata:
3
name: mysql-db
4
spec:
5
mode: MYSQL
6
port: 3306
7
config:
8
upstream:
9
url: mysql://my-db.local
10
mysql:
11
user: root
12
database: mysql
13
auth:
14
password:
15
fromSecret: mysql-db-password
NOTE

If the upstream is listening over TLS, then you can enable the TLS mode as shown in detail here.

NOTE

The example above shows an upstream that is directly accessible by the Cluster. You can also remotely serve upstreams behind NAT from anywhere as shown in detail here.

You can now apply the creation of the Service as follows (read more here):

octeliumctl apply /PATH/TO/SERVICE.YAML

Now after connecting to the Cluster via the octelium connect command (read more about connecting to Clusters here), you can simply access the database whose hostname is at mysql-db.default or simply mysql-db (read more here) as follows:

mysql -h mysql-db

You can also connect via the rootless mode and map the Service to your host's localhost (read more here) as follows:

# Connect as non-root/unprivileged OS user
octelium connect -p mysql-db:3306
# Now access the Service at localhost
mysql -h localhost

Dynamic Configuration

You can also provide dynamic secretless access where you can set different users, databases and passwords for different Users under different contexts. Read more about dynamic configuration here. Here is an example where Users are dynamically assigned to different MySQL users with different privileges based on their identity.

For example, you could create a full_access user for full access as follows:

1
CREATE USER 'full_access'@'localhost' IDENTIFIED BY '<YOUR_PASSWORD>';
2
GRANT ALL PRIVILEGES ON my_db.* TO 'full_access'@'localhost';
3
FLUSH PRIVILEGES;

And another read_only user for read-only as follows:

1
-- Create the user
2
CREATE USER 'read_only'@'localhost' IDENTIFIED BY '<YOUR_OTHER_PASSWORD>';
3
GRANT SELECT, SHOW VIEW ON my_db.* TO 'read_only'@'localhost';
4
FLUSH PRIVILEGES;

Now you define the Service so that more privileged Users belonging to either of engineering or admins Groups to automatically be assigned to the full_access user, and other Users (e.g. junior engineers, AI agents) are assigned to the read_only user as follows:

1
apiVersion: core/v1
2
kind: Service
3
metadata:
4
name: my-db
5
spec:
6
mode: MYSQL
7
port: 3306
8
dynamicConfig:
9
configs:
10
- name: read-only
11
upstream:
12
url: mysql://my-pg:3306
13
mysql:
14
user: read_only
15
database: my_db
16
auth:
17
password:
18
fromSecret: read-only-password
19
sslMode: REQUIRE
20
- name: full-access
21
upstream:
22
url: mysql://my-pg:3306
23
mysql:
24
user: full_access
25
database: my_db
26
auth:
27
password:
28
fromSecret: full-access-password
29
rules:
30
- condition:
31
match: ctx.user.spec.groups.hasAny(["engineering", "admins"])
32
configName: full-access
33
- condition:
34
matchAny: true
35
configName: read-only
NOTE

You might also want to read about Octelium's MySQL L7 aware access control here and access logs here

Authentication

HUMAN Users can use their emails to authenticate to the Cluster via web browsers using IdentityProviders. There currently 3 methods:

  • GitHub OAuth IdentityProvider as shown in detail here
  • OpenID Connect IdentityProviders (e.g. Okta, Auth0, etc...) as shown here.
  • SAML 2.0 IdentityProviders (e.g. Okta, Entra ID, etc...) as shown here.

Furthermore, HUMAN Users can register their FIDO2 Authenticators (e.g. Yubikeys) in order to natively login later via Passkey (read more here).

NOTE

You can read more about Authenticators and WebAuthn/TOTP MFA as shown here.

For WORKLOAD Users, they can authenticate themselves via the octelium login or octeliumctl login commands using various ways:

  • OAuth2 client credentials (read more here)
  • "Secretless" OpenID Connect identity assertions which can be used by octelium CLIs and containers running in cloud providers, GitHub Action runners, Kubernetes clusters, etc... (read more here).
  • Access tokens directly issued and used as bearer authentication tokens (read more here).

Visibility

Octelium also provides OpenTelemetry-ready, application-layer L7 aware visibility and access logging in real time (see an example for MySQL here). You can read more about visibility here.

1
{
2
"apiVersion": "core/v1",
3
"kind": "Log",
4
"metadata": {
5
// Omitted for the sake of brevity of the example
6
},
7
"entry": {
8
"service": {
9
"info": {
10
"common": {
11
"status": "ALLOWED"
12
// Omitted for the sake of brevity of the example
13
},
14
"mysql": {
15
"query": {
16
"query": "CREATE DATABASE db01;"
17
},
18
"type": "QUERY"
19
}
20
}
21
// Omitted for the sake of brevity of the example
22
}
23
}
24
}
© 2026 octelium.comOctelium Labs, LLCAll rights reserved
Octelium and Octelium logo are trademarks of Octelium Labs, LLC.
WireGuard is a registered trademark of Jason A. Donenfeld