---
title: "Configure TLS between AGS and Aerospike Database"
description: "Configure TLS between Aerospike Graph Service (AGS) and Aerospike Database using certificates and Docker."
---

# Configure TLS between AGS and Aerospike Database

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

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
    
    ```bash
    cd ../AGS-to-AerospikeDB
    ```
    
2.  Run the certificate generation script.
    
    Terminal window
    
    ```bash
    ./make-certs.sh
    ```
    
    Example response
    
    ```plaintext
    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
    
    ```bash
    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:

```plaintext
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:

```yaml
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:

```yaml
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
    
    ```bash
    docker-compose up -d
    ```
    
    Example response
    
    ```plaintext
    [+] 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
    
    ```bash
    docker ps
    ```
    
    Wait until `tls-aerospike-db` shows `healthy` before proceeding.
    
3.  Verify the Aerospike database TLS endpoint with `asinfo`.
    
    Terminal window
    
    ```bash
    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
    
    ```bash
    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
    
    ```bash
    python3 ./tls_example.py
    ```
    
    Example response
    
    ```plaintext
    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:

```yaml
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

```bash
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:
    
    ```yaml
    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:
    
    ```python
    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.

::: undefined
-   I’ve generated TLS certificates for the AGS-to-Database connection.
-   I’ve configured Aerospike Database with TLS.
-   I’ve started AGS with database TLS enabled.
-   I’ve verified the secure connection using Python.
:::

Share

Congratulations on completing this tutorial! Share your achievement with the world and let everyone know about your newly acquired skills.

[](https://www.linkedin.com/feed/?shareActive&mini=true&text=Just%20secured%20my%20Aerospike%20Graph%20deployment%20with%20TLS!%20%F0%9F%94%92%0A%0AConfigured%20encryption%20between%20Gremlin%20clients%20and%20AGS%2C%20plus%20backend%20encryption%20to%20the%20database.%20Clean%20setup%20with%20Docker%20and%20OpenSSL.%0A%0A%23AerospikeGraph%20%23TLS%20%23Security%20%23GraphDatabase%20%23DevOps%0A%0Ahttps%3A%2F%2Faerospike.com%2Fdocs%2Fgraph%2Fget-started-with-graph-and-tls "Post to LinkedIn")[](https://bsky.app/intent/compose?text=Just%20secured%20my%20Aerospike%20Graph%20deployment%20with%20TLS!%20%F0%9F%94%92%0A%0AConfigured%20encryption%20between%20Gremlin%20clients%20and%20AGS%2C%20plus%20backend%20encryption%20to%20the%20database.%20Clean%20setup%20with%20Docker%20and%20OpenSSL.%0A%0A%23AerospikeGraph%20%23TLS%20%23Security%20%23GraphDatabase%20%23DevOps%0A%0Ahttps%3A%2F%2Faerospike.com%2Fdocs%2Fgraph%2Fget-started-with-graph-and-tls "Post to BlueSky")[](https://twitter.com/intent/tweet?text=Just%20secured%20my%20Aerospike%20Graph%20deployment%20with%20TLS!%20%F0%9F%94%92%0A%0AConfigured%20encryption%20between%20Gremlin%20clients%20and%20AGS%2C%20plus%20backend%20encryption%20to%20the%20database.%20Clean%20setup%20with%20Docker%20and%20OpenSSL.%0A%0A%23AerospikeGraph%20%23TLS%20%23Security%20%23GraphDatabase%20%23DevOps%0A%0Ahttps%3A%2F%2Faerospike.com%2Fdocs%2Fgraph%2Fget-started-with-graph-and-tls "Post to Twitter")

::: undefined
-   To learn more about TLS configuration options, see the [TLS overview page](https://aerospike.com/docs/graph/manage/security/tls).
    
-   To configure Role-Based Access Control, see the [RBAC for AGS page](https://aerospike.com/docs/graph/manage/security/rbac-graph).
    
-   To set up production TLS with trusted certificates, see the [TLS between application and AGS page](https://aerospike.com/docs/graph/manage/security/tls/tls-gremlin-ags).
:::

[Previous  
Configure TLS between Gremlin client and AGS](https://aerospike.com/docs/graph/get-started-with-graph-and-tls/step/1/part/1/gremlin-to-ags-tls)