Enable IAM authentication for HTTP requests in non AWS Managed Cluster

Versions
Latest version (applies to all versions)

Describe the issue:

We have been using AWS Managed OpenSearch clusters for a long period of time now but need to move to self hosted so that we can be cloud agnostic amongst a few other reasons.

On the AWS Managed OpenSearch clusters we are able to auth into the dashboard using basic auth configured via internal users.

Also on the AWS Managed OpenSearch clusters we are able to make HTTP requests using the IAM role on our EC2 servers or AWS Lambda functions by signing requests. An example of how we may grant access is by adding the role of the EC2 instance or an IAM user ARN into the “Mapped Users” section for the “all_access” role.

Just to be clear we do not use IAM auth to log into the dashboard, we use basic auth for that. The IAM auth is only used for HTTP calls.

Now that we have built our own clusters using docker compose (see all configuration files below) we can no longer use IAM authentication in the same manor.

We can use basic auth to make HTTP requests but no longer use IAM signed requests and just get presented with this error:

opensearchpy.exceptions.AuthenticationException: AuthenticationException(401, ‘Unauthorized’)

I assume we need to add an authentication provider for IAM but the OpenSearch managed instances seem to hide this as I can only see a single auth provider for basic auth configured via the OpenSearch dashboard.

Has anyone set this up before outside of the managed AWS OpenSearch clusters? If so can they shed some light on how to achieve this or at least pointing in the right direction.

Kind regards,

Mike

Configuration - Docker Compose YML

version: '3'
services:
  opensearch-node1:
    build:
      dockerfile: Dockerfile
      args:
        - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
        - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    container_name: opensearch-node1
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node1
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true
      - "OPENSEARCH_JAVA_OPTS=-Xms3g -Xmx3g"
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - opensearch-data1:/usr/share/opensearch/data
    ports:
      - 9200:9200
      - 9600:9600
    networks:
      - opensearch-net
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 6144M
    restart: unless-stopped
  opensearch-node2:
    build:
      dockerfile: Dockerfile
      args:
        - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
        - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    container_name: opensearch-node2
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node2
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true
      - "OPENSEARCH_JAVA_OPTS=-Xms3g -Xmx3g"
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - opensearch-data2:/usr/share/opensearch/data
    networks:
      - opensearch-net
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 6144M
    restart: unless-stopped
  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:latest
    container_name: opensearch-dashboards
    ports:
      - 5601:5601
    expose:
      - "5601"
    environment:
      OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]'
    networks:
      - opensearch-net
    restart: unless-stopped
volumes:
  opensearch-data1:
  opensearch-data2:
networks:
  opensearch-net:

Configuration - Custom Docker File (Required to install the S3 Plugin)

FROM opensearchproject/opensearch:latest
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
RUN /usr/share/opensearch/bin/opensearch-plugin install --batch repository-s3
RUN /usr/share/opensearch/bin/opensearch-keystore create
RUN echo $AWS_ACCESS_KEY_ID | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.access_key
RUN echo $AWS_SECRET_ACCESS_KEY | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.secret_key

Relevant Logs or Screenshots:
opensearchpy.exceptions.AuthenticationException: AuthenticationException(401, ‘Unauthorized’)

@VFMikeE Non AWS Managed OpenSearch doesn’t support AWS IAM authentication.
However, you could consider using AWS Cognito with OpenID.

1 Like

Thanks Pablo.

I was leaning towards the same answer after not seeing oauth2 as a supported auth method.

It would be interesting to know how AWS do this on their managed OpenSearch clusters but that is way out of scope for the piece of work I am doing and as all of our OpenSearch clusters are purely backend services we can make do with alternative auth methods available via the natively support auth methods.

Thanks for taking your time to confirm my thoughts.

Have a great day.

1 Like