Authentication¶
Whenever a client connects to GraphDB, a session is created. The session stores various contextual information about the connection. Each session is always associated with a single user. Authentication is the process of mapping this session to a specific user. Once the session is mapped to a user, a set of permissions can be associated with it, using authorization.
This diagram can be used as a quick reference for our security model:

GraphDB supports two authentication providers natively. In addition to this, it is possible to turn off GraphDB security completely and implement your own security layer instead.
Local¶
This is the default security access provider. Users stored inside the local database take precedence over LDAP users. For example, if both providers have a user called “leah”, the settings and roles for this user will be sourced from the local database.
The local database stores usernames, encrypted passwords, local user settings and remote LDAP user settings. Passwords are encrypted using the SHA-256 algorithm. When a user tries to access the database, they will be met with a security challenge. If they can provide a valid username/password combination, a JWT token will be generated.
The local database is located in the settings.js file under the GraphDB work - workbench directory. By default this is ${graphdb.home}/work/workbench. If you are worried about the security of this file, we recommend encrypting it (see Encryption at rest).
Note
JWT is serialized as “Authorization: GDB <token>” header in every request, so it is vulnerable to a man-in-the-middle attack. Everyone who intercepts the JWT can reuse the session. To prevent this, we recommend to always enable encryption in transit.
Tokens are valid for 30 days. Within this period, each communication between the client and the server will be carried out only after the token has been validated. If the token has expired or is not present, the users will be met with a security challenge.
Note
During the token validity period, if the password is changed the user would still have access to the server. However, if the user is removed the token would stop working.
Local authentication does not need to be configured.
LDAP¶
Lightweight Directory Access Protocol (LDAP) is a lightweight client-server protocol for accessing directory services implementing X.500 standards. All its records are organized around the LDAP Data Interchange Format (LDIF), which is represented in a standard plain text file format.
An optional identity provider. In the event that a given username/password combination cannot be validated by the local database, and a LDAP server has been configured, GraphDB security will attempt to fetch the user from the LDAP server.
Even with LDAP turned on, the local database is still used for storing user settings. This means that you can use the workbench or the GraphDB API to change them. All other administration operations need to be performed on the LDAP server side.
Unlike local authentication, LDAP needs to be configured in the graphdb.properties file, by passing the configuration details to the Java process or via the GDB_JAVA_OPTS
parameter.
Note
The order of precedence for GraphDB configuration properties is: config file < GDB_JAVA_OPTS < command line supplied arguments
.
LDAP is turned on by using the following setting:
graphdb.auth.module=ldap
When LDAP is turned on, the following security settings can be used to configure it:
Property | Values | Usage |
---|---|---|
graphdb.auth.ldap.url (required) | ldap://<my-openldap-server>
:389/<partition> |
LDAP endpoint |
graphdb.auth.ldap.user.search.base | <empty> | Query to identify the directory where all authenticated users are located. |
graphdb.auth.ldap.user.search.filter (required) | (cn={0}) | Matches the attribute to a GraphDB username. |
graphdb.auth.ldap.role.search.base | <empty> | Query to identify the directory where roles/groups for authenticated users are located |
graphdb.auth.ldap.role.search.filter (required) | (uniqueMember={0}) | Authorize a user by matching the manner in which they are listed within the group. |
graphdb.auth.ldap.role.search.attribute | cn (default) | The attribute to identify the common name |
graphdb.auth.ldap.role.map.administrator (required) | my-group-name | Map a single LDAP group to GDB administrator role |
graphdb.auth.ldap.role.map. repositoryManager | my-group-name | Map a single LDAP group to GDB repository manager role |
graphdb.auth.ldap.role.map.repository .read.<my-repo> | my-group-name | Map a single LDAP group to GDB repository-specific read permissions |
graphdb.auth.ldap.role.map.repository .write.<my-repo> | my-group-name | Map a single LDAP group to GDB repository-specific write permissions |
graphdb.auth.ldap.repository.read.base | Query to identify the directory where repository read groups for authenticated users are located | |
graphdb.auth.ldap.repository.read.filter | (uniqueMember={0}) | Authorize a user by matching the manner in which they are listed within the group |
graphdb.auth.ldap.repository.read. attribute | cn (default) | Specify the mapping of a GraphDB repository id to a LDAP attribute |
graphdb.auth.ldap.repository.write.base | Query to identify the directory where repository write groups for authenticated users are located. | |
graphdb.auth.ldap.repository.write.filter | (uniqueMember={0}) | Authorize a user by matching the manner in which they are listed within the group |
graphdb.auth.ldap.repository.write. attribute | cn (default) | Specify the mapping of a GraphDB repository id to a LDAP attribute |
Note
Configuration changes happen only after restart.
Here is an example configuration:
# Turn on ldap authentication and configure the server.
graphdb.auth.module = ldap
graphdb.auth.ldap.url = ldap://localhost:10389/dc=example,dc=org
# Permit access for all users that are part of the “people” unit of the fictional “example.org” organisation.
graphdb.auth.ldap.user.search.base = ou=people
graphdb.auth.ldap.user.search.filter = (cn={0})
# Make all users in the Administration group GraphDB administrators as well.
graphdb.auth.ldap.role.search.base = ou=groups
graphdb.auth.ldap.role.search.filter = (member={0})
graphdb.auth.ldap.role.map.administrator = Administration
# Make all users in the Management group GraphDB Repository Managers as well.
graphdb.auth.ldap.role.map.repositoryManager = Management
# Enable all users in the Readers group to read the my_repo repository.
graphdb.auth.ldap.role.map.repository.read.my_repo = Readers
# Enable all users in the Writers group to write and read the my_repo repository.
graphdb.auth.ldap.role.map.repository.write.my_repo = Writers
# All entries located under the "groups" organizational unit that have members (i.e., groups), will be able to read repositories that share their common name.
graphdb.auth.ldap.repository.read.base = ou=groups
graphdb.auth.ldap.repository.read.filter = (member={0})
graphdb.auth.ldap.repository.read.attribute = cn
# All entries located under the "groups" organizational unit that have members (i.e., groups), will be able to read and write to repositories that share their common name.
graphdb.auth.ldap.repository.write.base = ou=groups
graphdb.auth.ldap.repository.write.filter = (member={0})
graphdb.auth.ldap.repository.write.attribute = cn
Basic Authentication¶
Instead of using JWT, users can access GraphDB by passing valid base-64 encoded username/password combinations as a header, in the following fashion:
Authorization: Basic YWRtaW46cm9vdA==
Note
Basic Authentication is even more vulnerable to man-in-the-middle attacks than JWT! Anyone who intercepts your requests will be able to reuse your credentials indefinitely until you change them. Since the credentials are merely base-64 encoded, they will also get your username and password. This is why it is very important to always use encryption in transit.