Secure Elasticsearch Access with SSO, TLS, and Auditing
Secure Elasticsearch access with SSO while keeping clusters off the public internet, authenticating with short-lived client certificates, and recording every request in the audit log.
Setup takes four steps: create a join token, configure the Elasticsearch server, grant access through AlmaForge RBAC, and connect with native clients or the REST API.
Prerequisites
Elasticsearch CLI
On your computer, check Java, which the SQL client requires:
java -versionopenjdk version "27" 2026-09-15OpenJDK Runtime Environment Homebrew (build 27)OpenJDK 64-Bit Server VM Homebrew (build 27, mixed mode, sharing)If it is missing:
brew install openjdk...==> Summary...export PATH="$(brew --prefix openjdk)/bin:$PATH"java -versionopenjdk version "27" 2026-09-15OpenJDK Runtime Environment Homebrew (build 27)OpenJDK 64-Bit Server VM Homebrew (build 27, mixed mode, sharing)export prints nothing. Add that line to ~/.zshrc to keep the PATH
setting. You will copy the matching SQL client from the database server
after installing Elasticsearch.
For Linux, install Java through your distribution's package manager.
Elasticsearch server
On your computer, open a second terminal and SSH into the database
server. Replace <ssh-user> and <database-host> with your SSH
account and server address:
ssh <ssh-user>@<database-host>...[<ssh-user>@<database-host> ~]$On the database server, check that you can run administrator commands, then check the operating system and installed database package:
sudo -v# No output on success. A password prompt may appear first.grep -E '^(ID_LIKE|VERSION_ID)=' /etc/os-releaseID_LIKE="rhel centos fedora"VERSION_ID="9.8"rpm -q elasticsearchelasticsearch-9.5.4-1.x86_64sudo -v must succeed. If the package check says Elasticsearch is not
installed, install it from the Elastic package repository before continuing.
Otherwise, the command prints its version.
Use an RPM-based Linux host with dnf for this example.
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 and repeat the check:
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. See CLI installation for package-specific options.
AlmaForge Cluster
On your computer, sign in to your cluster and check your permissions.
Get your cluster's hostname from its administrator. If you do not have
an AlmaForge cluster yet, complete the
standalone deployment before continuing.
Replace almaforge.example.com below with that hostname. Run the login command
and complete the sign-in in your browser:
alma login --proxy=almaforge.example.com:443...
> Profile URL: https://almaforge.example.com:443
Logged in as: [email protected]
Cluster: almaforge.example.com
Roles: admin
...
After signing in, check your account and roles:
alma status> Profile URL: https://almaforge.example.com:443
Logged in as: [email protected]
Cluster: almaforge.example.com
Roles: admin
...
In the status output, check that:
Clusternames the cluster you intend to configure.Logged in asshows your account.Rolesincludesadmin.
If admin is missing, ask a cluster administrator to grant that role,
then run alma logout and repeat
the login and status commands. Continue once 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:
alma create token --services=databaseToken created. client_id: <client-id> client_secret: <client-secret>You will copy client_id and client_secret into the agent configuration
in Step 2. They are valid for 30 minutes. If they expire before the agent
joins, create a new token and use its values.
Step 2. Configure the Elasticsearch server
Install and configure the agent
The agent is almad with its Database Service enabled. It
connects outward to your cluster on port 443 and carries connections
between users and Elasticsearch.
On the Elasticsearch server, check whether almad is installed:
almad versionAlmaForge v2026.1.0+<build>If the command is not found, install the AlmaForge package:
curl -fL https://get.almaforge.com/install.sh | sh...==> AlmaForge installed successfullyalmad versionAlmaForge v2026.1.0+<build>On an RPM-based system, the installer uses the RPM package and installs the
almad systemd service. It supports both amd64 and arm64.
The version command must succeed before you configure the agent.
For other Linux distributions, see
Linux package installation.
Already running an agent on this host?
Keep its existing settings and enable ALMA_DATABASE_SERVICE=true.
Preserve the other services and label selectors. The join credentials
must permit the database service. The local target created below
does not need a label selector.
On the Elasticsearch server, open the agent configuration:
sudoedit /etc/almaforge/almad.env# Your text editor opens.For a new agent, enter the settings below. Replace ALMA_PROXY with
your cluster's hostname and port 443. Set ALMA_CLIENT_ID and
ALMA_CLIENT_SECRET to the values from Step 1:
# Database Service agent on the Elasticsearch 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 close the editor. Restrict it to root because it contains the join credentials:
sudo chown root:root /etc/almaforge/almad.env# No output on success.sudo chmod 0600 /etc/almaforge/almad.env# No output on success.Create the TLS certificates
The agent and Elasticsearch run on the same server. Their connection uses the
loopback interface (localhost, or 127.0.0.1), so this traffic stays
on that server. A self-signed certificate for localhost is sufficient.
You do not need a public hostname or a certificate from a public CA.
Elasticsearch uses the AlmaForge database CA to verify client certificates presented by the agent.
Keep running these commands on the Elasticsearch server.
Download your cluster's public database CA. Replace almaforge.example.com
with your cluster's hostname:
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 root -g elasticsearch -m 0750 /etc/elasticsearch/certsCreate a self-signed server certificate and private key for localhost:
sudo openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \ -subj '/CN=localhost' \ -addext 'subjectAltName=DNS:localhost,IP:127.0.0.1' \ -keyout /etc/elasticsearch/certs/server.key -out /etc/elasticsearch/certs/server.crt...-----sudo chown root:elasticsearch /etc/elasticsearch/certs/server.key /etc/elasticsearch/certs/server.crt# No output on success.sudo chmod 0640 /etc/elasticsearch/certs/server.key# No output on success.sudo sh -c 'cat almaforge-db-ca.pem /etc/elasticsearch/certs/server.crt > /etc/elasticsearch/certs/clients.pem'sudo chown root:elasticsearch /etc/elasticsearch/certs/clients.pemsudo chmod 0644 /etc/elasticsearch/certs/clients.pem# No output on success.Enable TLS in Elasticsearch
Keep the password for the existing elastic administrator available for
creating the sample index. If you do not have it, reset it while the
server is still running with its existing TLS configuration:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password --username elastic --interactiveEnter a new password at the prompt and store it in your password manager.
This changes the elastic account's password, so update any other clients
that use that account.
Open /etc/elasticsearch/roles.yml and add the following role. Preserve
any existing role definitions. It permits reading only the demo index:
sudoedit /etc/elasticsearch/roles.yml# Grant the certificate-authenticated REST connection read access to demo.
alma_demo_reader:
indices:
- names: [demo]
privileges: [read, view_index_metadata]
Open /etc/elasticsearch/elasticsearch.yml on the server:
sudoedit /etc/elasticsearch/elasticsearch.yml# Your text editor opens.Replace the existing xpack.security.http.ssl block with the PEM settings
below, and add the anonymous authentication settings. Remove any HTTP TLS
keystore.path, truststore.path, keystore.password,
keystore.key_password, and truststore.password settings from the old
block. The PEM key and certificate cannot be combined with the old stores.
Preserve the existing xpack.security.transport.ssl settings, which
protect communication between Elasticsearch nodes.
# Elasticsearch TLS and anonymous read access for AlmaForge.
# Merge into /etc/elasticsearch/elasticsearch.yml.
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key: /etc/elasticsearch/certs/server.key
xpack.security.http.ssl.certificate: /etc/elasticsearch/certs/server.crt
xpack.security.http.ssl.certificate_authorities:
[/etc/elasticsearch/certs/clients.pem]
xpack.security.http.ssl.client_authentication: required
xpack.security.authc.anonymous.username: anonymous
xpack.security.authc.anonymous.roles: alma_demo_reader
xpack.security.authc.anonymous.authz_exception: true
Save the file. List the secure setting names in the Elasticsearch keystore:
sudo /usr/share/elasticsearch/bin/elasticsearch-keystore listRemove each of these HTTP TLS store entries if it appears in the list:
xpack.security.http.ssl.keystore.secure_passwordxpack.security.http.ssl.keystore.secure_key_passwordxpack.security.http.ssl.truststore.secure_password
For each listed entry, replace <setting-name> below with that name:
sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove <setting-name>Keep transport TLS entries and all other secure settings. Restart Elasticsearch after removing the obsolete HTTP store settings:
sudo systemctl restart elasticsearch# No output on success.systemctl is-active elasticsearchactiveCreate the sample index and documents as the elastic administrator.
Each command prompts for its password. Connections through AlmaForge
use the anonymous read role and cannot create or modify these documents:
sudo curl -fsS --user elastic --cacert /etc/elasticsearch/certs/server.crt \ --cert /etc/elasticsearch/certs/server.crt \ --key /etc/elasticsearch/certs/server.key \ -H 'Content-Type: application/json' -X PUT https://localhost:9200/demo/_doc/1 -d '{"name": "alice"}'sudo curl -fsS --user elastic --cacert /etc/elasticsearch/certs/server.crt \ --cert /etc/elasticsearch/certs/server.crt \ --key /etc/elasticsearch/certs/server.key \ -H 'Content-Type: application/json' -X PUT https://localhost:9200/demo/_doc/2 -d '{"name": "bob"}'sudo curl -fsS --user elastic --cacert /etc/elasticsearch/certs/server.crt \ --cert /etc/elasticsearch/certs/server.crt \ --key /etc/elasticsearch/certs/server.key \ -H 'Content-Type: application/json' -X PUT https://localhost:9200/demo/_doc/3 -d '{"name": "carol"}'Register Elasticsearch with the agent
Still on the Elasticsearch server, display the public server certificate:
sudo cat /etc/elasticsearch/certs/server.crt-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----Copy the entire certificate, including the BEGIN and END lines.
The agent uses it to verify Elasticsearch. Then open the target configuration:
sudo install -d -o root -g root -m 0700 /etc/almaforge/almad.d# No output on success.sudoedit /etc/almaforge/almad.d/elasticsearch.yaml# Your text editor opens.For a new file, copy the following YAML. If the file already exists,
update the existing resource and preserve its other settings. Replace
<paste the complete server certificate here> with the certificate you
copied. Indent every certificate line by six spaces beneath caCert: |:
# Connect the local Elasticsearch HTTPS listener through AlmaForge.
# Replace the placeholder with the contents of /etc/elasticsearch/certs/server.crt.
apiVersion: almaforge.com/v1
kind: DatabaseTarget
metadata:
name: elasticsearch
labels:
db: elasticsearch
env: prod
spec:
protocol: elasticsearch
uri: localhost:9200
tls:
caCert: |
<paste the complete server certificate here>
Check that the certificate includes both its BEGIN and END lines,
then save the file and close the editor. Restrict the file to root:
sudo chown root:root /etc/almaforge/almad.d/elasticsearch.yaml# No output on success.sudo chmod 0600 /etc/almaforge/almad.d/elasticsearch.yaml# No output on success.Start and check the agent
Enable the services at boot and start the agent:
sudo systemctl enable elasticsearch almad...sudo systemctl restart almad# No output on success.systemctl is-active elasticsearch almadactiveactiveBoth services must report active. If either fails, inspect its log:
sudo journalctl -u elasticsearch -u almad -n 50 --no-pager...<date> <time> <database-host> almad[<pid>]: <log-message>...Resolve any reported errors before continuing. The agent reads the
target configuration at startup, so restart almad after
changing /etc/almaforge/almad.d/elasticsearch.yaml.
Install the SQL client
On the Elasticsearch server, check the installed package version:
rpm -q elasticsearchelasticsearch-9.5.4-1.x86_64On your computer, copy the matching SQL client JAR. Replace
<ssh-user> and <database-host> with the account and address used
above. If your server version differs, replace 9.5.4 in both the
copy command and the launcher below:
mkdir -p "$HOME/.local/share/elasticsearch-sql-cli" "$HOME/.local/bin"export PATH="$HOME/.local/bin:$PATH"scp <ssh-user>@<database-host>:/usr/share/elasticsearch/bin/elasticsearch-sql-cli-9.5.4.jar \ "$HOME/.local/share/elasticsearch-sql-cli/"elasticsearch-sql-cli-9.5.4.jar 100% ...mkdir and export print nothing. Keep the export line in ~/.zshrc
for future terminals. Create the launcher:
cat > "$HOME/.local/bin/elasticsearch-sql-cli" <<'EOF'#!/bin/shexec java --enable-native-access=ALL-UNNAMED -jar "$HOME/.local/share/elasticsearch-sql-cli/elasticsearch-sql-cli-9.5.4.jar" "$@"EOFchmod 0755 "$HOME/.local/bin/elasticsearch-sql-cli"Both commands finish without output. The Java option lets the client's terminal library run on modern Java. Check the launcher:
elasticsearch-sql-cli --helpElasticsearch SQL CLI
Non-option arguments:uri
Option Description------ -----------...-h, --help Show help...The command must print its usage and options without a Java or file-not-found error. The Elasticsearch SQL CLI reference describes the standalone client.