Security administration helpers require Aerospike Enterprise with security enabled and a cluster connection authenticated with the needed admin privileges. The local Enterprise security profile exercises user lifecycle, PKI users, password rotation, role privileges, whitelists, and quotas.

Start An Authenticated Client

Pass credentials at cluster startup.

{:ok, _pid} =
  Aerospike.start_link(
    name: :aerospike,
    transport: Aerospike.Transport.Tcp,
    hosts: ["127.0.0.1:3200"],
    namespaces: ["test"],
    user: "admin",
    password: "admin",
    pool_size: 2
  )

TLS uses the TLS transport and transport options under connect_opts. Username/password auth remains top-level cluster configuration.

{:ok, _pid} =
  Aerospike.start_link(
    name: :aerospike_tls,
    transport: Aerospike.Transport.Tls,
    hosts: ["aerospike.example.com:4333"],
    namespaces: ["test"],
    user: "svc_ingest",
    password: System.fetch_env!("AEROSPIKE_PASSWORD"),
    pool_size: 4,
    connect_opts: [
      tls_name: "aerospike.example.com",
      tls_cacertfile: "/etc/ssl/aerospike/ca.crt",
      connect_timeout_ms: 5_000,
      info_timeout: 5_000
    ]
  )

For mTLS or PKI deployments, add client certificate and key files:

connect_opts: [
  tls_name: "aerospike.example.com",
  tls_cacertfile: "/etc/ssl/aerospike/ca.crt",
  tls_certfile: "/etc/ssl/aerospike/client.crt",
  tls_keyfile: "/etc/ssl/aerospike/client.key"
]

tls_verify: :verify_peer is the default. Use tls_verify: :verify_none only for local test environments.

Users

Create password-authenticated users with role names.

:ok =
  Aerospike.create_user(
    :aerospike,
    "svc_ingest",
    "replace-this-password",
    ["read-write"]
  )

{:ok, user} = Aerospike.query_user(:aerospike, "svc_ingest")
user.roles

:ok = Aerospike.grant_roles(:aerospike, "svc_ingest", ["udf-admin"])
:ok = Aerospike.revoke_roles(:aerospike, "svc_ingest", ["udf-admin"])
:ok = Aerospike.drop_user(:aerospike, "svc_ingest")

Create PKI users when TLS certificate authentication is configured on the server:

:ok = Aerospike.create_pki_user(:aerospike, "svc_pki_ingest", ["read"])

change_password/4 rotates the running cluster's in-memory credentials when the changed user is the same user configured on that cluster.

Roles And Privileges

Privileges are %Aerospike.Privilege{} structs. Global privileges leave :namespace and :set as nil; data privileges may narrow scope.

read_profiles = %Aerospike.Privilege{
  code: :read,
  namespace: "test",
  set: "profiles"
}

write_events = %Aerospike.Privilege{
  code: :write,
  namespace: "test",
  set: "events"
}

:ok =
  Aerospike.create_role(:aerospike, "ingest_limited", [read_profiles],
    whitelist: ["127.0.0.1"],
    read_quota: 1_000,
    write_quota: 500
  )

:ok = Aerospike.grant_privileges(:aerospike, "ingest_limited", [write_events])
{:ok, role} = Aerospike.query_role(:aerospike, "ingest_limited")
role.privileges

Whitelist and quota limits can be changed independently. An empty whitelist clears the role whitelist; 0 clears an individual quota when the server is configured to support quotas.

:ok =
  Aerospike.set_whitelist(:aerospike, "ingest_limited", [
    "10.0.0.0/8",
    "192.168.10.20"
  ])

:ok = Aerospike.set_whitelist(:aerospike, "ingest_limited", [])
:ok = Aerospike.set_quotas(:aerospike, "ingest_limited", 0, 0)
:ok = Aerospike.drop_role(:aerospike, "ingest_limited")

XDR Filters

set_xdr_filter/4 sets or clears one Enterprise XDR expression filter for a datacenter and namespace. This requires XDR to be configured on the target Enterprise server. The checked-in local profiles do not configure an XDR topology, so XDR validation is opt-in.

filter =
  Aerospike.Exp.eq(
    Aerospike.Exp.int_bin("replicate"),
    Aerospike.Exp.int(1)
  )

:ok = Aerospike.set_xdr_filter(:aerospike, "dc-west", "test", filter)
:ok = Aerospike.set_xdr_filter(:aerospike, "dc-west", "test", nil)

Passing nil clears the current filter. Community Edition or Enterprise servers without XDR configured may reject the command after local validation.