How to add backend role or admin permissions for SAML authenticated user

Hi,

I have configured SAML SSO in my opensearch and I am able to authenticate into my opensearch using single sign-on.

Also my config.yaml file has authc section for SAML, but don’t have authz section. Also in the opensearch documentation, I didn’t find authz section. So is it correct that SAML doesn’t need authz section? please clarify.

But after authentication, I am not able to see any role under backend roles. I want to have admin permissions to the user who is authenticated through single sign-on. Do we need to have something configured on IDP side on SAML or just adding backend role works?

How can I achieve this?

Hi @ravis85. Could you share the following?

  1. OpenSearch version
  2. What is the SAML IdP
  3. content of config.yml and opensearch_dashboards.yml

Hi @pablo

Thanks for your reply.

Please see below requested information.

  1. OpenSearch version - opensearch:1.3.2
  2. SAML IdP - PingIdentity
  3. Contents of config.yml and opensearch_dashboards.yml are as below.

opensearch_dashboards.yml -

# SPDX-License-Identifier: Apache-2.0

# Description:
# Default configuration for OpenSearch Dashboards

#timelion.ui.enabled: true
#server.name: opensearch-dashboards
server.host: "0"
opensearch.hosts: ["https://localhost:9200"]
opensearch.ssl.verificationMode: none
opensearch.username: "kibanaserver"
opensearch.password: "kibanaserver"
opensearch.requestHeadersWhitelist: [ authorization,securitytenant ]

opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"]
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
# Use this setting if you are running opensearch-dashboards without https
#opensearch_security.cookie.secure: false
opensearch_security.auth.type: "saml"
#server.xsrf.whitelist: ["/_plugins/_security/saml/acs/idpinitiated", "/_plugins/_security/saml/acs", "/_plugins/_security/saml/logout"]
server.xsrf.whitelist: [/_plugins/_security/saml/acs,/_opendistro/_security/saml/acs,/_plugins/_security/saml/acs/idpinitiated,/_opendistro/_security/saml/acs/idpinitiated,/_plugins/_security/saml/logout,/_opendistro/_security/saml/logout]```

config.yml -


# This is the main OpenSearch Security configuration file where authentication
# and authorization is defined.
#
# You need to configure at least one authentication domain in the authc of this file.
# An authentication domain is responsible for extracting the user credentials from
# the request and for validating them against an authentication backend like Active Directory for example.
#
# If more than one authentication domain is configured the first one which succeeds wins.
# If all authentication domains fail then the request is unauthenticated.
# In this case an exception is thrown and/or the HTTP status is set to 401.
#
# After authentication authorization (authz) will be applied. There can be zero or more authorizers which collect
# the roles from a given backend for the authenticated user.
#
# Both, authc and auth can be enabled/disabled separately for REST and TRANSPORT layer. Default is true for both.
#        http_enabled: true
#        transport_enabled: true
#
# For HTTP it is possible to allow anonymous authentication. If that is the case then the HTTP authenticators try to
# find user credentials in the HTTP request. If credentials are found then the user gets regularly authenticated.
# If none can be found the user will be authenticated as an "anonymous" user. This user has always the username "anonymous"
# and one role named "anonymous_backendrole".
# If you enable anonymous authentication all HTTP authenticators will not challenge.
#
#
# Note: If you define more than one HTTP authenticators make sure to put non-challenging authenticators like "proxy" or "clientcert"
# first and the challenging one last.
# Because it's not possible to challenge a client with two different authentication methods (for example
# Kerberos and Basic) only one can have the challenge flag set to true. You can cope with this situation
# by using pre-authentication, e.g. sending a HTTP Basic authentication header in the request.
#
# Default value of the challenge flag is true.
#
#
# HTTP
#   basic (challenging)
#   proxy (not challenging, needs xff)
#   kerberos (challenging)
#   clientcert (not challenging, needs https)
#   jwt (not challenging)
#   host (not challenging) #DEPRECATED, will be removed in a future version.
#                          host based authentication is configurable in roles_mapping

# Authc
#   internal
#   noop
#   ldap

# Authz
#   ldap
#   noop



_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    # Set filtered_alias_mode to 'disallow' to forbid more than 2 filtered aliases per index
    # Set filtered_alias_mode to 'warn' to allow more than 2 filtered aliases per index but warns about it (default)
    # Set filtered_alias_mode to 'nowarn' to allow more than 2 filtered aliases per index silently
    #filtered_alias_mode: warn
    #do_not_fail_on_forbidden: false
    #kibana:
    # Kibana multitenancy
    #multitenancy_enabled: true
    #server_username: kibanaserver
    #index: '.kibana'
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
        internalProxies: '192\.168\.0\.10|192\.168\.0\.11' # regex pattern
        #internalProxies: '.*' # trust all internal proxies, regex pattern
        #remoteIpHeader:  'x-forwarded-for'
        ###### see https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for regex help
        ###### more information about XFF https://en.wikipedia.org/wiki/X-Forwarded-For
        ###### and here https://tools.ietf.org/html/rfc7239
        ###### and https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve

    authc:
      internal_auth:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: internal
      saml_auth_domain:
        http_enabled: true
        transport_enabled: false
        order: 1
        description: "SAML provider"
        http_authenticator:
          type: saml
          challenge: true
          config:
            idp:
              enable_ssl: true
              verify_hostnames: true
              metadata_file: /usr/share/opensearch/plugins/opensearch-security/securityconfig/metadata.xml
              entity_id: https://ssodev.example.com/entity
            sp:
              entity_id: https://sandbox.elk.example.com
#              forceAuthn: true
            kibana_url: https://sandbox.elk.example.com
#            subject_key: UserID
           roles_key: Role
            exchange_key: '88d7fe3fd7624e98490a9e6c68daeaedc7467863189d22d36113b39a8fbf5e60'
        authentication_backend:
          type: noop```

Hello @pablo ,

I have the same problem here, since we can’t use two different auth solution at the same time, once saml is enabled i can’t connect with the admin account and set the roles.

I even tried to find the saml users in the database but i can’t find them, i tried to patch the saml user with this command :

curl -XPATCH https://opensearch-dashboards:9200/_plugins/_security/api/internalusers/me@mydomain.com -u admin:mypassword -k -H 'Content-Type: application/json' -d '[{"op": "replace", "path": "/backend_roles", "value": ["admin"]}]'

but answer is :

{"status":"NOT_FOUND","message":"user me@mydomain.com not found."}

When i connect on opensearch dashboards by saml i though it will create the user but apparently not.

opensearch version : 2.0.1
SAML idp : gsuite
content of config.yml and opensearch_dashboards.yml is very very similar to @ravis85

@ravis85 I just managed to change the permission of my saml user with this :

curl -XPATCH https://opensearch:9200/_plugins/_security/api/rolesmapping/all_access -u admin:mypassword -k -H 'Content-Type: application/json' -H 'Accept: application/json' -d '[{"op":"add", "path": "/users", "value": ["me@mydomain.com"]}]'

just change the value field, the -u admin:mypassword to your admin internal user (default is admin:admin) and the host.

hope this help

@nomopo Have you tried using securityadmin.sh and yml config files instead.

Hi @pablo
Could you please check my files and suggest what can be done?

Hi @nomopo Thanks for your help.

It worked for me, however this is a manual approach. I would like to have a setup like whenever a group sign in using single sign-on, he should get the admin privileges, but this needs to be for some group of users(based on distribution list) and not for all.

Rest all the users should be authenticated using single sign on and can have a member privileges.

Is it possible to implement? please suggest.

@ravis85 I’ve got the PingID and SAML working in my lab.
In regards to authz, SAML authentication doesn’t need this section. It is used only by LDAP authentication as LDAP connection is split into a two-phase connection handshake - authentication and authorization.

In SAML authentication, the authorization part is configured by Attribute Mappings and included in the authorization token.

Then in config.yml you need to point to that mapping.

image

Below is an example of mapping custom PingID group with role in OpenSearch.

I have a role called pablo in OpenSearch.
roles.yml

image

and mapping in roles_mapping.yml
image

I created a group in PingID called custom_role_1 and assigned it to user test2.

image

kibanauser role is required when you want to access OpenSearch Dashboards UI.

Using the above configuration OpenSearch will translate the mapping and assign correct roles.

image
image

@ravis85 I’ve just noticed that your roles_key is incorrectly indented in config.yml. It must be under config at the same level as kibana_url.

Hi @pablo

Thank you sharing the details and pointing out the issue in the indentation of roles_key. I will perform these changes and check.

I will let you know incase of any issues or doubts

Hi @pablo
One question, so for SAML, we need to create the groups on IDP side and map those groups with roles in Opensearch side, this is the way SAML in OpenSearch works?

Please correct me if my understanding is wrong.

Thanks

@ravis85 That’s correct.

Hi @pablo

I have made the changes on IdP side for atribute mapping of roles with group names(our DLs) and I can see that SAML response is returning the DLs. I have mapped that group to my admin role in backend_roles.

Now I can see my group from SAML in backend_roles in OpenSearch UI under “View roles and identities”, but I am not able to see “Security” tab" under “OpenSearch Plugins”.

I want to have “all_access” kind of role permissions for my group, which is I added in backend_roles, could you please share the snippet of “all_access” role, I am not able to find it in roles.yml

Please see below my roles.yml and roles_mapping.yml file

roles.yml -

i4dadminrole : {
  "reserved" : false,
  "hidden" : false,
  "cluster_permissions" : [
    "cluster_all"
  ],
  "index_permissions" : [
    {
      "index_patterns" : [
        "*"
      ],
      "dls" : "",
      "fls" : [ ],
      "masked_fields" : [ ],
      "allowed_actions" : [
        "crud"
      ]
    }
  ],
  "tenant_permissions" : [
    {
      "tenant_patterns" : [
        "global_tenant"
       ],
      "allowed_actions" : [
        "kibana_all_write"
      ]
    }
  ],
  "static" : false
}

roles_mapping.yml -

i4dadminrole:
  reserved: false
  backend_roles:
  - "DL GIM TI Prod Dev Infrastructure for Developers"
  description: "Maps DL GIM TIProd Dev Infrastructure for Developers from PingID to i4dadminrole role"

Could you please check and suggest if I am doing anything wrong here?

Also in the tenant_permissions, I have mentioned “global_tenant”, but after login, its showing me private tenant only.

Thanks

1 Like

Hi @pablo

Could you please check the above message and suggest?

Add admin backend role along with your group name in role_mapping.yml

Like grp_name , admin

Hi @kannappansenthil Thank you for your reply.

I tried adding admin backend role along with my group name as you suggested, still its not working. I can’t see “security” tab for my user(who is part of the group)

i4dadminrole:
  reserved: false
  backend_roles:
  - "DL GIM TI Prod Dev Infrastructure for Developers,admin"
  description: "Maps DL GIM TI Prod Dev Infrastructure for Developers from PingID to i4dadminrole role"

Hi ,

it should be list.

backend_roles:
  - "DL GIM TI Prod Dev Infrastructure for Developers"
  - "admin"

Hi @kannappansenthil

I tried providing as a list, but still I can’t see “security” for my user.

i4dadminrole:
  reserved: false
  backend_roles:
    - "DL GIM TI Prod Dev Infrastructure for Developers"
    - "admin"

Is my role(i4dadminrole) which I am mapping here has “cluster_all” permissions is correct for getting that “security” plugin tab in UI or some more permissions are required?

Could you please check my role and suggest whether its correct?