Security Configuration¶
Lenses allows you to easily secure access to the Lenses API and UI. You can password protect the UI and API as well as allow service accounts. More advanced features include LDAP and Kerberos authentication, role and group based access control, topic whitelisting/blacklisting. This section describes how to configure the security setup.
Lenses security options start with lenses.security.***
and should be stored
in a separate file, named security.conf
. You can set the path to the
security configuration file in the main configuration file lenses.conf
via
the key lenses.secret.file
. This way security.conf
can be managed only
by the administration team and have more tight access control than the rest of
the configuration.
Lenses has support for the following login modes: BASIC
, LDAP
and
KERBEROS
. The security mode is configured through the
lenses.security.mode
option. The permission matrix
contains additional details on roles and access levels.
BASIC¶
If BASIC
mode is set, then user accounts and groups are stored in the
configuration file itself. Users are assigned one or more groups and this
determines which roles they are granted. Users and groups are set via the
lenses.security.users
and lenses.security.groups
options respectively.
For example:
# Security by default to is set to BASIC, alternatively LDAP.
lenses.security.mode=BASIC
# Define the user groups and their roles. At least one user group needs to be set
lenses.security.groups=[
{"name": "adminGroup", "roles": ["admin", "write", "read"]},
{"name": "writeGroup", "roles": ["read", "write"], topic: { blacklist: ["payment.*"] },
{"name": "readGroup", "roles": ["read"], topic: { whitelist: [ "users.*" ] },
{"name": "nodataGroup", "roles": ["nodata"]}
]
#Define the users and link each one to the group(-s) it belongs
lenses.security.users=[
{"username": "admin", "password": "admin999", "displayname": "Lenses Admin", "groups": ["adminGroup"]},
{"username": "write", "password": "write1", "displayname": "Write User", "groups": ["writeGroup"]},
{"username": "read", "password": "read1", "displayname": "Read Only", "groups": ["readGroup"]},
{"username": "nodata", "password": "nodata1", "displayname": "No Data", "groups": ["nodataGroup"]}
]
The admin
role inherits automatically the read
and write
privileges. The write
role inherits read
privilege.
Security modes require lenses.security.groups
to be specified. In addition
to specifying the roles for each group, you can optionally specify which topics
can be accessed through a whitelist/blacklist approach. In the example
above, the writeGroup will get to access all topics apart from the ones
starting with payment. The readGroup has been set using the whitelisting
approach, and will only allow access to topics with names starting with
users. The entries for the topic.whitelist and topic.blacklist are
expected to be regular expressions.
The permission matrix contains additional details on roles and access levels.
Note
Lenses offers topic centric security; you can control which topics a user group can access. A simple white/black list configuration enables you to handle multi-tenancy over Kafka. Leaving out the setting means the group will be able to access all topics.
LDAP¶
It is common for enterprises to use an LDAP server for user management and Lenses can integrate with your LDAP environment for user authentication and group assignment.
If you want to use LDAP support then the lenses.security.mode
option must be
set to LDAP
and the ldap
configuration section must be completed to
provide the settings.
Each individual LDAP setup will assign membership to groups using a different hierarchy, therefore there is a plugin to allow custom implementations for retrieving the user group list.
The project template for a custom implementation can be found on Github. With the
implementation ready, all that is required is to drop the jar file into Lenses
lib
folder and set the configuration entry lenses.security.ldap.plugin
to point to the implementation full classpath.
Lenses provides out-of-the-box a default implementation via
com.landoop.lenses.security.ldap.LdapMemberOfUserGroupPlugin
class. Here is the
template for the LDAP configuration section:
lenses.security.mode=LDAP
lenses.security.ldap.url="ldaps://mycompany.com:636"
lenses.security.ldap.base="OU=Users,DC=mycompany,DC=com"
lenses.security.ldap.user="$LDAP_USER"
lenses.security.ldap.password="$LDAP_USER_PASSWORD"
lenses.security.ldap.filter="(&(objectClass=person)(sAMAccountName=<user>))"
//LDAP roles retriever settings
lenses.security.ldap.plugin.class="com.landoop.lenses.security.ldap.LdapMemberOfUserGroupPlugin"
lenses.security.ldap.plugin.group.extract.regex="(?i)CN=(\\w+),ou=ServiceGroups.*"
lenses.security.ldap.plugin.memberof.key="memberOf"
lenses.security.ldap.plugin.person.name.key = "sn"
Key | Description | Optional | Type | Default |
---|---|---|---|---|
url | The LDAP server url.
For example:
ldap://mycompany.com:10389 |
No | String | N/A |
base | Your LDAP base.
For example:
dc=jboss,dc=org |
No | String | N/A |
user | Your LDAP user.
For example:
uid=admin,ou=system |
No | String | N/A |
password | Your LDAP user password. | No | String | N/A |
filter | The LDAP search filter - must result in
a unique result. See default value.
<user> is required since is replaced
at runtime with the current
user id.
|
Yes | String | (&(objectClass=person)(sAMAccountName=<user>)) |
plugin.class | Contains the full classpath for
the LDAP roles retriever implementation
|
Yes | string | N/A |
plugin.memberof.key | Your LDAP member of key entry.
This is the key for which a
role is attached to the user entry.
For example,
memberOf: cn=AdminR,ou=Groups,dc=jboss,dc=org - links the AdminR role to the
current user entry.
|
Yes | String | memberOf |
plugin.person.name.key | Your LDAP person entry attribute
containing the user full name.
The default value if the configuration is
not provided is
sn . |
yes | string | sn |
plugin.group.extract.regex | The regular expression syntax to extra
the role for each
memberof entry.The default value matches the
earlier example for
memberof . |
Yes | String | (?i)CN=(\\w+),ou=Groups.* |
Note
The configuration entries lenses.security.ldap.plugin.memberof.key
,
lenses.security.ldap.plugin.person.name.key
and
lenses.security.ldap.plugin.group.extract.regex
are specific to the
implementation Lenses provides out of the box. Any custom implementation
may require different entries under lenses.security.ldap.plugin
Here is a sample configuration LDAP enabled Lenses:
lenses.security.mode=LDAP
lenses.security.ldap.url="ldaps://landoop.ldap.url:636"
lenses.security.ldap.base="DC=landoop,DC=com"
lenses.security.ldap.password=*****
lenses.security.ldap.user="UID=smiths,OU=Services,DC=landoop,DC=com"
lenses.security.ldap.filter="(&((objectclass=person)(CN=<user>)))"
lenses.security.ldap.plugin.class="com.landoop.lenses.security.ldap.LdapMemberOfUserGroupPlugin"
lenses.security.ldap.plugin.memberof.key="memberOf"
lenses.security.ldap.plugin.group.extract.regex="(?i)CN=(\\w+),ou=ServiceGroups.*"
lenses.security.ldap.plugin.person.name.key ="sn"
Kerberos¶
A popular solution for single sign on is Kerberos, which is often used in corporate environments. Clients obtain tickets from the Kerberos Key Distribution Centre (KDC) for a particular service and then that ticket is sent to the service when the client needs to authenticate against it.
If you want to enable Kerberos support then the lenses.security.mode
option
must be set to KERBEROS
and the kerberos
configuration section must be
completed to provide the specific kerberos settings. The following table
enumerates the kerberos config settings.
Key | Description | Optional | Type | Default |
---|---|---|---|---|
servicePrincipal | The Lenses service principal. For example, HTTP/hostname | No | String | N/A |
keytab | The path to the location of the service keytab | No | String | N/A |
debug | Set to true to output Java’s JAAS debugging information | Yes | Boolean | false |
Here is a sample configuration for Kerberos enabled Lenses:
lenses.security.mode=KERBEROS
lenses.security.kerberos.service.principal="HTTP/lenses.host"
lenses.security.kerberos.keytab=/tmp/lenses.keytab
lenses.security.kerberos.debug=true
One of the limitations of Kerberos is that it is purely an authentication system
for user principals without support for group membership. Therefore, in order to
combine authentication with authorization it is necessary to map users to groups
in a similar manner to the BASIC
mode.
This is simply a mapping from username to group(s) specified in the security config, as in the following example:
#Define the users and link each one to the group(-s) it belongs
lenses.security.mappings = [
{ "username": "sam@LANDOOP.COM", "groups": ["adminGroup", "userGroup"] },
{ "username": "tom@LANDOOP.COM", "groups": ["userGroup"] }
]
Once Kerberos is enabled you should be implicitly logged in whenever you visit
the lenses UI or directly to one of the REST API’s such as /api/auth
. If you
are using Kerberos on a windows system, then logging into your windows domain is
usually sufficient to issue your Kerberos credentials. On a Linux environment,
you will typically need to login manually using kinit at the command line
before visiting any Kerberos enabled service.
Service Accounts¶
Service accounts allow easier integration with Lenses API. A typical use case is
enabling your CI/CD tools to interact with Lenses. Via the
lenses.security.service.accounts
specific users and their authorization
token can be defined. Here is how two service accounts can be created:
lenses.security.groups=[
{"name": "group1", "roles": ["admin", "write", "read"]},
{"name": "group2", "roles": ["read", "write"], topic: { blacklist: ["payment.*"] },
{"name": "group3", "roles": ["read"], topic: { whitelist: [ "users.*" ] },
]
lenses.security.service.accounts=[
{
"username": "jenkins",
"token": "1231543kn!!1",
"groups": ["group1", "group2"]
},
{
"username": "goCli",
"token": "12345678",
"groups": ["group3"]
}
]
Your CI system (like Jenkins) and the Lenses Go CLI tool can call into the API
without having to first login. All that is required is for every HTTP request
to contain the HTTP header: X-Kafka-Lenses-Token:$TOKEN
.
Each service account is of course linked to a user group in order to restrict the actions it can execute.