---
title: "Quickstart: Data masking"
description: "Quickstart guide for configuring dynamic data masking and RBAC in Aerospike Database to redact sensitive bin values."
---

# Quickstart: Data masking

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

This quickstart creates a secured Aerospike instance with dynamic data masking rules that automatically redact sensitive bins like SSNs and emails based on the privileges of the connected user.

## Quickstart goals

When you finish this quickstart, you will have done the following:

-   Started a single-node Aerospike Database cluster with security and basic audit logging enabled.
-   Created three users with different privileges:
    -   `app_service`: can read unmasked values and write masked bins
    -   `analyst_1`: can read data but sees masked values for protected bins
    -   `masking_admin`: can create and remove masking rules
-   Added masking rules on three bins (`ssn`, `email`, `notes`) in `test.customers`.
-   Verified masked reads and blocked writes.
-   Viewed audit log entries for masking changes and role violations.

### Success criteria

You are done when all of the following are true:

-   `show masking namespace test` shows three rules for `test.customers`.
-   `app_service` sees unmasked values for `ssn`, `email`, and `notes`.
-   `analyst_1` sees masked values for `ssn`, `email`, and `notes`.
-   `analyst_1` cannot update a masked bin and receives `AEROSPIKE_ROLE_VIOLATION`.
-   The audit log includes at least one `permitted` masking event and one `role violation` event.

## Prerequisites

Verify the following before you begin:

-   Docker is installed and running.
-   Port `3000` is available on your machine.

::: note
When RBAC is enabled in Aerospike Database Enterprise Edition, the default credentials are username `admin`, password `admin`. See [Manage RBAC users and roles](https://aerospike.com/docs/database/8.1.2/manage/security/rbac/).
:::

## Start Aerospike Database with Docker

This quickstart uses Docker for both the server and the tools (`asadm`, `asinfo`, `aql`) to minimize local dependencies.

1.  From a shell prompt, create `aerospike.conf` in a new working directory.
    
    Create directory
    
    ```bash
    mkdir -p aerospike-data-masking-quickstart
    ```
    
    Change to new directory
    
    ```bash
    cd aerospike-data-masking-quickstart
    ```
    
    Create local configuration file
    
    ```bash
    touch aerospike.conf
    ```
    
2.  Create a Docker network for the quickstart.
    
    Terminal window
    
    ```bash
    docker network create aerospike-qs
    ```
    
    Expected output: Docker network ID
    
    ```text
    ad0bc9f7cbb96ee07a...1b2a7fdb6618becf
    ```
    
3.  Start Aerospike Database.
    
    Terminal window
    
    ```bash
    docker run -d \
    
      --name aerospike-masking \
    
      --network aerospike-qs \
    
      -p 3000:3000 \
    
      -p 3001:3001 \
    
      -p 3002:3002 \
    
      -p 3003:3003 \
    
      -v "$(pwd)/aerospike.conf:/etc/aerospike/aerospike.conf" \
    
      aerospike/aerospike-server-enterprise:8.1.1.0
    ```
    
    The `-v` line binds a local Aerospike configuration file to the configuration file in the Docker container.
    
    Expected output: Docker container ID
    
    ```text
    fb23d3ee1d82c0fb...7316a2fb134b4112e
    ```
    
4.  Update the local configuration file with the following command.
    
    Update aerospike.conf
    
    ```bash
    cat > aerospike.conf <<'EOF'
    
    service {
    
      feature-key-file /etc/aerospike/features.conf
    
      cluster-name docker
    
    }
    
    logging {
    
      file /var/log/aerospike/aerospike.log {
    
        context any info
    
    }
    
      file /var/log/aerospike/audit.log {
    
        context audit info
    
      }
    
    }
    
    security {
    
      log {
    
         report-violation true # report failed operations due to violated security checks
    
      }
    
    }
    
    network {
    
      service {
    
        address any
    
        port 3000
    
      }
    
    admin {
    
        address any
    
        port 3003
    
      }
    
      heartbeat {
    
        mode mesh
    
        address local
    
        port 3002
    
        interval 150
    
        timeout 10
    
      }
    
      fabric {
    
        address local
    
        port 3001
    
      }
    
    }
    
    namespace test {
    
      replication-factor 1
    
      storage-engine device {
    
        file /opt/aerospike/data/test.dat
    
        filesize 4G
    
        read-page-cache true
    
      }
    
    }
    
    EOF
    ```
    
5.  Restart the container to enable the configuration changes.
    
    Terminal window
    
    ```bash
    docker restart aerospike-masking
    ```
    
6.  Verify the server build version.
    
    Terminal window
    
    ```bash
    docker run --rm -it \
    
      --network aerospike-qs \
    
      aerospike/aerospike-server-enterprise:8.1.1.0 \
    
      asinfo -h aerospike-masking -p 3000 -U admin -P admin -v build
    ```
    
    Expected output
    
    ```text
    8.1.1.0
    ```
    

## Create roles and users (RBAC)

In this quickstart, you use RBAC privileges to control who can read unmasked data and who can modify masked bins.

1.  Open `asadm` and authenticate as `admin`.
    
    Terminal window
    
    ```bash
    docker run --rm -it \
    
      --network aerospike-qs \
    
      aerospike/aerospike-server-enterprise:8.1.1.0 \
    
      asadm -h aerospike-masking -p 3000 -U admin -P admin
    ```
    
2.  At the `Admin>` prompt, enter privileged mode.
    
    Enable privileged mode in asadm
    
    ```bash
    enable
    ```
    
3.  At the `Admin+>` prompt, create roles.
    
    Create banking\_app role
    
    ```bash
    manage acl create role banking_app priv read-write
    ```
    
    Grant read-masked to banking\_app role
    
    ```bash
    manage acl grant role banking_app priv read-masked
    ```
    
    Grant write-masked to banking\_app role
    
    ```bash
    manage acl grant role banking_app priv write-masked
    ```
    
    Create analyst role
    
    ```bash
    manage acl create role analyst priv read
    ```
    
    Create masking\_dba role
    
    ```bash
    manage acl create role masking_dba priv masking-admin
    ```
    
4.  Create users.
    
    Create app\_service user
    
    ```bash
    manage acl create user app_service password SecureApp123! roles banking_app
    ```
    
    Create analyst\_1 user
    
    ```bash
    manage acl create user analyst_1 password Analyst456! roles analyst
    ```
    
    Create masking\_admin user
    
    ```bash
    manage acl create user masking_admin password DBA789! roles masking_dba
    ```
    
5.  Verify users and roles.
    
    Show users
    
    ```bash
    show users
    ```
    
    Show roles
    
    ```bash
    show roles
    ```
    

## Define masking rules

Masking rules are defined at the namespace/set/bin level. Each bin can have at most one masking rule.

::: caution
To ensure data privacy, always verify that your masking rules cover all potential data types stored within a bin.
:::

### Type-match requirement

For a masking rule to function correctly, its defined type must match the data type of the bin. If there is a mismatch, the system behaves as follows:

-   Writes: Any attempt to write data with a type that does not match the masking rule will be rejected with an error.
    
-   Reads: If the data type in the database does not match the masking rule, the rule is ignored. The data will be returned unmasked, regardless of the user’s permissions.
    

Example Scenario: The SSN Bin

| Action | Scenario | Result |
| --- | --- | --- |
| Write | A rule exists for `ssn` (String), but you attempt to write an Integer. | Error: The write is rejected. |
| Read. | An Integer already exists in `ssn`, but a rule is later applied for String. | **Security Gap:** The read succeeds and returns the raw value because the String-based rule does not recognize the Integer data. |

1.  Open a second `asadm` session as `masking_admin`.
    
    Terminal window
    
    ```bash
    docker run --rm -it \
    
      --network aerospike-qs \
    
      aerospike/aerospike-server-enterprise:8.1.1.0 \
    
      asadm -h aerospike-masking -p 3000 -U masking_admin -P DBA789!
    ```
    
2.  At the `Admin>` prompt, enter privileged mode.
    
    Enable privileged mode in asadm
    
    ```bash
    enable
    ```
    
3.  Add masking rules for three bins.
    
    Add SSN redact rule
    
    ```bash
    manage masking add redact position 0 length 7 value * namespace test set customers bin ssn type string
    ```
    
    Add email redact rule
    
    ```bash
    manage masking add constant value redacted@example.com namespace test set customers bin email type string
    ```
    
    Add notes redact rule
    
    ```bash
    manage masking add constant value [REDACTED] namespace test set customers bin notes type string
    ```
    
4.  Verify the rules.
    
    Show masking rules in namespace and set
    
    ```bash
    show masking namespace test
    ```
    
    **Expected output:**
    
    ```text
    Namespace| Set       | Bin   | Type | Function
    
    test     | customers | ssn   | string | redact position 0 length 7 value *
    
    test     | customers | email | string | constant value redacted@example.com
    
    test     | customers | notes | string | constant value [REDACTED]
    ```
    

## Insert a record as an authorized user

Use [Aerospike Quick Look (AQL)](https://aerospike.com/docs/database/tools/aql/) to insert and query records without writing client code.

1.  Connect to AQL as `app_service`.
    
    Terminal window
    
    ```bash
    docker run --rm -it \
    
      --network aerospike-qs \
    
      aerospike/aerospike-tools \
    
      aql --user app_service --password SecureApp123! --host aerospike-masking --port 3000
    ```
    
2.  At the `aql>` prompt, insert a record that includes the bins you protected with masking rules.
    
    Insert a record
    
    ```bash
    INSERT INTO test.customers (PK, name, ssn, email, notes) VALUES ('CUST-00001', 'Sample Customer', '123-45-6789', 'customer@example.com', 'Customer prefers email communication')
    ```
    
    **Expected output:**
    
    ```plaintext
    OK, 1 record affected.
    ```
    

## Verify masked reads and blocked writes

Read the same record as two different users and compare the results.

1.  At the same `aql>` prompt, read as the `app_service` user (unmasked).
    
    Read sample record
    
    ```bash
    SELECT * FROM test.customers WHERE PK='CUST-00001'
    ```
    
    **Expected output (unmasked values):**
    
    ```text
    +------------+-----------------+-------------+----------------------+--------------------------------------+
    
    | PK         | name            | ssn         | email                | notes                                |
    
    +------------+-----------------+-------------+----------------------+--------------------------------------+
    
    | CUST-00001 | Sample Customer | 123-45-6789 | customer@example.com | Customer prefers email communication |
    
    +------------+-----------------+-------------+----------------------+--------------------------------------+
    
    1 row in set (0.002 secs)
    ```
    
2.  Exit AQL and reconnect as `analyst_1`.
    
    Exit AQL
    
    ```bash
    exit
    ```
    
    Run AQL and connect as analyst\_1
    
    ```bash
    docker run --rm -it \
    
      --network aerospike-qs \
    
      aerospike/aerospike-tools \
    
      aql --user analyst_1 --password Analyst456! --host aerospike-masking --port 3000
    ```
    
3.  Read as `analyst_1` (masked).
    
    Read sample record
    
    ```bash
    SELECT * FROM test.customers WHERE PK='CUST-00001'
    ```
    
    **Expected output (masked values):**
    
    ```text
    +------------+-----------------+-------------+----------------------+------------+
    
    | PK         | name            | ssn         | email                | notes      |
    
    +------------+-----------------+-------------+----------------------+------------+
    
    | CUST-00001 | Sample Customer | *******6789 | redacted@example.com | [REDACTED] |
    
    +------------+-----------------+-------------+----------------------+------------+
    
    1 row in set (0.002 secs)
    ```
    
4.  Attempt to update a masked bin as `analyst_1` (blocked).
    
    Update a masked bin
    
    ```bash
    INSERT INTO test.customers (PK, ssn) VALUES ('CUST-00001', '999-99-9999')
    ```
    
    **Expected output:**
    
    ```text
    Error: (81) AEROSPIKE_ROLE_VIOLATION
    ```
    

## Check the audit log

Read operations are not audited. The audit log includes masking rule changes and failed write attempts to masked bins.

1.  In a separate terminal, tail the audit log from the server container.
    
    Terminal window
    
    ```bash
    docker exec -it aerospike-masking tail -f /var/log/aerospike/audit.log
    ```
    
2.  Verify that you see events similar to the following:
    
    -   `permitted ... action: masking ...` (rule changes)
    -   `role violation ...` (blocked write attempts)

## Before production

This quickstart is designed for fast validation, not production hardening.

-   Test masking rules in a non-production environment first.
-   Verify deterministic behavior where your application requires stable masked values.
-   Verify audit log retention, access controls, and monitoring for your compliance requirements.

## Cleanup

To remove the local quickstart environment:

1.  Stop and remove the server container.
    
    Terminal window
    
    ```bash
    docker rm -f aerospike-masking
    ```
    
2.  Remove the Docker network.
    
    Terminal window
    
    ```bash
    docker network rm aerospike-qs
    ```
    
3.  Remove the local quickstart directory.
    
    Terminal window
    
    ```bash
    cd ..
    
    rm -rf aerospike-data-masking-quickstart
    ```
    

## Next steps

For production guidance, policy design, and rule behavior details, see [Data masking](https://aerospike.com/docs/database/8.1.2/learn/security/data-masking/).