add searchguard

add authentication to elk with searchguard

Issue-ID: CLAMP-419

Change-Id: I66bca485750e3377db10f6f43efb7f741a42c17d
Signed-off-by: osgn422w <gervais-martial.ngueko@intl.att.com>
diff --git a/src/main/docker/elasticsearch/Dockerfile b/src/main/docker/elasticsearch/Dockerfile
new file mode 100644
index 0000000..2c932c8
--- /dev/null
+++ b/src/main/docker/elasticsearch/Dockerfile
@@ -0,0 +1,20 @@
+# https://github.com/elastic/elasticsearch-docker
+FROM docker.elastic.co/elasticsearch/elasticsearch:6.6.2
+
+COPY config/sg/ config/sg/
+COPY config/ config/
+COPY bin/ bin/
+#RUN chmod +x bin/init_sg.sh
+COPY my-entrypoint.sh /usr/local/bin/my-entrypoint.sh
+# Search Guard plugin
+RUN elasticsearch-plugin install --batch com.floragunn:search-guard-6:6.6.2-25.1 \
+	&& chmod +x plugins/search-guard-6/tools/*.sh \
+	&& chown -R elasticsearch config/sg/ \
+	&& chmod -R go= config/sg/
+
+# Add your elasticsearch plugins setup here
+# Example: RUN elasticsearch-plugin install analysis-icu
+
+#  This custom entrypoint script is used instead of 
+# the original's /usr/local/bin/docker-entrypoint.sh
+ENTRYPOINT ["bash","-c","my-entrypoint.sh"]
\ No newline at end of file
diff --git a/src/main/docker/elasticsearch/bin/init_sg.sh b/src/main/docker/elasticsearch/bin/init_sg.sh
new file mode 100644
index 0000000..1c4e607
--- /dev/null
+++ b/src/main/docker/elasticsearch/bin/init_sg.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+plugins/search-guard-6/tools/sgadmin.sh \
+	-cd config/sg/ \
+	-ts config/sg/truststore.jks \
+	-ks config/sg/kirk-keystore.jks \
+	-nhnv \
+	-icl
\ No newline at end of file
diff --git a/src/main/docker/elasticsearch/config/elasticsearch.yml b/src/main/docker/elasticsearch/config/elasticsearch.yml
new file mode 100644
index 0000000..72ce137
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/elasticsearch.yml
@@ -0,0 +1,33 @@
+---
+## Default Elasticsearch configuration from elasticsearch-docker.
+## from https://github.com/elastic/elasticsearch-docker/blob/master/.tedi/template/elasticsearch.yml
+#
+cluster.name: "docker-cluster"
+network.host: 0.0.0.0
+
+# minimum_master_nodes need to be explicitly set when bound on a public IP
+# set to 1 to allow single node clusters
+# Details: https://github.com/elastic/elasticsearch/pull/17288
+discovery.zen.minimum_master_nodes: 1
+
+## Use single node discovery in order to disable production mode and avoid bootstrap checks
+## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
+#
+discovery.type: single-node
+
+## X-Pack settings
+## see https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-xpack.html
+#
+xpack.license.self_generated.type: basic
+xpack.security.enabled: false
+
+## Search Guard
+#
+searchguard.enterprise_modules_enabled: false
+
+searchguard.ssl.transport.keystore_filepath: sg/node-0-keystore.jks
+searchguard.ssl.transport.truststore_filepath: sg/truststore.jks
+searchguard.ssl.transport.enforce_hostname_verification: false
+
+searchguard.authcz.admin_dn:
+  - "CN=kirk,OU=client,O=client,l=tEst,C=De"
diff --git a/src/main/docker/elasticsearch/config/sg/kirk-keystore.jks b/src/main/docker/elasticsearch/config/sg/kirk-keystore.jks
new file mode 100644
index 0000000..dd7562e
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/kirk-keystore.jks
Binary files differ
diff --git a/src/main/docker/elasticsearch/config/sg/node-0-keystore.jks b/src/main/docker/elasticsearch/config/sg/node-0-keystore.jks
new file mode 100644
index 0000000..5693b7b
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/node-0-keystore.jks
Binary files differ
diff --git a/src/main/docker/elasticsearch/config/sg/sg_action_groups.yml b/src/main/docker/elasticsearch/config/sg/sg_action_groups.yml
new file mode 100644
index 0000000..38ffef0
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/sg_action_groups.yml
@@ -0,0 +1,153 @@
+UNLIMITED:
+  readonly: true
+  permissions:
+    - "*"
+
+###### INDEX LEVEL ######
+
+INDICES_ALL:
+  readonly: true
+  permissions:
+    - "indices:*"
+
+# for backward compatibility
+ALL:
+  readonly: true
+  permissions:
+    - INDICES_ALL
+
+MANAGE:
+  readonly: true
+  permissions:
+    - "indices:monitor/*"
+    - "indices:admin/*"
+
+CREATE_INDEX:
+  readonly: true
+  permissions:
+    - "indices:admin/create"
+    - "indices:admin/mapping/put"
+
+MANAGE_ALIASES:
+  readonly: true
+  permissions:
+    - "indices:admin/aliases*"
+
+INDEX_OWNER:
+  - CREATE_INDEX
+  - CRUD
+
+# for backward compatibility
+MONITOR:
+  readonly: true
+  permissions:
+    - INDICES_MONITOR
+
+INDICES_MONITOR:
+  readonly: true
+  permissions:
+    - "indices:monitor/*"
+
+DATA_ACCESS:
+  readonly: true
+  permissions:
+    - "indices:data/*"
+    - CRUD
+
+WRITE:
+  readonly: true
+  permissions:
+    - "indices:data/write*"
+    - "indices:admin/mapping/put"
+
+READ:
+  readonly: true
+  permissions:
+    - "indices:data/read*"
+    - "indices:admin/mappings/fields/get*"
+
+DELETE:
+  readonly: true
+  permissions:
+    - "indices:data/write/delete*"
+
+CRUD:
+  readonly: true
+  permissions:
+    - READ
+    - WRITE
+
+SEARCH:
+  readonly: true
+  permissions:
+    - "indices:data/read/search*"
+    - "indices:data/read/msearch*"
+    - SUGGEST
+
+SUGGEST:
+  readonly: true
+  permissions:
+    - "indices:data/read/suggest*"
+
+INDEX:
+  readonly: true
+  permissions:
+    - "indices:data/write/index*"
+    - "indices:data/write/update*"
+    - "indices:admin/mapping/put"
+    - "indices:data/write/bulk*"
+
+GET:
+  readonly: true
+  permissions:
+    - "indices:data/read/get*"
+    - "indices:data/read/mget*"
+
+###### CLUSTER LEVEL ######
+
+CLUSTER_ALL:
+  readonly: true
+  permissions:
+    - "cluster:*"
+
+CLUSTER_MONITOR:
+  readonly: true
+  permissions:
+    - "cluster:monitor/*"
+
+CLUSTER_COMPOSITE_OPS_RO:
+  readonly: true
+  permissions:
+    - "indices:data/read/mget"
+    - "indices:data/read/msearch"
+    - "indices:data/read/mtv"
+    - "indices:admin/aliases/exists*"
+    - "indices:admin/aliases/get*"
+    - "indices:data/read/scroll"
+
+CLUSTER_COMPOSITE_OPS:
+  readonly: true
+  permissions:
+    - "indices:data/write/bulk"
+    - "indices:admin/aliases*"
+    - "indices:data/write/reindex"
+    - CLUSTER_COMPOSITE_OPS_RO
+  
+MANAGE_SNAPSHOTS:
+  readonly: true
+  permissions:
+    - "cluster:admin/snapshot/*"
+    - "cluster:admin/repository/*"
+
+# CLAMPDASHBOARD ELASTICSEARCH ENTRYPOINT
+GET_TEMPLATE:
+  - "indices:admin/template/get"
+PUT_TEMPLATE:
+  - "indices:admin/template/put"
+TEMPLATE_OWNER:
+  - GET_TEMPLATE
+  - PUT_TEMPLATE
+ES_INPUT:
+  - TEMPLATE_OWNER
+  - WRITE
+  - MONITOR
diff --git a/src/main/docker/elasticsearch/config/sg/sg_config.yml b/src/main/docker/elasticsearch/config/sg/sg_config.yml
new file mode 100644
index 0000000..7d3a933
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/sg_config.yml
@@ -0,0 +1,238 @@
+# This is the main Search Guard 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
+#
+# 5.x Migration: "enabled: true/false" will also be respected currently but only to provide backward compatibility.
+#
+# 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 "sg_anonymous"
+# and one role named "sg_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) NOT FREE FOR COMMERCIAL
+#   clientcert (not challenging, needs https)
+#   jwt (not challenging) NOT FREE FOR COMMERCIAL
+#   host (not challenging) #DEPRECATED, will be removed in a future version.
+#                           host based authentication is configurable in sg_roles_mapping
+
+# Authc
+#   internal
+#   noop
+#   ldap  NOT FREE FOR COMMERCIAL USE
+
+# Authz
+#   ldap  NOT FREE FOR COMMERCIAL USE
+#   noop
+
+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
+      # see https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md
+      # To make this work you need to install https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki
+      #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 ...
+#    auth_failure_listeners:
+#      ip_rate_limiting:
+#        type: ip
+#        allowed_tries: 10
+#        time_window_seconds: 3600
+#        block_expiry_seconds: 600
+#        max_blocked_clients: 100000
+#        max_tracked_clients: 100000
+#      internal_authentication_backend_limiting:
+#        type: username
+#        authentication_backend: intern        
+#        allowed_tries: 10
+#        time_window_seconds: 3600
+#        block_expiry_seconds: 600
+#        max_blocked_clients: 100000
+#        max_tracked_clients: 100000
+        
\ No newline at end of file
diff --git a/src/main/docker/elasticsearch/config/sg/sg_internal_users.yml b/src/main/docker/elasticsearch/config/sg/sg_internal_users.yml
new file mode 100644
index 0000000..1712d37
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/sg_internal_users.yml
@@ -0,0 +1,45 @@
+# This is the internal user database
+# The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh
+
+#password is: admin
+admin:
+  readonly: true
+  hash: $2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG
+  roles:
+    - admin
+  attributes:
+    #no dots allowed in attribute names
+    attribute1: value1
+    attribute2: value2
+    attribute3: value3
+
+#password is: logstash
+logstash:
+  hash: $2a$12$u1ShR4l4uBS3Uv59Pa2y5.1uQuZBrZtmNfqB3iM/.jL0XoV9sghS2
+  roles:
+    - logstash
+
+#password is: kibanaserver  
+kibanaserver:
+  readonly: true
+  hash: $2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H.
+
+#password is: kibanaro
+kibanaro:  
+  hash: $2a$12$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC
+  roles:
+    - kibanauser
+    - readall
+
+#password is: readall
+readall:
+  hash: $2a$12$ae4ycwzwvLtZxwZ82RmiEunBbIPiAmGZduBAjKN0TXdwQFtCwARz2
+  #password is: readall
+  roles:
+    - readall
+
+#password is: snapshotrestore
+snapshotrestore:
+  hash: $2y$12$DpwmetHKwgYnorbgdvORCenv4NAK8cPUg8AI6pxLCuWf/ALc0.v7W
+  roles:
+    - snapshotrestore
\ No newline at end of file
diff --git a/src/main/docker/elasticsearch/config/sg/sg_roles.yml b/src/main/docker/elasticsearch/config/sg/sg_roles.yml
new file mode 100644
index 0000000..6902fba
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/sg_roles.yml
@@ -0,0 +1,304 @@
+#<sg_role_name>:
+#  cluster:
+#    - '<permission>'
+#  indices:
+#    '<indexname or alias>':
+#      '<type>':  
+#        - '<permission>'
+#      _dls_: '<dls query>'
+#      _fls_:
+#        - '<field>'
+#        - '<field>'
+
+# When a user make a request to Elasticsearch then the following roles will be evaluated to see if the user has
+# permissions for the request. A request is always associated with an action and is executed against and index (or alias)
+# and a type. If a request is executed against all indices (or all types) then the asterix ('*') is needed.
+# Every role a user has will be examined if it allows the action against an index (or type). At least one role must match
+# for the request to be successful. If no role match then the request will be denied. Currently a match must happen within
+# one single role - that means that permissions can not span multiple roles. 
+
+# For <permission>, <indexname or alias> and <type> simple wildcards and regular expressions are possible. 
+# A asterix (*) will match any character sequence (or an empty sequence)
+# A question mark (?) will match any single character (but NOT empty character)
+# Example: '*my*index' will match 'my_first_index' as well as 'myindex' but not 'myindex1'
+# Example: '?kibana' will match '.kibana' but not 'kibana'
+
+# To use a full blown regex you have to pre- and apend a '/' to use regex instead of simple wildcards
+# '/<java regex>/'
+# Example: '/\S*/' will match any non whitespace characters
+
+# Important: 
+# Index, alias or type names can not contain dots (.) in the <indexname or alias> or <type> expression.
+# Reason is that we currently parse the config file into a elasticsearch settings object which cannot cope with dots in keys.
+# Workaround: Just configure something like '?kibana' instead of '.kibana' or 'my?index' instead of 'my.index'
+# This limitation will likely removed with Search Guard 6
+
+# DLS (Document level security) - NOT FREE FOR COMMERCIAL
+# http://docs.search-guard.com/v6/document-level-security
+
+# FLS (Field level security) - NOT FREE FOR COMMERCIAL
+# http://docs.search-guard.com/v6/field-level-security
+
+# Kibana multitenancy - NOT FREE FOR COMMERCIAL
+# http://docs.search-guard.com/v6/kibana-multi-tenancy
+
+# Allows everything, but no changes to searchguard configuration index
+sg_all_access:
+  readonly: true
+  cluster:
+    - UNLIMITED
+  indices:
+    '*':
+      '*':
+        - UNLIMITED
+  tenants:
+    admin_tenant: RW
+
+# Read all, but no write permissions
+sg_readall:
+  readonly: true
+  cluster:
+    - CLUSTER_COMPOSITE_OPS_RO
+  indices:
+    '*':
+      '*':
+        - READ
+
+# Read all and monitor, but no write permissions 
+sg_readall_and_monitor:
+  cluster:
+    - CLUSTER_MONITOR
+    - CLUSTER_COMPOSITE_OPS_RO
+  indices:
+    '*':
+      '*':
+        - READ
+
+# For users which use kibana, access to indices must be granted separately
+sg_kibana_user:
+  readonly: true
+  cluster:
+    - INDICES_MONITOR
+    - CLUSTER_COMPOSITE_OPS
+  indices:
+    '?kibana':
+      '*':
+        - MANAGE
+        - INDEX
+        - READ
+        - DELETE
+    '?kibana-6':
+      '*':
+        - MANAGE
+        - INDEX
+        - READ
+        - DELETE
+    '?kibana_*':
+      '*':
+        - MANAGE
+        - INDEX
+        - READ
+        - DELETE
+    '?tasks':
+      '*':
+        - INDICES_ALL
+    '?management-beats':
+      '*':
+        - INDICES_ALL        
+    '*':
+      '*':
+        - indices:data/read/field_caps*
+        - indices:data/read/xpack/rollup*
+        - indices:admin/mappings/get*
+        - indices:admin/get
+
+# For the kibana server
+sg_kibana_server:
+  readonly: true
+  cluster:
+      - CLUSTER_MONITOR
+      - CLUSTER_COMPOSITE_OPS
+      - cluster:admin/xpack/monitoring*
+      - indices:admin/template*
+      - indices:data/read/scroll*
+  indices:
+    '?kibana':
+      '*':
+        - INDICES_ALL
+    '?kibana-6':
+      '*':
+        - INDICES_ALL
+    '?kibana_*':
+      '*':
+        - INDICES_ALL
+    '?reporting*':
+      '*':
+        - INDICES_ALL
+    '?monitoring*':
+      '*':
+        - INDICES_ALL
+    '?tasks':
+      '*':
+        - INDICES_ALL
+    '?management-beats*':
+      '*':
+        - INDICES_ALL
+    '*':
+      '*':
+        - "indices:admin/aliases*"
+
+# For logstash and beats
+sg_logstash:  
+  cluster:
+    - ES_INPUT
+    - CLUSTER_MONITOR
+    - CLUSTER_COMPOSITE_OPS
+    - indices:admin/template/get
+    - indices:admin/template/put
+  indices:
+    'logstash-*':
+      '*':
+        - INDEX_OWNER
+    '*beat*':
+      '*':
+        - INDEX_OWNER
+    'dmaap*':
+      '*':
+        - INDEX_OWNER
+    'events*':
+      '*':
+        - INDEX_OWNER
+    'errors*':
+      '*':
+        - INDEX_OWNER
+
+# Allows adding and modifying repositories and creating and restoring snapshots
+sg_manage_snapshots:
+  cluster:
+    - MANAGE_SNAPSHOTS
+  indices:
+    '*':
+      '*':
+        - "indices:data/write/index"
+        - "indices:admin/create"
+
+# Allows each user to access own named index
+sg_own_index:
+  cluster:
+    - CLUSTER_COMPOSITE_OPS
+  indices:
+    '${user_name}':
+      '*':
+        - INDICES_ALL
+
+### X-Pack COMPATIBILITY
+sg_xp_monitoring:
+  readonly: true
+  cluster:
+    - cluster:monitor/xpack/info
+    - cluster:monitor/main
+    - cluster:admin/xpack/monitoring/bulk
+  indices:
+    '?monitor*':
+      '*':
+        - INDICES_ALL
+
+sg_xp_alerting:
+  readonly: true
+  cluster:
+    - indices:data/read/scroll
+    - cluster:admin/xpack/watcher*
+    - cluster:monitor/xpack/watcher*
+  indices:
+    '?watches*':
+      '*':
+        - INDICES_ALL
+    '?watcher-history-*':
+      '*':
+        - INDICES_ALL
+    '?triggered_watches':
+      '*':
+        - INDICES_ALL
+    '*':
+      '*':
+        - READ
+        - indices:admin/aliases/get
+
+sg_xp_machine_learning:
+  readonly: true
+  cluster:
+    - cluster:admin/persistent*
+    - cluster:internal/xpack/ml*
+    - indices:data/read/scroll*
+    - cluster:admin/xpack/ml*
+    - cluster:monitor/xpack/ml*
+  indices:
+    '*':
+      '*':
+        - READ
+        - indices:admin/get*
+    '?ml-*':
+      '*':
+        - "*"
+
+
+### LEGACY ROLES, FOR COMPATIBILITY ONLY
+### WILL BE REMOVED IN SG7, DO NOT USE ANYMORE
+
+sg_readonly_and_monitor:
+  cluster:
+    - CLUSTER_MONITOR
+    - CLUSTER_COMPOSITE_OPS_RO
+  indices:
+    '*':
+      '*':
+        - READ
+
+# Make xpack monitoring work
+sg_monitor:
+  cluster:
+    - cluster:admin/xpack/monitoring/*
+    - cluster:admin/ingest/pipeline/put       
+    - cluster:admin/ingest/pipeline/get
+    - indices:admin/template/get
+    - indices:admin/template/put
+    - CLUSTER_MONITOR
+    - CLUSTER_COMPOSITE_OPS
+  indices:
+    '?monitor*':
+      '*':
+        - INDICES_ALL
+    '?marvel*':
+      '*':
+        - INDICES_ALL
+    '?kibana*':
+      '*':
+        - READ
+    '*':
+      '*':
+        - indices:data/read/field_caps
+
+# Make xpack alerting work
+sg_alerting:
+  cluster:
+    - indices:data/read/scroll
+    - cluster:admin/xpack/watcher/watch/put
+    - cluster:admin/xpack/watcher*
+    - CLUSTER_MONITOR
+    - CLUSTER_COMPOSITE_OPS
+  indices:
+    '?kibana*':
+      '*':
+        - READ
+    '?watches*':
+      '*':
+        - INDICES_ALL
+    '?watcher-history-*':
+      '*':
+        - INDICES_ALL
+    '?triggered_watches':
+      '*':
+        - INDICES_ALL
+    '*':
+      '*':
+        - READ
diff --git a/src/main/docker/elasticsearch/config/sg/sg_roles_mapping.yml b/src/main/docker/elasticsearch/config/sg/sg_roles_mapping.yml
new file mode 100644
index 0000000..45bb775
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/sg_roles_mapping.yml
@@ -0,0 +1,34 @@
+# In this file users, backendroles and hosts can be mapped to Search Guard roles.
+# Permissions for Search Guard roles are configured in sg_roles.yml
+
+sg_all_access:
+  readonly: true
+  backendroles:
+    - admin
+
+sg_logstash:
+  backendroles:
+    - logstash
+    
+sg_kibana_server:
+  readonly: true
+  users:
+    - kibanaserver
+    
+sg_kibana_user:
+  backendroles:
+    - kibanauser
+
+sg_readall:
+  readonly: true
+  backendroles:
+    - readall
+
+sg_manage_snapshots:
+  readonly: true
+  backendroles:
+    - snapshotrestore
+
+sg_own_index:
+  users:
+    - '*'
\ No newline at end of file
diff --git a/src/main/docker/elasticsearch/config/sg/truststore.jks b/src/main/docker/elasticsearch/config/sg/truststore.jks
new file mode 100644
index 0000000..7a1b59a
--- /dev/null
+++ b/src/main/docker/elasticsearch/config/sg/truststore.jks
Binary files differ
diff --git a/src/main/docker/elasticsearch/my-entrypoint.sh b/src/main/docker/elasticsearch/my-entrypoint.sh
new file mode 100644
index 0000000..9eee64e
--- /dev/null
+++ b/src/main/docker/elasticsearch/my-entrypoint.sh
@@ -0,0 +1,8 @@
+source init_sg.sh
+
+while [ $? -ne 0 ]; do
+   sleep 10
+   source init_sg.sh
+done &
+
+/bin/bash -c "source /usr/local/bin/docker-entrypoint.sh;"
diff --git a/src/main/docker/kibana/conf/kibana.yml b/src/main/docker/kibana/conf/kibana.yml
index 0c4eda9..2edcb80 100644
--- a/src/main/docker/kibana/conf/kibana.yml
+++ b/src/main/docker/kibana/conf/kibana.yml
@@ -6,4 +6,12 @@
 elasticsearch.hosts: http://elasticsearch:9200
 server.ssl.enabled: true
 server.ssl.key: /usr/share/kibana/config/keystore/org.onap.clamp.key.pem
-server.ssl.certificate: /usr/share/kibana/config/keystore/org.onap.clamp.crt.pem
\ No newline at end of file
+server.ssl.certificate: /usr/share/kibana/config/keystore/org.onap.clamp.crt.pem
+
+## Search Guard
+#
+xpack.security.enabled: false
+elasticsearch.username: kibanaserver
+elasticsearch.password: kibanaserver
+
+searchguard.cookie.password: 123567818187654rwrwfsfshdhdhtegdhfzftdhncn
\ No newline at end of file
diff --git a/src/main/docker/logstash/pipeline/logstash.conf b/src/main/docker/logstash/pipeline/logstash.conf
index 6fe9d96..5c1d47d 100644
--- a/src/main/docker/logstash/pipeline/logstash.conf
+++ b/src/main/docker/logstash/pipeline/logstash.conf
@@ -238,6 +238,8 @@
         elasticsearch {
             codec => "json"
             hosts => ["${elasticsearch_base_url}"]
+            user => "${LOGSTASH_USR}"
+            password => "${LOGSTASH_PWD}"
             index => "errors-%{+YYYY.MM.DD}"
             doc_as_upsert => true
         }
@@ -246,6 +248,8 @@
         elasticsearch {
             codec => "json"
             hosts => ["${elasticsearch_base_url}"]
+            user => "${LOGSTASH_USR}"
+            password => "${LOGSTASH_PWD}"
             document_id => "%{requestID}"
             index => "events-cl-%{+YYYY.MM.DD}" # creates daily indexes for control loop
             doc_as_upsert => true
@@ -256,6 +260,8 @@
         elasticsearch {
             codec => "json"
             hosts => ["${elasticsearch_base_url}"]
+            user => "${LOGSTASH_USR}"
+            password => "${LOGSTASH_PWD}"
             index => "events-raw-%{+YYYY.MM.DD}" # creates daily indexes
             doc_as_upsert => true
         }