Mandatory Mutual TLS¶
A secure 3forge Enterprise server accepts only authenticated, authorized SSL clients. On the listeners below, configuring an SSL keystore makes client authentication mandatory and impossible to turn off, there is no toggle. Every external client must present a certificate whose public key is listed in the server's authorized-clients file, keys/3forge.auth, or the connection is rejected at the TLS handshake. (A listener with no keystore stays plain TCP.) Browser-facing listeners behave differently: the Web HTTPS listener and the developer-tools WebSocket serve server-side TLS from a keystore alone and authenticate at the Basic or cookie layer instead.
The design reuses Enterprise's existing ssh-rsa .pub key machinery: no PKI or certificate authority is required, and self-signed certificates work, only the public key is pinned.
Secure Listeners¶
| Listener | Default port | Keystore property | Authorized-clients property |
|---|---|---|---|
| Center | 3270 |
ami.center.ssl.keystore.file |
ami.center.ssl.authorized.clients.file |
| JDBC | 3280 |
ami.db.jdbc.ssl.keystore.file |
ami.db.jdbc.ssl.authorized.clients.file |
| Relay | 3289 |
ami.port.keystore.file |
ami.port.ssl.authorized.clients.file |
| Gateway | 3406 |
ami.gateway.ssl.keystore.file |
ami.gateway.ssl.authorized.clients.file |
| Gateway JDBC | 3407 |
ami.gateway.jdbc.ssl.keystore.file |
ami.gateway.jdbc.ssl.authorized.clients.file |
Provisioning a Client¶
The allowlist is read once, at startup
The server builds its SSL context, and reads the allowlist, when it starts. Adding or removing a key has no effect until restart. Stage key changes with maintenance windows.
Self-Authorizing Bootstrap¶
The server auto-generates its own keystore and .pub on first start and always seeds its own key into the allowlist (creating the file if absent). So a fresh secure instance boots in one pass, and its in-process connections (relay→center, web→center, gateway routes, replication) work with no manual setup. External clients are never auto-added, provision them as above.
Client-Side Enablement¶
Each client family points at its client certificate and key; private keys never leave the machine that owns them, only .pub lines are exchanged.
| Client | How to enable |
|---|---|
| Python | client_cert_file / client_key_file (plus optional trusted_server_pub_file) on each shard's SSL options, or as DB-API / SQLAlchemy parameters |
| ODBC | SSL_CLIENT_CERT_FILE / SSL_CLIENT_KEY_FILE (optional SSL_SERVER_PUB_FILE) |
| Excel RTD | client_cert_file / client_key_file per shard in ami_rtd_config.json |
| C++ | Shard::ssl |
Windows Note¶
PowerShell 5.1 > redirection writes UTF-16 with a BOM, which breaks ssh-keygen -i. Use ssh-keygen -y -f client.key.pem, or let openssl write files with -out.
Related¶
- Security Defaults: where mutual TLS fits among the shipped security defaults.
- AI Agent Access (MCP) → transport security: trusting the self-signed certificate for an HTTPS MCP client, and regenerating the keystore with a matching SAN.