Skip to content

Configure TLS between AGS and Aerospike Database

The example on this page demonstrates how to encrypt communication between Aerospike Graph Service (AGS) and the Aerospike Database cluster. AGS-to-Database TLS protects vertex and edge data as it moves between the graph layer and storage layer.

Generate certificates

The example includes a script that creates certificates for both AGS and the Aerospike Database server.

  1. Navigate to the AGS-to-AerospikeDB directory.

    Terminal window
    cd ../AGS-to-AerospikeDB
  2. Run the certificate generation script.

    Terminal window
    ./make-certs.sh
    Example response
    Checking system for openssl command.
    /usr/bin/openssl
    Found OpenSSL 3.0.0 7 sep 2021
    Generating CA key 'security/ca.key'.
    Generating self-signed CA cert 'security/ca.crt'.
    Generating server key 'security/server.key'.
    Signing server CSR with CA.
    Signing server CERT with CA.
    Removing intermediate files.
    Files generated:
    ca.key — your CA private key
    ca.crt — your CA certificate
    server.key — your server private key
    server.crt — your server certificate

    If the script lacks execute permissions, enable them and rerun the command:

    Terminal window
    chmod +x make-certs.sh
    ./make-certs.sh

    All certificates are created in the security/ directory.

Understanding the Aerospike Database configuration

The aerospike.conf file defines a TLS context and enables TLS for client connections.

Key configuration elements:

service {
cluster-name exampleCluster
}
network {
tls exampleCluster {
ca-file /opt/aerospike/etc/ca.crt
cert-file /opt/aerospike/etc/server.crt
key-file /opt/aerospike/etc/server.key
}
service {
port 3000 # Non-TLS port
tls-port 4000 # TLS port for client connections
tls-name exampleCluster
tls-authenticate-client false
}
fabric {
tls-port 4001 # TLS port for inter-node fabric
tls-name exampleCluster
}
}

What each block does:

  • cluster-name exampleCluster and the matching tls exampleCluster { ... } block bind the TLS assets to a logical name. Aerospike clients reference that name when they connect over TLS.
  • tls defines where Aerospike finds the CA (ca-file), certificate (cert-file), and private key (key-file). If any path is wrong, the database refuses to start.
  • service exposes two ports: port 3000 for legacy/plaintext traffic and tls-port 4000 for TLS. Setting tls-name exampleCluster tells the service block which TLS context to load, and tls-authenticate-client false keeps client authentication disabled (matching the current AGS support matrix).
  • fabric reuses the same TLS context for inter-node messaging on port 4001, ensuring replication and cluster-status traffic between Aerospike nodes is encrypted just like client traffic.

Understanding the Docker configuration

The docker-compose.yaml file mounts the certificates into both containers and configures AGS to connect via TLS.

For the database container:

volumes:
# Mount certificates into the database container
- ./security:/opt/aerospike/etc/
# Mount custom configuration file
- ./aerospike.conf:/opt/aerospike/etc/aerospike.conf
command: ["--config-file", "/opt/aerospike/etc/aerospike.conf"]

Mounting the entire security/ directory into /opt/aerospike/etc/ gives the database container read-only access to every certificate the config references, while the custom aerospike.conf replaces the stock configuration with one that enables TLS.

For the AGS container:

volumes:
# Mount CA and server certificates for AGS to use as a client
- ./security/ca.crt:/opt/aerospike-graph/aerospike-client-tls/ca.crt
- ./security/server.crt:/opt/aerospike-graph/aerospike-client-tls/server.crt
environment:
# Specify the TLS endpoint (host:tls-name:tls-port)
aerospike.client.host: tls-aerospike-db:exampleCluster:4000
# Enable TLS for the database client
aerospike.client.tls: "true"

Here AGS receives the same CA and server certificate that the database is using. The Aerospike Java client only needs the CA (ca.crt) to verify the server, but mounting server.crt keeps the example data set in sync with the database container.

The aerospike.client.host variable follows the HOST:TLS_NAME:TLS_PORT format, so exampleCluster matches the tls definition in aerospike.conf and 4000 matches the database TLS port. Setting aerospike.client.tls: "true" tells AGS to build TLS sockets instead of plaintext ones; omit or set to "false" and the client ignores the mounted certificates.

Start the services

  1. Start the Docker containers.

    Terminal window
    docker-compose up -d
    Example response
    [+] Running 3/3
    ✔ Network tls-asgraph-net Created
    ✔ Container tls-aerospike-db Healthy
    ✔ Container tls-aerospike-graph-service Started
  2. Check that both containers report a healthy status (approximately 15 seconds).

    Terminal window
    docker ps

    Wait until tls-aerospike-db shows healthy before proceeding.

  3. Verify the Aerospike database TLS endpoint with asinfo.

    Terminal window
    asinfo -h tls-aerospike-db:exampleCluster:4000 \
    --tls-enable \
    --tls-cafile=/opt/aerospike/etc/ca.crt \
    -v status

    Because asinfo is part of the Aerospike Tools package (not a default macOS/Linux binary), run it from inside the database container:

    Terminal window
    docker exec tls-aerospike-db \
    asinfo -h localhost:exampleCluster:4000 \
    --tls-enable \
    --tls-cafile=/opt/aerospike/etc/ca.crt \
    -v status

    (Inside the container, localhost resolves to the database itself, so TLS verification still succeeds.)

    A successful TLS health check prints ok. Any other response indicates the server could not complete the TLS handshake; inspect the database logs for details.

Verify the connection

The tls_example.py script connects to AGS over an unencrypted WebSocket (the client-to-AGS connection is not encrypted in this example) and runs a traversal. The traversal data is encrypted between AGS and the database.

  1. Run the Python example.

    Terminal window
    python3 ./tls_example.py
    Example response
    Attempt 1/5: Connecting to Graph...
    Connection established and healthy.
    Values:
    ['aerospike', 'unlimited']
    Connected and Queried Successfully, TLS between AGS and Aerospike DB is set up!
  2. Verify that the script output includes “TLS between AGS and Aerospike DB is set up!”.

How AGS connects to the database

AGS acts as a client to Aerospike Database. The environment variables in docker-compose.yaml configure the Aerospike Java client embedded in AGS:

environment:
aerospike.client.host: tls-aerospike-db:exampleCluster:4000
aerospike.client.tls: "true"
aerospike.client.namespace: test

Putting it together:

  • aerospike.client.host points to the Docker service name (tls-aerospike-db), the TLS context (exampleCluster), and the TLS port (4000). AGS embeds the Aerospike Java client, so this value tells that client exactly which certificate to expect when it dials the database.
  • aerospike.client.tls: "true" enables TLS mode within the Aerospike Java client. When true, the client looks for certificates under /opt/aerospike-graph/aerospike-client-tls/ (where the Compose file mounted them).
  • aerospike.client.namespace: test ensures AGS talks to the correct Aerospike namespace after the TLS handshake succeeds.

Because AGS handles the database handshake internally, Gremlin clients do not need to change anything for this layer; the WebSocket connection to AGS can remain the same while AGS encrypts its backend traffic.

Troubleshooting

If AGS fails to connect to the database:

TLS handshake failures:

  • Check database logs: docker logs tls-aerospike-db | grep -i tls
  • Verify the cluster name matches in three places:
    • aerospike.conf: cluster-name exampleCluster
    • aerospike.conf: tls exampleCluster { ... }
    • docker-compose.yaml: aerospike.client.host: tls-aerospike-db:exampleCluster:4000
  • Ensure certificates are signed by the same CA

Certificate path issues:

  • Confirm volume mounts are correct in docker-compose.yaml
  • Verify file permissions: certificates must be readable by the container user
  • Check that certificate files exist: ls -l security/

AGS startup failures:

  • AGS logs will indicate TLS errors: docker logs tls-aerospike-graph-service
  • Common error: “Failed to connect to Aerospike” indicates database TLS is not ready
  • Wait for database health check to pass before expecting AGS to connect successfully

Clean up

When you’re finished, stop and remove the containers:

Terminal window
docker-compose down

The generated certificates in security/ remain for future use. To regenerate certificates (for example, after expiration), delete the security/ directory and rerun ./make-certs.sh.

Combining both TLS layers

For production deployments, enable both client-to-AGS and AGS-to-Database TLS to provide end-to-end encryption.

  1. Generate certificates for both layers..

    You can reuse the same Certificate Authority (CA) for both TLS scenarios. Run both certificate generation scripts to create:

    • security/ca.crt and security/ca.key (CA certificates)
    • g-tls/server.crt and g-tls/server.key (for AGS WebSocket endpoint)
    • security/server.crt and security/server.key (for Aerospike Database)
  2. Create a combined Docker Compose configuration..

    Merge the volume mounts and environment variables from both examples:

    services:
    aerospike-db:
    image: aerospike/aerospike-server-enterprise:8.0.0.7
    volumes:
    - ./security:/opt/aerospike/etc/
    - ./aerospike.conf:/opt/aerospike/etc/aerospike.conf
    command: ["--config-file", "/opt/aerospike/etc/aerospike.conf"]
    aerospike-graph-service:
    image: aerospike/aerospike-graph-service:latest
    depends_on:
    aerospike-db:
    condition: service_healthy
    volumes:
    # AGS WebSocket TLS (client-to-AGS)
    - ./g-tls:/opt/aerospike-graph/gremlin-server-tls:ro
    - ./security/ca.crt:/opt/aerospike-graph/gremlin-server-ca/ca.crt:ro
    # Database client TLS (AGS-to-Database)
    - ./security/ca.crt:/opt/aerospike-graph/aerospike-client-tls/ca.crt
    - ./security/server.crt:/opt/aerospike-graph/aerospike-client-tls/server.crt
    environment:
    # Enable WebSocket TLS
    aerospike.graph-service.ssl.enabled: "true"
    # Enable database client TLS
    aerospike.client.host: aerospike-db:exampleCluster:4000
    aerospike.client.tls: "true"
    aerospike.client.namespace: test
  3. Update your Gremlin client to use secure connections..

    Modify your Python client to use wss:// (WebSocket Secure) with an SSL context:

    import ssl
    from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
    ssl_context = ssl.create_default_context(cafile="./security/ca.crt")
    ssl_context.check_hostname = False
    connection = DriverRemoteConnection(
    'wss://localhost:8182/gremlin', # Secure WebSocket
    'g',
    ssl_context=ssl_context
    )
  4. Verify end-to-end encryption..

    When both TLS layers are active:

    • Gremlin queries travel over encrypted WebSocket (client → AGS)
    • Graph traversal data moves over encrypted connections (AGS → Database)
    • Certificates are validated at both boundaries

This configuration provides defense in depth: even if an attacker gains access to the internal network, they cannot intercept unencrypted traffic between AGS and the database.

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?