Pulling tenants from external source

When asking questions, please provide the following information:

*ElasticSearch 6.2.4 with Kibana 6.2.4 and SearchGuard 6.2.4-22.1 and matching SG Kibana plugin

*Java 1.8.0_112 on Windows 7, 64-bit

kibana.yml:

elasticsearch.username: “kibanaserver”

elasticsearch.password: “kibanaserver”

elasticsearch.requestHeadersWhitelist: [“sgtenant”, “Authorization”]

leoelasticsearch.ssl.verificationMode: none

searchguard.multitenancy.enabled: true

elasticsearch.yml

searchguard.ssl.transport.pemcert_filepath: esnode.pem

searchguard.ssl.transport.pemkey_filepath: esnode-key.pem

searchguard.ssl.transport.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.transport.enforce_hostname_verification: false

searchguard.ssl.http.enabled: true

searchguard.ssl.http.pemcert_filepath: esnode.pem

searchguard.ssl.http.pemkey_filepath: esnode-key.pem

searchguard.ssl.http.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.http.clientauth_mode: OPTIONAL

searchguard.allow_unsafe_democertificates: true

searchguard.allow_default_init_sgindex: true

searchguard.authcz.admin_dn:

  • CN=kirk,OU=client,O=client,L=test, C=de

searchguard.audit.type: internal_elasticsearch

searchguard.enable_snapshot_restore_privilege: true

searchguard.check_snapshot_restore_write_privileges: true

searchguard.restapi.roles_enabled: [“sg_all_access”]

cluster.routing.allocation.disk.threshold_enabled: false

cluster.name: searchguard_demo

network.host: 0.0.0.0

discovery.zen.minimum_master_nodes: 1

node.max_local_storage_nodes: 3

sg_config:

searchguard:

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

kibana:

Kibana multitenancy - NOT FREE FOR COMMERCIAL USE

To make this work you need to install Home · floragunncom/search-guard-module-kibana-multitenancy Wiki · GitHub

see https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md

multitenancy_enabled: true

server_username: kibanaserver

index: ‘.kibana’

#do_not_fail_on_forbidden: false

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’

proxiesHeader: ‘x-forwarded-by’

#trustedProxies: ‘.*’ # trust all external proxies, regex pattern

see Pattern (Java Platform SE 7 ) for regex help
more information about XFF X-Forwarded-For - Wikipedia
and here RFC 7239: Forwarded HTTP Extension
and Apache Tomcat 8 Configuration Reference (8.0.53) - The Valve Component

authc:

kerberos_auth_domain:

http_enabled: false

transport_enabled: false

order: 6

http_authenticator:

type: kerberos # NOT FREE FOR COMMERCIAL USE

challenge: true

config:

If true a lot of kerberos/security related debugging output will be logged to standard out

krb_debug: false

If true then the realm will be stripped from the user name

strip_realm_from_principal: true

authentication_backend:

type: noop

basic_internal_auth_domain:

http_enabled: true

transport_enabled: true

order: 4

http_authenticator:

type: basic

challenge: true

authentication_backend:

type: intern

proxy_auth_domain:

http_enabled: false

transport_enabled: false

order: 3

http_authenticator:

type: proxy

challenge: false

config:

user_header: “x-proxy-user”

roles_header: “x-proxy-roles”

authentication_backend:

type: noop

jwt_auth_domain:

http_enabled: false

transport_enabled: false

order: 0

http_authenticator:

type: jwt

challenge: false

config:

signing_key: “base64 encoded HMAC key or public RSA/ECDSA pem key”

jwt_header: “Authorization”

jwt_url_parameter: null

roles_key: null

subject_key: null

authentication_backend:

type: noop

clientcert_auth_domain:

http_enabled: false

transport_enabled: false

order: 2

http_authenticator:

type: clientcert

config:

username_attribute: cn #optional, if omitted DN becomes username

challenge: false

authentication_backend:

type: noop

ldap:

http_enabled: false

transport_enabled: false

order: 5

http_authenticator:

type: basic

challenge: false

authentication_backend:

LDAP authentication backend (authenticate users against a LDAP or Active Directory)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(sAMAccountName={0})’

Use this attribute from the user as username (if not set then DN is used)

username_attribute: null

authz:

roles_from_myldap:

http_enabled: false

transport_enabled: false

authorization_backend:

LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

rolebase: ‘ou=groups,dc=example,dc=com’

Filter to search for roles (currently in the whole subtree beneath rolebase)

{0} is substituted with the DN of the user

{1} is substituted with the username

{2} is substituted with an attribute value from user’s directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute

rolesearch: ‘(member={0})’

Specify the name of the attribute which value should be substituted with {2} above

userroleattribute: null

Roles as an attribute of the user entry

userrolename: disabled

#userrolename: memberOf

The attribute in a role entry containing the name of that role, Default is “name”.

Can also be “dn” to use the full DN as rolename.

rolename: cn

Resolve nested roles transitive (roles which are members of other roles and so on …)

resolve_nested_roles: true

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(uid={0})’

Skip users matching a user name, a wildcard or a regex pattern

#skip_users:

- ‘cn=Michael Jackson,ou*people,o=TEST’

- ‘/\S*/’

roles_from_another_ldap:

enabled: false

authorization_backend:

type: ldap # NOT FREE FOR COMMERCIAL USE

#config goes here …

Hello,

we are hosting a multi-tenant cloud service and looking forward to use Elasticsearch with Kibana and Searchguard to meet the needed security issues. As we currently already have different tenants, we were thinking about if it would be possible to somehow pull the tenants and their descriptions and declarations from an external source, maybe even automatically every now and then. Would that be possible with SG or would we need a script calling the SG API roles endpoint ourselves to modify/add/delete tenants?

Regards,

Anna

Hi Anna,

that’s a very specific feature and I’m afraid we do not support this out of the box. If you want to periodically update the tenants you would need to set up some kind of script or cron job that changes/updates the definition by either using sgadmin or the REST API.

I’m very curious since we did not get this question/feature request before: What is your actual use case for pulling in tenants definitions from an external source? We’re always keen to learn about the various usage scenarios of Search Guard so we can plan the feature roadmap accordingly. So anything you can share about your use case is most welcome!

···

On Wednesday, May 16, 2018 at 3:48:03 PM UTC+2, Anna Eimbeck wrote:

When asking questions, please provide the following information:

*ElasticSearch 6.2.4 with Kibana 6.2.4 and SearchGuard 6.2.4-22.1 and matching SG Kibana plugin

*Java 1.8.0_112 on Windows 7, 64-bit

kibana.yml:

elasticsearch.username: “kibanaserver”

elasticsearch.password: “kibanaserver”

elasticsearch.requestHeadersWhitelist: [“sgtenant”, “Authorization”]

leoelasticsearch.ssl.verificationMode: none

searchguard.multitenancy.enabled: true

elasticsearch.yml

searchguard.ssl.transport.pemcert_filepath: esnode.pem

searchguard.ssl.transport.pemkey_filepath: esnode-key.pem

searchguard.ssl.transport.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.transport.enforce_hostname_verification: false

searchguard.ssl.http.enabled: true

searchguard.ssl.http.pemcert_filepath: esnode.pem

searchguard.ssl.http.pemkey_filepath: esnode-key.pem

searchguard.ssl.http.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.http.clientauth_mode: OPTIONAL

searchguard.allow_unsafe_democertificates: true

searchguard.allow_default_init_sgindex: true

searchguard.authcz.admin_dn:

  • CN=kirk,OU=client,O=client,L=test, C=de

searchguard.audit.type: internal_elasticsearch

searchguard.enable_snapshot_restore_privilege: true

searchguard.check_snapshot_restore_write_privileges: true

searchguard.restapi.roles_enabled: [“sg_all_access”]

cluster.routing.allocation.disk.threshold_enabled: false

cluster.name: searchguard_demo

network.host: 0.0.0.0

discovery.zen.minimum_master_nodes: 1

node.max_local_storage_nodes: 3

sg_config:

searchguard:

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

kibana:

Kibana multitenancy - NOT FREE FOR COMMERCIAL USE

To make this work you need to install https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki

see https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md

multitenancy_enabled: true

server_username: kibanaserver

index: ‘.kibana’

#do_not_fail_on_forbidden: false

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’

proxiesHeader: ‘x-forwarded-by’

#trustedProxies: ‘.*’ # trust all external proxies, regex pattern

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:

kerberos_auth_domain:

http_enabled: false

transport_enabled: false

order: 6

http_authenticator:

type: kerberos # NOT FREE FOR COMMERCIAL USE

challenge: true

config:

If true a lot of kerberos/security related debugging output will be logged to standard out

krb_debug: false

If true then the realm will be stripped from the user name

strip_realm_from_principal: true

authentication_backend:

type: noop

basic_internal_auth_domain:

http_enabled: true

transport_enabled: true

order: 4

http_authenticator:

type: basic

challenge: true

authentication_backend:

type: intern

proxy_auth_domain:

http_enabled: false

transport_enabled: false

order: 3

http_authenticator:

type: proxy

challenge: false

config:

user_header: “x-proxy-user”

roles_header: “x-proxy-roles”

authentication_backend:

type: noop

jwt_auth_domain:

http_enabled: false

transport_enabled: false

order: 0

http_authenticator:

type: jwt

challenge: false

config:

signing_key: “base64 encoded HMAC key or public RSA/ECDSA pem key”

jwt_header: “Authorization”

jwt_url_parameter: null

roles_key: null

subject_key: null

authentication_backend:

type: noop

clientcert_auth_domain:

http_enabled: false

transport_enabled: false

order: 2

http_authenticator:

type: clientcert

config:

username_attribute: cn #optional, if omitted DN becomes username

challenge: false

authentication_backend:

type: noop

ldap:

http_enabled: false

transport_enabled: false

order: 5

http_authenticator:

type: basic

challenge: false

authentication_backend:

LDAP authentication backend (authenticate users against a LDAP or Active Directory)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(sAMAccountName={0})’

Use this attribute from the user as username (if not set then DN is used)

username_attribute: null

authz:

roles_from_myldap:

http_enabled: false

transport_enabled: false

authorization_backend:

LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

rolebase: ‘ou=groups,dc=example,dc=com’

Filter to search for roles (currently in the whole subtree beneath rolebase)

{0} is substituted with the DN of the user

{1} is substituted with the username

{2} is substituted with an attribute value from user’s directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute

rolesearch: ‘(member={0})’

Specify the name of the attribute which value should be substituted with {2} above

userroleattribute: null

Roles as an attribute of the user entry

userrolename: disabled

#userrolename: memberOf

The attribute in a role entry containing the name of that role, Default is “name”.

Can also be “dn” to use the full DN as rolename.

rolename: cn

Resolve nested roles transitive (roles which are members of other roles and so on …)

resolve_nested_roles: true

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(uid={0})’

Skip users matching a user name, a wildcard or a regex pattern

#skip_users:

- ‘cn=Michael Jackson,ou*people,o=TEST’

- ‘/\S*/’

roles_from_another_ldap:

enabled: false

authorization_backend:

type: ldap # NOT FREE FOR COMMERCIAL USE

#config goes here …

Hello,

we are hosting a multi-tenant cloud service and looking forward to use Elasticsearch with Kibana and Searchguard to meet the needed security issues. As we currently already have different tenants, we were thinking about if it would be possible to somehow pull the tenants and their descriptions and declarations from an external source, maybe even automatically every now and then. Would that be possible with SG or would we need a script calling the SG API roles endpoint ourselves to modify/add/delete tenants?

Regards,

Anna

Hi Jochen,

coming from there, I would like to explain the current scenario we have:

We offer a cloud environment with a report function. Said function should be realized with the use of Kibana and SearchGuard to secure the ElasticSearch database working in the backend. As the reports shall be used for different customers, we want to use the multi-tenancy feature of SearchGuard. The reports shall be integrated into the existing cloud environment meaning we currently already have a tenant database as well as a user database, making use of a claim based authentication (OAuth). I asked for the external pulling of tenants as for we do not want to administer 2 places where we use tenants. What we are also interested in is a Single-Sign-On Solution. As we also want to use our claim based authentication integrated into SearchGuard, I was wondering how it would be possible to put together the users with their matching tenants. Having users and matching tenants in our database, would we need to put the matching tenant into the token?

···

Am Mittwoch, 16. Mai 2018 22:40:09 UTC+2 schrieb Jochen Kressin:

Hi Anna,

that’s a very specific feature and I’m afraid we do not support this out of the box. If you want to periodically update the tenants you would need to set up some kind of script or cron job that changes/updates the definition by either using sgadmin or the REST API.

I’m very curious since we did not get this question/feature request before: What is your actual use case for pulling in tenants definitions from an external source? We’re always keen to learn about the various usage scenarios of Search Guard so we can plan the feature roadmap accordingly. So anything you can share about your use case is most welcome!

On Wednesday, May 16, 2018 at 3:48:03 PM UTC+2, Anna Eimbeck wrote:

When asking questions, please provide the following information:

*ElasticSearch 6.2.4 with Kibana 6.2.4 and SearchGuard 6.2.4-22.1 and matching SG Kibana plugin

*Java 1.8.0_112 on Windows 7, 64-bit

kibana.yml:

elasticsearch.username: “kibanaserver”

elasticsearch.password: “kibanaserver”

elasticsearch.requestHeadersWhitelist: [“sgtenant”, “Authorization”]

leoelasticsearch.ssl.verificationMode: none

searchguard.multitenancy.enabled: true

elasticsearch.yml

searchguard.ssl.transport.pemcert_filepath: esnode.pem

searchguard.ssl.transport.pemkey_filepath: esnode-key.pem

searchguard.ssl.transport.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.transport.enforce_hostname_verification: false

searchguard.ssl.http.enabled: true

searchguard.ssl.http.pemcert_filepath: esnode.pem

searchguard.ssl.http.pemkey_filepath: esnode-key.pem

searchguard.ssl.http.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.http.clientauth_mode: OPTIONAL

searchguard.allow_unsafe_democertificates: true

searchguard.allow_default_init_sgindex: true

searchguard.authcz.admin_dn:

  • CN=kirk,OU=client,O=client,L=test, C=de

searchguard.audit.type: internal_elasticsearch

searchguard.enable_snapshot_restore_privilege: true

searchguard.check_snapshot_restore_write_privileges: true

searchguard.restapi.roles_enabled: [“sg_all_access”]

cluster.routing.allocation.disk.threshold_enabled: false

cluster.name: searchguard_demo

network.host: 0.0.0.0

discovery.zen.minimum_master_nodes: 1

node.max_local_storage_nodes: 3

sg_config:

searchguard:

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

kibana:

Kibana multitenancy - NOT FREE FOR COMMERCIAL USE

To make this work you need to install https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki

see https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md

multitenancy_enabled: true

server_username: kibanaserver

index: ‘.kibana’

#do_not_fail_on_forbidden: false

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’

proxiesHeader: ‘x-forwarded-by’

#trustedProxies: ‘.*’ # trust all external proxies, regex pattern

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:

kerberos_auth_domain:

http_enabled: false

transport_enabled: false

order: 6

http_authenticator:

type: kerberos # NOT FREE FOR COMMERCIAL USE

challenge: true

config:

If true a lot of kerberos/security related debugging output will be logged to standard out

krb_debug: false

If true then the realm will be stripped from the user name

strip_realm_from_principal: true

authentication_backend:

type: noop

basic_internal_auth_domain:

http_enabled: true

transport_enabled: true

order: 4

http_authenticator:

type: basic

challenge: true

authentication_backend:

type: intern

proxy_auth_domain:

http_enabled: false

transport_enabled: false

order: 3

http_authenticator:

type: proxy

challenge: false

config:

user_header: “x-proxy-user”

roles_header: “x-proxy-roles”

authentication_backend:

type: noop

jwt_auth_domain:

http_enabled: false

transport_enabled: false

order: 0

http_authenticator:

type: jwt

challenge: false

config:

signing_key: “base64 encoded HMAC key or public RSA/ECDSA pem key”

jwt_header: “Authorization”

jwt_url_parameter: null

roles_key: null

subject_key: null

authentication_backend:

type: noop

clientcert_auth_domain:

http_enabled: false

transport_enabled: false

order: 2

http_authenticator:

type: clientcert

config:

username_attribute: cn #optional, if omitted DN becomes username

challenge: false

authentication_backend:

type: noop

ldap:

http_enabled: false

transport_enabled: false

order: 5

http_authenticator:

type: basic

challenge: false

authentication_backend:

LDAP authentication backend (authenticate users against a LDAP or Active Directory)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(sAMAccountName={0})’

Use this attribute from the user as username (if not set then DN is used)

username_attribute: null

authz:

roles_from_myldap:

http_enabled: false

transport_enabled: false

authorization_backend:

LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

rolebase: ‘ou=groups,dc=example,dc=com’

Filter to search for roles (currently in the whole subtree beneath rolebase)

{0} is substituted with the DN of the user

{1} is substituted with the username

{2} is substituted with an attribute value from user’s directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute

rolesearch: ‘(member={0})’

Specify the name of the attribute which value should be substituted with {2} above

userroleattribute: null

Roles as an attribute of the user entry

userrolename: disabled

#userrolename: memberOf

The attribute in a role entry containing the name of that role, Default is “name”.

Can also be “dn” to use the full DN as rolename.

rolename: cn

Resolve nested roles transitive (roles which are members of other roles and so on …)

resolve_nested_roles: true

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(uid={0})’

Skip users matching a user name, a wildcard or a regex pattern

#skip_users:

- ‘cn=Michael Jackson,ou*people,o=TEST’

- ‘/\S*/’

roles_from_another_ldap:

enabled: false

authorization_backend:

type: ldap # NOT FREE FOR COMMERCIAL USE

#config goes here …

Hello,

we are hosting a multi-tenant cloud service and looking forward to use Elasticsearch with Kibana and Searchguard to meet the needed security issues. As we currently already have different tenants, we were thinking about if it would be possible to somehow pull the tenants and their descriptions and declarations from an external source, maybe even automatically every now and then. Would that be possible with SG or would we need a script calling the SG API roles endpoint ourselves to modify/add/delete tenants?

Regards,

Anna

Hi Anna,

thanks for the explanation, that makes sense. However, I do see one problem here: You say that you are using claim based authentication (JWT maybe?). In this scenario, the identity or access token identifies a unique user. However, the tenants in Search Guard/Kibana are tied to a Search Guard role, not a single user. This means to add/remove tenants for a particular user you need to add/remove them from one of the Search Guard roles the user is assigned to.

If I understand your scenario correctly, you want to add tenant information directly to your token, as a new claim. And Search Guard should then use this information to kind of create the tenants dynamically from this claim. This is not possible at the moment, but I think it is a valuable idea. I will definitely add it to our backlog.

Thanks for the info, and let me know if I got something wrong here.

···

On Thursday, May 17, 2018 at 2:46:04 PM UTC+2, Anna Eimbeck wrote:

Hi Jochen,

coming from there, I would like to explain the current scenario we have:

We offer a cloud environment with a report function. Said function should be realized with the use of Kibana and SearchGuard to secure the ElasticSearch database working in the backend. As the reports shall be used for different customers, we want to use the multi-tenancy feature of SearchGuard. The reports shall be integrated into the existing cloud environment meaning we currently already have a tenant database as well as a user database, making use of a claim based authentication (OAuth). I asked for the external pulling of tenants as for we do not want to administer 2 places where we use tenants. What we are also interested in is a Single-Sign-On Solution. As we also want to use our claim based authentication integrated into SearchGuard, I was wondering how it would be possible to put together the users with their matching tenants. Having users and matching tenants in our database, would we need to put the matching tenant into the token?

Am Mittwoch, 16. Mai 2018 22:40:09 UTC+2 schrieb Jochen Kressin:

Hi Anna,

that’s a very specific feature and I’m afraid we do not support this out of the box. If you want to periodically update the tenants you would need to set up some kind of script or cron job that changes/updates the definition by either using sgadmin or the REST API.

I’m very curious since we did not get this question/feature request before: What is your actual use case for pulling in tenants definitions from an external source? We’re always keen to learn about the various usage scenarios of Search Guard so we can plan the feature roadmap accordingly. So anything you can share about your use case is most welcome!

On Wednesday, May 16, 2018 at 3:48:03 PM UTC+2, Anna Eimbeck wrote:

When asking questions, please provide the following information:

*ElasticSearch 6.2.4 with Kibana 6.2.4 and SearchGuard 6.2.4-22.1 and matching SG Kibana plugin

*Java 1.8.0_112 on Windows 7, 64-bit

kibana.yml:

elasticsearch.username: “kibanaserver”

elasticsearch.password: “kibanaserver”

elasticsearch.requestHeadersWhitelist: [“sgtenant”, “Authorization”]

leoelasticsearch.ssl.verificationMode: none

searchguard.multitenancy.enabled: true

elasticsearch.yml

searchguard.ssl.transport.pemcert_filepath: esnode.pem

searchguard.ssl.transport.pemkey_filepath: esnode-key.pem

searchguard.ssl.transport.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.transport.enforce_hostname_verification: false

searchguard.ssl.http.enabled: true

searchguard.ssl.http.pemcert_filepath: esnode.pem

searchguard.ssl.http.pemkey_filepath: esnode-key.pem

searchguard.ssl.http.pemtrustedcas_filepath: root-ca.pem

searchguard.ssl.http.clientauth_mode: OPTIONAL

searchguard.allow_unsafe_democertificates: true

searchguard.allow_default_init_sgindex: true

searchguard.authcz.admin_dn:

  • CN=kirk,OU=client,O=client,L=test, C=de

searchguard.audit.type: internal_elasticsearch

searchguard.enable_snapshot_restore_privilege: true

searchguard.check_snapshot_restore_write_privileges: true

searchguard.restapi.roles_enabled: [“sg_all_access”]

cluster.routing.allocation.disk.threshold_enabled: false

cluster.name: searchguard_demo

network.host: 0.0.0.0

discovery.zen.minimum_master_nodes: 1

node.max_local_storage_nodes: 3

sg_config:

searchguard:

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

kibana:

Kibana multitenancy - NOT FREE FOR COMMERCIAL USE

To make this work you need to install https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki

see https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md

multitenancy_enabled: true

server_username: kibanaserver

index: ‘.kibana’

#do_not_fail_on_forbidden: false

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’

proxiesHeader: ‘x-forwarded-by’

#trustedProxies: ‘.*’ # trust all external proxies, regex pattern

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:

kerberos_auth_domain:

http_enabled: false

transport_enabled: false

order: 6

http_authenticator:

type: kerberos # NOT FREE FOR COMMERCIAL USE

challenge: true

config:

If true a lot of kerberos/security related debugging output will be logged to standard out

krb_debug: false

If true then the realm will be stripped from the user name

strip_realm_from_principal: true

authentication_backend:

type: noop

basic_internal_auth_domain:

http_enabled: true

transport_enabled: true

order: 4

http_authenticator:

type: basic

challenge: true

authentication_backend:

type: intern

proxy_auth_domain:

http_enabled: false

transport_enabled: false

order: 3

http_authenticator:

type: proxy

challenge: false

config:

user_header: “x-proxy-user”

roles_header: “x-proxy-roles”

authentication_backend:

type: noop

jwt_auth_domain:

http_enabled: false

transport_enabled: false

order: 0

http_authenticator:

type: jwt

challenge: false

config:

signing_key: “base64 encoded HMAC key or public RSA/ECDSA pem key”

jwt_header: “Authorization”

jwt_url_parameter: null

roles_key: null

subject_key: null

authentication_backend:

type: noop

clientcert_auth_domain:

http_enabled: false

transport_enabled: false

order: 2

http_authenticator:

type: clientcert

config:

username_attribute: cn #optional, if omitted DN becomes username

challenge: false

authentication_backend:

type: noop

ldap:

http_enabled: false

transport_enabled: false

order: 5

http_authenticator:

type: basic

challenge: false

authentication_backend:

LDAP authentication backend (authenticate users against a LDAP or Active Directory)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(sAMAccountName={0})’

Use this attribute from the user as username (if not set then DN is used)

username_attribute: null

authz:

roles_from_myldap:

http_enabled: false

transport_enabled: false

authorization_backend:

LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)

type: ldap # NOT FREE FOR COMMERCIAL USE

config:

enable ldaps

enable_ssl: false

enable start tls, enable_ssl should be false

enable_start_tls: false

send client certificate

enable_ssl_client_auth: false

verify ldap hostname

verify_hostnames: true

hosts:

  • localhost:8389

bind_dn: null

password: null

rolebase: ‘ou=groups,dc=example,dc=com’

Filter to search for roles (currently in the whole subtree beneath rolebase)

{0} is substituted with the DN of the user

{1} is substituted with the username

{2} is substituted with an attribute value from user’s directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute

rolesearch: ‘(member={0})’

Specify the name of the attribute which value should be substituted with {2} above

userroleattribute: null

Roles as an attribute of the user entry

userrolename: disabled

#userrolename: memberOf

The attribute in a role entry containing the name of that role, Default is “name”.

Can also be “dn” to use the full DN as rolename.

rolename: cn

Resolve nested roles transitive (roles which are members of other roles and so on …)

resolve_nested_roles: true

userbase: ‘ou=people,dc=example,dc=com’

Filter to search for users (currently in the whole subtree beneath userbase)

{0} is substituted with the username

usersearch: ‘(uid={0})’

Skip users matching a user name, a wildcard or a regex pattern

#skip_users:

- ‘cn=Michael Jackson,ou*people,o=TEST’

- ‘/\S*/’

roles_from_another_ldap:

enabled: false

authorization_backend:

type: ldap # NOT FREE FOR COMMERCIAL USE

#config goes here …

Hello,

we are hosting a multi-tenant cloud service and looking forward to use Elasticsearch with Kibana and Searchguard to meet the needed security issues. As we currently already have different tenants, we were thinking about if it would be possible to somehow pull the tenants and their descriptions and declarations from an external source, maybe even automatically every now and then. Would that be possible with SG or would we need a script calling the SG API roles endpoint ourselves to modify/add/delete tenants?

Regards,

Anna