Creating dedicated Elasticsearch users and roles avoids sharing the built-in elastic superuser and limits access to only the indices and APIs required for a specific task.

Roles are privilege bundles applied at the cluster level (for APIs like monitoring) and at the index level (for patterns like logs-*). Users authenticate with a password and inherit privileges from one or more roles, with management performed through the _security/role and _security/user endpoints.

Security administration requires an authenticated account with the manage_security privilege. In environments where the HTTP layer is protected by TLS, replace http://localhost:9200 with https://localhost:9200 and supply a trusted CA using --cacert (avoiding --insecure outside of throwaway testing). Passing credentials on the command line can expose secrets through shell history and process listings, so prefer short-lived sessions and protected terminals.

Steps to create users and roles in Elasticsearch:

  1. Authenticate as an administrative user to confirm access to the security APIs.
    $ curl -sS --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:password "https://localhost:9200/_security/_authenticate?pretty"
    {
      "username" : "elastic",
      "roles" : [
        "superuser"
      ],
      "full_name" : null,
      "email" : null,
      "metadata" : {
        "_reserved" : true
      },
      "enabled" : true,
      "authentication_realm" : {
        "name" : "reserved",
        "type" : "reserved"
      },
      "lookup_realm" : {
        "name" : "reserved",
        "type" : "reserved"
      },
      "authentication_type" : "realm"
    }
  2. Create a role with index privileges.
    $ curl -sS --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:password -H "Content-Type: application/json" -X PUT "https://localhost:9200/_security/role/logs_reader?pretty" -d '{
      "cluster": ["monitor"],
      "indices": [
        { "names": ["logs-*"], "privileges": ["read", "view_index_metadata"] }
      ]
    }'
    {
      "role" : { "created" : true }
    }

    Restrict names to the smallest index pattern that fits, and avoid write privileges unless required.

  3. Create a user assigned to the role.
    $ curl -sS --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:password -H "Content-Type: application/json" -X PUT "https://localhost:9200/_security/user/logs-viewer?pretty" -d '{
      "password" : "strong-password",
      "roles" : ["logs_reader"],
      "full_name" : "Logs Viewer"
    }'
    {
      "created" : true
    }

    Use a strong, unique password and avoid committing credentials to scripts or shell history.

  4. Authenticate with the new user.
    $ curl -sS --cacert /etc/elasticsearch/certs/http_ca.crt -u logs-viewer:strong-password "https://localhost:9200/_security/_authenticate?pretty"
    {
      "username" : "logs-viewer",
      "roles" : [
        "logs_reader"
      ],
      "full_name" : "Logs Viewer",
      "email" : null,
      "metadata" : { },
      "enabled" : true,
      "authentication_realm" : {
        "name" : "default_native",
        "type" : "native"
      },
      "lookup_realm" : {
        "name" : "default_native",
        "type" : "native"
      },
      "authentication_type" : "realm"
    }
  5. Confirm the effective privileges for the new user.
    $ curl -sS --cacert /etc/elasticsearch/certs/http_ca.crt -u logs-viewer:strong-password "https://localhost:9200/_security/user/_privileges?pretty"
    {
      "cluster" : [ "monitor" ],
      "global" : [ ],
      "indices" : [
        {
          "names" : [ "logs-*" ],
          "privileges" : [ "read", "view_index_metadata" ],
          "allow_restricted_indices" : false
        }
      ],
      "applications" : [ ],
      "run_as" : [ ]
    }