Skip to main content

OpenSearch Domain Is Not Publicly Accessible

Overview

This check ensures that your Amazon OpenSearch Service domains are not publicly accessible from the internet. OpenSearch domains should have restricted access policies that limit who can connect to them, rather than allowing anyone on the internet to access your data.

Risk

A publicly accessible OpenSearch domain is a critical security risk:

  • Data theft: Attackers can query your domain and steal sensitive logs, analytics data, or personal information
  • Data tampering: Unauthorized users can modify or delete your indexes, corrupting your data
  • Service disruption: Malicious actors can overload your domain or delete critical data, causing outages
  • Lateral movement: A compromised OpenSearch domain can be used as a stepping stone to attack other parts of your infrastructure

Remediation Steps

Prerequisites

You need permission to modify OpenSearch domain access policies in your AWS account. This typically requires the es:UpdateDomainConfig permission.

Required IAM permissions

Your IAM user or role needs these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"es:DescribeDomain",
"es:UpdateDomainConfig"
],
"Resource": "arn:aws:es:*:*:domain/*"
}
]
}

AWS Console Method

  1. Sign in to the AWS Management Console
  2. Navigate to Amazon OpenSearch Service
  3. Click on the domain name that was flagged
  4. Select the Security configuration tab
  5. Under Access policy, click Edit
  6. Replace the existing policy with a restrictive one that specifies your AWS account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<YOUR-ACCOUNT-ID>:root"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:<YOUR-ACCOUNT-ID>:domain/<YOUR-DOMAIN-NAME>/*"
}
]
}
  1. Replace <YOUR-ACCOUNT-ID> with your 12-digit AWS account ID
  2. Replace <YOUR-DOMAIN-NAME> with your actual domain name
  3. Click Save changes

Important: For better security, consider restricting access to specific IAM roles or users instead of the entire account root.

AWS CLI (optional)

View current access policy:

aws opensearch describe-domain \
--domain-name <YOUR-DOMAIN-NAME> \
--region us-east-1 \
--query 'DomainStatus.AccessPolicies'

Update the access policy to restrict access:

aws opensearch update-domain-config \
--domain-name <YOUR-DOMAIN-NAME> \
--region us-east-1 \
--access-policies '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<YOUR-ACCOUNT-ID>:root"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:<YOUR-ACCOUNT-ID>:domain/<YOUR-DOMAIN-NAME>/*"
}
]
}'

Replace:

  • <YOUR-DOMAIN-NAME> with your OpenSearch domain name
  • <YOUR-ACCOUNT-ID> with your 12-digit AWS account ID

For VPC-based domains (more secure):

If your domain supports VPC access, you can update it to use a VPC instead of public access. Note that this is a significant change that requires planning.

CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: OpenSearch domain with restricted access policy

Parameters:
DomainName:
Type: String
Description: Name of the OpenSearch domain
Default: my-opensearch-domain

AccountId:
Type: String
Description: AWS Account ID for access policy

Resources:
OpenSearchDomain:
Type: AWS::OpenSearchService::Domain
Properties:
DomainName: !Ref DomainName
EngineVersion: OpenSearch_2.11
ClusterConfig:
InstanceType: t3.small.search
InstanceCount: 1
EBSOptions:
EBSEnabled: true
VolumeSize: 10
VolumeType: gp3
AccessPolicies:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AccountId}:root'
Action: 'es:*'
Resource: !Sub 'arn:aws:es:${AWS::Region}:${AccountId}:domain/${DomainName}/*'
EncryptionAtRestOptions:
Enabled: true
NodeToNodeEncryptionOptions:
Enabled: true
DomainEndpointOptions:
EnforceHTTPS: true
TLSSecurityPolicy: Policy-Min-TLS-1-2-2019-07

Outputs:
DomainEndpoint:
Description: OpenSearch domain endpoint
Value: !GetAtt OpenSearchDomain.DomainEndpoint
DomainArn:
Description: OpenSearch domain ARN
Value: !GetAtt OpenSearchDomain.Arn

Deploy the stack:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name opensearch-restricted-access \
--parameter-overrides \
DomainName=my-opensearch-domain \
AccountId=123456789012 \
--region us-east-1
Terraform (optional)
variable "domain_name" {
description = "Name of the OpenSearch domain"
type = string
default = "my-opensearch-domain"
}

variable "account_id" {
description = "AWS Account ID"
type = string
}

variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}

resource "aws_opensearch_domain" "main" {
domain_name = var.domain_name
engine_version = "OpenSearch_2.11"

cluster_config {
instance_type = "t3.small.search"
instance_count = 1
}

ebs_options {
ebs_enabled = true
volume_size = 10
volume_type = "gp3"
}

encrypt_at_rest {
enabled = true
}

node_to_node_encryption {
enabled = true
}

domain_endpoint_options {
enforce_https = true
tls_security_policy = "Policy-Min-TLS-1-2-2019-07"
}

access_policies = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${var.account_id}:root"
}
Action = "es:*"
Resource = "arn:aws:es:${var.aws_region}:${var.account_id}:domain/${var.domain_name}/*"
}
]
})
}

output "domain_endpoint" {
description = "OpenSearch domain endpoint"
value = aws_opensearch_domain.main.endpoint
}

output "domain_arn" {
description = "OpenSearch domain ARN"
value = aws_opensearch_domain.main.arn
}

Apply the configuration:

terraform init
terraform plan -var="account_id=123456789012"
terraform apply -var="account_id=123456789012"

Verification

After making changes, verify that your domain is no longer publicly accessible:

  1. In the AWS Console, go to Amazon OpenSearch Service
  2. Select your domain
  3. Check the Security configuration tab
  4. Confirm the access policy no longer contains "Principal": "*" or overly permissive statements
CLI verification
aws opensearch describe-domain \
--domain-name <YOUR-DOMAIN-NAME> \
--region us-east-1 \
--query 'DomainStatus.AccessPolicies' \
--output text

The output should show a restrictive policy with specific AWS principals, not "Principal": "*".

You can also re-run the Prowler check to confirm remediation:

prowler aws -c opensearch_service_domains_not_publicly_accessible -r us-east-1

Additional Resources

Notes

  • VPC is more secure: For production workloads, consider deploying your OpenSearch domain within a VPC instead of relying solely on access policies. VPC deployment provides network-level isolation.

  • Fine-grained access control: OpenSearch supports fine-grained access control (FGAC) which allows you to control access at the index, document, and field level. Consider enabling this for sensitive data.

  • Policy changes take time: Access policy updates can take several minutes to propagate. Wait a few minutes before testing.

  • Existing connections: Changing access policies does not immediately terminate existing connections. Users with open sessions may continue to have access until their sessions expire.

  • Application impact: Before restricting access, ensure all legitimate applications and users are included in your new access policy to avoid service disruptions.