{"id":15056863,"url":"https://github.com/instaclustr/cassandra-ldap","last_synced_at":"2025-04-10T04:55:32.629Z","repository":{"id":34768279,"uuid":"135666024","full_name":"instaclustr/cassandra-ldap","owner":"instaclustr","description":"LDAP Authenticator for Apache Cassandra","archived":false,"fork":false,"pushed_at":"2024-09-09T09:04:52.000Z","size":333,"stargazers_count":24,"open_issues_count":21,"forks_count":17,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-10-19T23:51:17.732Z","etag":null,"topics":["apache-cassandra","auth","authentication","authenticator","cassandra","cassandra-ldap","ldap","ldap-authentication","ldap-server","netapp-public"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/instaclustr.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-01T04:06:42.000Z","updated_at":"2024-09-09T09:03:19.000Z","dependencies_parsed_at":"2024-01-30T17:30:01.264Z","dependency_job_id":"479c0802-60b6-4bf6-9d33-4f23c75d96f8","html_url":"https://github.com/instaclustr/cassandra-ldap","commit_stats":{"total_commits":66,"total_committers":8,"mean_commits":8.25,"dds":"0.33333333333333337","last_synced_commit":"2d4e74ad92c68b7f732ec8374d5df7e61c15cb0e"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instaclustr%2Fcassandra-ldap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instaclustr%2Fcassandra-ldap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instaclustr%2Fcassandra-ldap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instaclustr%2Fcassandra-ldap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/instaclustr","download_url":"https://codeload.github.com/instaclustr/cassandra-ldap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161256,"owners_count":21057554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-cassandra","auth","authentication","authenticator","cassandra","cassandra-ldap","ldap","ldap-authentication","ldap-server","netapp-public"],"created_at":"2024-09-24T21:57:15.198Z","updated_at":"2025-04-10T04:55:32.602Z","avatar_url":"https://github.com/instaclustr.png","language":"Java","funding_links":[],"categories":["General"],"sub_categories":["Cassandra Security"],"readme":"# Instaclustr LDAP Authenticator\n\n_LDAP Authenticator for Apache Cassandra_\n\nimage:https://circleci.com/gh/instaclustr/cassandra-ldap.svg?style=svg[\"Instaclustr\",link=\"https://circleci.com/gh/instaclustr/cassandra-ldap\"]\n\n- Website: https://www.instaclustr.com/\n- Documentation: https://www.instaclustr.com/support/documentation/\n\nThis is a pluggable authentication implementation for Apache Cassandra, providing a way to authenticate\nand create users based on a configured LDAP server. This implementation provides authentication only.\nRole management must be performed through the usual Cassandra role management— CassandraAuthorizer.\nSee **How it works** for more details.\n\n## Deprecation note\n\nBy releasing of Cassandra 5.0, the Cassandra team has stopped to actively develop / support Cassandra versions\n3.0 and 3.11. We keep the source code of respective 3.0 and 3.11 modules in the repository, but they are\ncommented out from main `pom.xml` as they require Java 8 but Cassandra 5.0 requires Java 11 and the testing framework we use for running embedded Cassandra can not deal with Java 11 while testing Cassandra 3.x even we set source and target for Maven to 1.8. If you want to build 3.x modules, please be sure you run Java 8 and you build only the respective module you want.\n\n## Project Structure and Building\n\nThis project consists of 5 modules; the `base` module is the module on which all other implementation modules\ndepend. It contains core implementation which is necessary as all concrete modules are reusing it.\n\nThe `base` module depends on Cassandra dependency—version 3.0.18 but its scope is `provided` as\nthese classes will be present when such plugin as a whole is put on a class path of Cassandra in runtime.\n\nThere are five implementation modules:\n\n* cassandra-2.2 - builds against version 2.2.19\n* cassandra-3.0 - builds against version 3.0.31\n* cassandra-3.11 - builds against version 3.11.18\n* cassandra-4.0 - builds against version 4.0.16\n* cassandra-4.1 - builds aganist version 4.1.8\n* cassandra-5.0 - builds aganist version 5.0.3\n\nProject is built as:\n\n```\n$ mvn clean install\n```\n\nThis does _not_ invoke integration tests. For integration tests to run, please specify `it` profile:\n\n```\n$ mvn clean install -Pit\n```\n\nIntegration tests will expect a Docker installation to be present (or a way to connect to one). There\nis a Docker container started with the LDAP server running against which an integration test, per module,\nis started.\n\n## Configuration of Plugins\n\nAfter build, the respective JAR to place to Cassandra `CLASSPATH` (e.g. by placing it to `libs` directory\nof Cassandra installation) is located in the `target` directory of each build as `casandra-ldap-{c* version}.jar`.\nThis JAR already contains artifacts from `base` so you do not need to take care of it-one JAR is enough.\nYou may at most probably use a plugin built against a respective version for other Cassandra\nversions of the same minor release, so you might use 3.11.8 plugin for 3.11.4, for example.\n\nThe configuration is ridden by a configuration file and system properties which you need to start Cassandra with\nto point that plugin to a configuration file to read properties from.\n\nThe system property is `-Dcassandra.ldap.properties.file=/path/to/configiration.properties`. If\nnot set, it will try to resolve `$CASSANDRA_CONF/ldap.properties`.\n\nThe content of the configuration file is as follows:\n\n\n|===\n|property name |explanation\n\n|ldap_uri\n|Ldap server URI. Specify ldaps when using a secure LDAP port (strongly recommended), example: `ldap://127.0.0.1:389/dc=example,dc=org`\n\n|context_factory\n|defaults to `com.sun.jndi.ldap.LdapCtxFactory`\n\n|service_dn\n|Service user distinguished name. This user will be a SUPERUSER and be used for looking up user details on authentication, example: `cn=admin,dc=example,dc=org`\n\n|service_password\n|Service user password\n\n|filter_template\n|template for searching in LDAP, explanation further in this readme, defaults to `(cn=%s)`\n\n|auth_cache_enabled\n|relevant for Cassandra 3.11 and 4.0 plugins, defaults to `false`\n\n|consistency_for_role\n|consistency level to use for retrieval of a role to check if it can log in - defaults to LOCAL_ONE\n\n|auth_bcrypt_gensalt_log2_rounds\n|number of rounds to hash passwords\n\n|load_ldap_service\n|defaults to false, if it is true, SPI mechanism will look on class path to load custom implementation of `LDAPUserRetriever`.\n\n|default_role_membership\n|A role to add new LDAP users to by default. Defaults to empty (users will not be added to any role).\n\n|cassandra_ldap_admin_user\n|name of a user/role which will be considered a default superuser, instead of `cassandra`. Please consult \"How it Works\" section to know more about the usage.\n\n|allow_empty_password\n|allow or disallow empty passwords when trying to connect to ldap server to prevent insecure behavior, defaults to `true`\n|===\n\n\n## Configuration of Cassandra\n\nIf is *strongly* recommended to use `NetworkTopologyStrategy` for your `system_auth keyspace`.\n\nPlease be sure that `system_auth` keyspace uses `NetworkTopologyStrategy` with number of replicas equal to number of nodes in DC. If it is not\nthe case, you can alter your keyspace as follows:\n\n    ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': '3'}  AND durable_writes = true;\n\nAfter this, repair `system_auth` keyspace so it all propagates to other nodes.\n\nYou need to restart your cluster in a rolling fashion. For each node, you need to add one of these configurations\ninto `cassandra.yaml` for each node:\n\n### Cassandra 2.2\n\n```\nauthenticator: Cassandra22LDAPAuthenticator\nrole_manager: LDAPCassandraRoleManager\nauthorizer: CassandraAuthorizer\n```\n\n### Cassandra 3.0\n\n```\nauthenticator: Cassandra30LDAPAuthenticator\nrole_manager: LDAPCassandraRoleManager\nauthorizer: CassandraAuthorizer\n```\n\n### Cassandra 3.11 - 4.x\n\n```\nauthenticator: LDAPAuthenticator\nauthorizer: CassandraAuthorizer\nrole_manager: LDAPCassandraRoleManager\n```\n\nFor 3.11 and 4, configure credential caching parameters in `cassandra.yaml` if necessary and if you want\nthat cache to be enabled (as per configuration parameters). [Re]start Cassandra.\n\n## Example\n\nFor fast testing there is Debian OpenLDAP Docker container\n\n    docker run -e LDAP_ADMIN_PASSWORD=admin --rm -d -p 389:389 --name ldap1 osixia/openldap\n\nThe `ldap.configuration` file in the `conf` directory does not need to be changed, and with the above `docker run` it will work out of the box. You just\nhave to put it in `$CASSANDRA_CONF` or set respective configuration property as described above.\n\n## Explanation of filter_template property\n\n`filter_template` property is by default `(cn=%s)` where `%s` will be replaced by name you want to log in with.\nFor example if you do `cqlsh -u myuserinldap`, a search filter for LDAP will be `(cn=myuserinldap)`. You\nmay have a different search filter based on your need, a lot of people use e.g. SAM or something similar.\nIf you try to log in with `cqlsh -u cn=myuserinldap`, there will be no replacement done and this will be\nused as a search filter instead.\n\n## How it Works\n\nLDAPAuthenticator currently supports plain text authorization requests only in the form of a username and password.\nThis request is made to the LDAP server over plain text, so you should be using client encryption on the Cassandra\nside and secure ldap (ldaps) on the LDAP side.\n\nCredentials are sent from your client to the Cassandra server and then tested against the LDAP server for\nauthentication using a specified service account. This service account should be configured in the `ldap.properties`\nfile using the `service_dn` and `service_password` properties. If `service_dn` is set, such a role will be created in database,\nwhen not already present, upon node's start.\n\n`service_dn` account, which will be automatically created, will be superuser in Cassandra.\n\nAll \"normal\" roles are not affected - they behave exactly as you are used to.\n\nIf the LDAP server connection is lost or there is another communication error while talking to LDAP server,\nthe operator still has a possibility of logging in via `cassandra` user as usual, and until the LDAP server is not back again;\nUsers meant to be authenticated against the LDAP server will not be able to log in but all \"normal\" users will be able to\nlog in and the disruption of LDAP communication will not affect their ability to do so as they live in Cassandra natively.\n\nIn case a user specifies just `test` as login name (or any other name, for that matter), it will try to\nauthenticate against database first and if not successful against LDAP using filter `filter_template` which defaults to `(cn=%s)`\n\nIt is possible to delete administration role (e.g. role `cassandra`) but if one does that, all administration operations are only able to\nbe done via LDAP account. In case LDAP is down, the operator would not have any control over DB as `cassandra` is not present anymore.\nIn such case, it is recommended to create another admin-like user with a strong password _before_ the `cassandra` role is deleted. A plugin is internally creating new roles\nwhen somebody from LDAP logs in and it is not in DB yet. For this functionality, there needs to be some admin-like user which writes them `system_auth.roles` table.\nIf you delete `cassandra` user, there is suddenly not such user. You have to restart node and specify this property:\n\n    -Dcassandra.ldap.admin.user=dba\n\nWhere `dba` is _new_ superuser which is able to write to `system_auth.roles` and acts as Cassandra admin.\n\nUpon login via LDAP user, this plugin will create a dummy role just to be able to play as a normal Cassandra role\nwith all its permissions and so on. Passwords for LDAP users are not stored in Cassandra, obviously.\n\nCredentials are cached for implementations for Cassandra 3.11 and 4.0 so that way we are not hitting LDAP server\nall the time when there is a lot of login attempts with same login name. An administrator can increase\nrelevant validity settings in `cassandra.yaml` to increase these periods even more.\n\n## SPI for LDAP server implementations (advanced)\n\nIn order to talk to a LDAP server, there is `DefaultLDAPServer` class in `base` module which all modules are using.\nHowever, it might not be enough - there is a lot of LDAP servers out there and their internals and configuration\nmight render the default implementation incompatible. If you have special requirements, you might provide your\nown implementation by implementing `LDAPUserRetriever`. You have to have `load_ldap_service` set to `true` as well.\n\nTo tell LDAP plugin to use your implementation, you need to create a file in `src/main/resources/META-INF/services`\ncalled `LDAPUserRetriever` and the content of that file needs to\nbe just one line - the fully qualified class name (with package) of your custom implementation.\n\nAfter you build such plugin, the SPI mechanism upon plugin's initialisation during Cassandra node startup\nwill pick up your custom LDAP server connection / authentication logic.\n\n## Default Role Membership\n\nIt is possible to automatically add new LDAP users to an existing Cassandra role when they are created by setting the\n`default_role_membership` configuration option. When this is set, any LDAP users logging in to Cassandra for the first\ntime will be added to the role specified. Users who already exist in Cassandra will not be added to the group. If the\ndefault role specified does not exist, the role will not be created and new users will not receive the default membership.\nOnly one role can be specified.\n\n## Further Information\n- See blog by Stefan Miklosovic about https://www.instaclustr.com/the-instaclustr-ldap-plugin-for-cassandra/[Apache Cassandra LDAP Authentication]\n- Please see https://www.instaclustr.com/support/documentation/announcements/instaclustr-open-source-project-status/[Instaclustr support status] of this project\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstaclustr%2Fcassandra-ldap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finstaclustr%2Fcassandra-ldap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstaclustr%2Fcassandra-ldap/lists"}