opensearch-project / terraform-provider-opensearch

https://registry.terraform.io/providers/opensearch-project/opensearch
Apache License 2.0
73 stars 56 forks source link

[BUG] 403 Forbidden Error When Mapping 'all_access' Role to LDAP Group in OpenSearch #153

Closed ghost closed 6 months ago

ghost commented 6 months ago

What is the bug?

When attempting to map the "all_access" predefined role in OpenSearch to an LDAP group, the process fails and results in an error. The specific error message received is "Error: elastic: Error 403 (Forbidden)". This suggests a permission issue, but the exact cause is unclear.

How can one reproduce the bug?

  1. Set up OpenSearch with LDAP authc and authz.
  2. Attempt to map the "all_access" predefined role to an LDAP group through the OpenSearch security configuration.
  3. Observe that the mapping does not succeed and results in the aforementioned error message.

    What is the expected behavior?

    The expected behavior is that the "all_access" role should successfully map to the specified LDAP group, granting members of this group the appropriate access permissions within OpenSearch.

What is your host/environment? [Please provide details about your operating system, version of OpenSearch, and any other relevant environment details.]

Do you have any additional context?

resource "opensearch_roles_mapping" "mapper" {
  role_name   = "all_access"
  description = "Mapping all_access role to ldap group"
  backend_roles = ["ldap_group"]
}
prudhvigodithi commented 6 months ago

[Triage] Thanks @yoicomment Looks similar https://github.com/opensearch-project/terraform-provider-opensearch/issues/158, https://github.com/opensearch-project/terraform-provider-opensearch/issues/156 .

Adding @rblcoder @bbarani

rblcoder commented 6 months ago

@yoicomment You would also need to specify any existing users and backend_roles for the role mapping in the terraform code.

ghost commented 6 months ago
resource "opensearch_roles_mapping" "mapper" {
  role_name   = "all_access"
  description = "Mapping all_access role to ldap group"
  backend_roles = ["ldap_group"]
}

As you can see, I specified "ldap_group" as "backend_roles". Shouldn't that be enough? I don't want to assign "all_access" to users explicitely.

Besides that, I found a security setting:

image

Does it fail because it is set to the default value?

rblcoder commented 6 months ago

@yoicomment The user you are authenticating with from the Terraform OpenSearch provider would continue to need access if you are using HTTP basic auth. Are you using HTTP basic auth?

ghost commented 6 months ago

Yes, I'm using the admin user for that

rblcoder commented 6 months ago

@yoicomment I too get 403 error if I remove admin from the role mapping for the following configuration as admin is a user from the internal user database and loses access if it is not part of the role mapping.

terraform {
  required_providers {
    opensearch = {
      source = "opensearch-project/opensearch"
      version = "2.2.0"
    }
  }
}

provider "opensearch" {
  url = "https://localhost:9200"
  username          = "admin"
  password          = "admin"
  insecure = true

  version_ping_timeout = "10"

}

resource "opensearch_roles_mapping" "mapper" {
  role_name   = "all_access"
  description = "Mapping all_access role to ldap group"
  backend_roles = ["admin", "Administrator"]
}
ghost commented 6 months ago

This is my "internal_users.yml" file.

_meta:
  type: "internalusers"
  config_version: 2

# Define your internal users here

admin:
  hash: "$2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG"
  reserved: true
  backend_roles:
  - "admin"
  description: "Admin user"

This is my "roles_mapping.yml" file:

_meta:
  type: "rolesmapping"
  config_version: 2

all_access:
  reserved: true
  hidden: false
  backend_roles:
  - "admin"
  hosts: []
  users: []
  and_backend_roles: []
  description: "Maps admin to all_access"

I use this for:

provider "opensearch" {
  url = "https://localhost:9200"
  username          = "admin"
  password          = "admin"
}

The name of the ldap group is:

all_admins

Now, I wanna assign the role to this ldap group:

resource "opensearch_roles_mapping" "mapper" {
  role_name   = "all_access"
  description = "Mapping all_access role to ldap group"
  backend_roles = ["all_admins"]
}

And this does not work for me.

rblcoder commented 6 months ago

@yoicomment Yes, we have admin user in the roles_mapping.yml and the role mapping created using the YAML will be replaced with the role mapping created by applying the Terraform code. With backend_roles = ["admin", "all_admins"], it will work.

ghost commented 6 months ago

With backend_roles = ["admin", "all_admins"], it will work.

Why need to add "admin" here? I don't have a ldap group named "admin"

rblcoder commented 6 months ago

@yoicomment admin is the user we are authenticating with from Terraform OpenSearch Provider.

ghost commented 6 months ago

I'm utterly confused. Why would you add a user to "backend_roles"?

rblcoder commented 6 months ago

This is my "internal_users.yml" file.

_meta:
  type: "internalusers"
  config_version: 2

# Define your internal users here

admin:
  hash: "$2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG"
  reserved: true
  backend_roles:
  - "admin"
  description: "Admin user"

This is my "roles_mapping.yml" file:

_meta:
  type: "rolesmapping"
  config_version: 2

all_access:
  reserved: true
  hidden: false
  backend_roles:
  - "admin"
  hosts: []
  users: []
  and_backend_roles: []
  description: "Maps admin to all_access"

I use this for:

provider "opensearch" {
  url = "https://localhost:9200"
  username          = "admin"
  password          = "admin"
}

The name of the ldap group is:

all_admins

Now, I wanna assign the role to this ldap group:

resource "opensearch_roles_mapping" "mapper" {
  role_name   = "all_access"
  description = "Mapping all_access role to ldap group"
  backend_roles = ["all_admins"]
}

And this does not work for me.

admin was already specified under backend_roles in your roles_mapping.yml, the same needs to be specified again in the terraform code.

ghost commented 6 months ago

What if I omit "admin" from:

backend_roles = ["admin", "all_admins"]

and have only:

backend_roles = ["all_admins"]

What would happen then?

ghost commented 6 months ago

Would the user "admin" still have the role of "all_access"?

rblcoder commented 6 months ago

@yoicomment If admin is removed from backend_roles = ["admin", "all_admins"], admin will no longer be mapped to all_access.

ghost commented 6 months ago

@rblcoder but why need to add it to backend_roles when it is already set in the roles_mapping.yml file?

ghost commented 6 months ago

@rblcoder Somehow, the role mapping from roles_mapping.yml file is overwritten by the terraform roles mapping. Isn't that strange?

rblcoder commented 6 months ago

@yoicomment The Security plugin stores its configuration including users, roles, permissions, and backend settings in a system index on the OpenSearch cluster.

roles_mapping.yml is applied using securityadmin.sh script.

After the .opendistro_security index is initialized, you can use OpenSearch Dashboards or the REST API to manage your users, roles, and permissions. Refer https://opensearch.org/docs/latest/security/configuration/security-admin/

Three ways to map users to roles OpenSearch Dashboards roles_mapping.yml REST API Refer https://opensearch.org/docs/2.11/security/access-control/users-roles/

The rest api PUT _plugins/_security/api/rolesmapping/ Creates the specified role mapping if it does not already exist or replaces it if it already exists. https://opensearch.org/docs/latest/security/access-control/api/

This is the api called by the Terraform OpenSearch Provider.

Since the role mapping already exists, it is replaced when we call the REST API.

ghost commented 6 months ago

@rblcoder okay, this makes sense! Thank you :)

prudhvigodithi commented 6 months ago

Thanks @rblcoder

ghost commented 6 months ago

@prudhvigodithi she smart tho, aws should hire her