All versions of this manual
X

 Linkurious administration manual

Welcome to the Linkurious Enterprise administrator documentation. This documentation will help you install, run and customize Linkurious Enterprise.

Architecture overview

Linkurious Enterprise is a three-tier application.

The presentation layer is a Web application. It uses our graph visualization library, Ogma, to allow rich interactions with the graph. It also provides a user interface to enable data administration and collaboration among end users.

The presentation layer communicates with the logic layer via a JSON-based REST API. Custom presentation layer application can be developed on top of the logic layer.

The logic layer is a NodeJS-based server. It provides a unified REST API to read, write and search into graph databases from multiple vendors (Neo4j and Cosmos DB). It implements also a security layer with modular authentication that enables role-based access control policies. It can be connected to multiple graph databases at the same time and offers high-level APIs for collaborative exploration of graphs: users can create, share and publish graph visualizations, and multiple users can edit graph data.

Administrators can control it from its REST API for easy automation and deployment.

Multiple external authentication providers are supported (LDAP, Microsoft Active Directory, Microsoft Azure Active Directory, Google Suite, OpenID Connect, SAML2 / ADFS).

The data layer supports several graph databases, as well as indexation engines.

 FAQ

Going to production

What should I do before going to production?

1. Ready your graph database for production

Consult with your vendor to make sure that your graph database is installed on appropriate hardware and configured for better performances:

Make sure that your graph database is secure:

2. Ready Elasticsearch for production

Keep in mind that Linkurious Enterprise can be used without Elasticsearch, see search options.

If you are using Linkurious Enterprise with Elasticsearch

3. Ready your user-data store for production

By default, SQLite is used for the user-data store. SQLite is not recommended for production environment: switch to MySQL/MariaDB/MSSQL instead.

Schedule regular backups of the user-data store:

Make sure your user-data-store database is secure

If you need high-availability, set up replication

4. Ready Linkurious Enterprise itself for production

How can Fault tolerance be achieved?

Linkurious Enterprise can be set up with a backup instance to allow for continuity of service when the main server crashes.

For this setup:

A reverse proxy is then configured to send requests to the backup server when the main server is down. If you are using nginx, this sample configuration can be used:

http {
    # define the "backend" upstream
    upstream backend {
        # main server
        server linkurious-main.example.com;

        # backup server
        server linkurious-backup.example.com backup;
    }

    # redirect all queries to the "backend" upsteam
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

See nginx documentation for more details.

Fault-tolerance diagram

Security

Where is the user-data store located?

The user-data store database (containing visualizations, saved queries, user, groups, etc) is stored in a SQL database.

By default, this database is an SQLite database (located at linkurious/data/database.sqlite). In production, the use of a MySQL/MariaDB/MSSQL database is recommended. These databases can be located on a remote server.

Is the user-data store encrypted?

The default user-data store (SQLite) is not encrypted.

Encryption is available with the following vendors:

Is it possible to delete the SQLite user-data store when using an external database?

Yes, when using an external user-data store (e.g. MariaDB, MySQL or MSSQL), the SQLite files can be deleted.

What kind of information is stored in the configuration file?

The configuration file contains all configurable options, as well as the configuration options of all configured data sources (e.g. User-Data Store host/port/username/encrypted password; Graph Database URL/username/encrypted password; Index Search URL/username/encrypted password, etc). All passwords/secrets in the configuration file are encrypted before storage.

The configuration file, like the rest of the data folder, should be considered private and not be readable by anyone other than the Linkurious Enterprise service account.

How are application secrets stored?

All application secrets stored by Linkurious Enterprise (Graph Database credentials, User-Data Store credentials, Index Search credentials, SSL certificate passphrase, etc.) are encrypted using the AES-256-CTR algorithm.

How are user credentials stored?

User passwords are strongly hashed before being stored in the database. Passwords for LDAP and other external authentication solutions are not stored at all.

Where is the audit trail stored?

The audit trail files are generated in linkurious/data/audit-trail by default. This path can be set in the audit trail configuration.

Does enabling the audit-trail require additional security measures?

The audit trail contains sensitive information and should be secured. It should be owned and readable only by the Linkurious Enterprise service account.

How can the data directory be secured?

The data directory contains logs, configuration files, and, if enabled, audit trails. This information is sensitive, and the directory should be owned and readable only by the Linkurious Enterprise service account

What is a service account and why should I use one?

A service account is an operating system user account with restricted privileges that is used only to run a specific service and own it data related to this service. Service accounts are not intended to be used by people, except for performing administrative operations. Access to service accounts is usually tightly controlled using privileged access management solutions.

Service accounts prevent other users and services from reading or writing to sensitive files in the directories that they own, and are themselves prevented from reading and writing to other parts of the file system where they are not owners.

Can Kerberos be used for single sign-on?

We do not support Kerberos as of now (but we support many other third-party authentication services).

What do the log files contain?

Linkurious Enterprise creates three types of logs:

How can the communication with an LDAP server be secured?

If your LDAP server supports secure LDAP, use the "ldaps://" protocol in your LDAP configuration.

How can Elasticsearch be secured?

If you need authentication and transport layer security for Elasticsearch:

Can I customize the cryptographic ciphers used for TLS?

To customize supported TLS ciphers, in the general configuration, set tlsCipherList in the server section. Here is an example, based on Mozilla's recommended cipher list:

{
  "tlsCipherList": "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!eNULL:!aNULL"
}

What should I do before updating Linkurious Enterprise to a new release?

We are trying to keep the Linkurious Enterprise update process as simple as possible. However, sometimes configuration can require specific manual activities.

Before you upgrade to a new version of Linkurious Enterprise, consider browsing our public resources to verify whether there are specific instructions that applies to your configuration or activities you are planning.

Miscellaneous

How can I troubleshoot TLS connectivity issues?

If you have issues configuring a secure connection, temporarily tweaking the TLS settings may help troubleshooting the issue.

TLS certificate validation can be disabled by setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0. Note this should only be done for troubleshooting purpose as it makes TLS inherently insecure.

Some useful Node options can also be set:

These settings can be set in the /data/manager/manager.json configuration file, in the env section of the Linkurious Server service. For instance, it may looks like this:

{
  "env": {
    "NODE_TLS_REJECT_UNAUTHORIZED": 0,
    "NODE_OPTIONS": "--max-old-space-size=4096 --trace-tls --openssl-legacy-provider --tls-cipher-list=DEFAULT@SECLEVEL=0"
  }
}

For Neo4j connections, certificate validation can be disabled by changing the URL scheme:

For Active Directory, TLS debug settings can be set directly in the Linkurious Enterprise configuration file, see Active Directory configuration.

What are PEM Certificates?

PEM (for Privacy-Enhanced Mail) is a file format for storing and sending cryptographic keys and certificates.

To verify if a certificate is PEM-encoded, open it with a text-editor, it should look something like this:

-----BEGIN CERTIFICATE-----
MIICLDCCAdKgAwIBAgIBADAKBggqhkjOPQQDAjB9MQswCQYDVQQGEwJCRTEPMA0G
A1UEChMGR251VExTMSUwIwYDVQQLExxHbnVUTFMgY2VydGlmaWNhdGUgYXV0aG9y
DwEB/wQFAwMHBgAwHQYDVR0OBBYEFPC0gf6YEr+1KLlkQAPLzB9mTigDMAoGCCqG
SM49BAMCA0gAMEUCIDGuwD1KPyG+hRf88MeyMQcqOFZD0TbVleF+UsAGQ4enAiEA
l4wOuDwKQa+upc8GftXE2C//4mKANBC6It01gUaTIpo=
-----END CERTIFICATE-----

If you have a DER-encoded certificate (binary), it can be converted to PEM:

Can I use Linkurious Enterprise without Elasticsearch?

Most graph vendors support search strategies other than Elasticsearch. See details on our search options page.

Can I use a custom tile server in geo-spatial mode?

Yes. See the geospatial configuration options for further details.

Can I use ESRI ArcGIS for geo-spatial mode?

Yes, you can configure ArcGIS as the tile-server for geo-spatial mode. The ArcGIS documentation describes the API endpoints that is compatible with Linkurious Enterprise:

For example:

What are the command lines utilities to administrate Linkurious Enterprise?

Will enabling the audit trail impact performance?

Depending on the configuration options specified, enabling the audit trail can have an impact on performance. See the audit trail documentation for details.

 Getting started: Version support policy

What is a version?

Linkurious Enterprise uses version codes with 3 numbers separated by dots (e.g. 2.9.14). The numbers are interpreted as MAJOR.MINOR.PATCH. For example, Linkurious Enterprise 2.9.11 is a patch version that is part of the Linkurious Enterprise 2.9 minor version, which is itself part of the Linkurious Enterprise 2 major version.

Version stability

When updating Linkurious Enterprise from one version to another (for any version in the “stable” or “maintenance” stage), the following is guaranteed:

Breaking change

A breaking change is a change that either removes a feature, or changes an existing feature in a way that makes adopting this change require either:

Examples:

Non-breaking improvement

A non-breaking improvement is a change that either adds a new feature, or extends the capacities of an existing features without removing any existing functional behavior.

Examples:

Stages of a minor version

A minor version of Linkurious Enterprise (e.g. 2.9) is always in one of the following stages:

Release frequency

Support duration

Example life-cycle

This is an example version life-cycle to illustrate how minor and patch version are released. release lifecycle example diagram

 Getting started: Release notes

Changelog for Linkurious Enterprise v4.0.27

Release Date: 2024-04-17

New Features & Improvements (138)

Bug Fixes (264)

Breaking changes (13)

 Getting started: Client requirements

Linkurious Enterprise Client

Technical requirements for users that access Linkurious Enterprise with their Web browser:

Hardware

Hardware requirements of the Linkurious Enterprise Web client vary with the size of the visualized graphs. For up to 500 nodes and edges in a single visualization, we recommend to use a machine with 8 GB RAM, and 2 CPU cores @ 1.6 Ghz.

Desktop browsers

End-users will access Linkurious Enterprise through a Web browser. The following browsers are officially supported:

Display and touch

 Getting started: Graph DB Feature Map

Features per graph database vendor

Feature \ Vendor Neo4j Amazon Neptune Memgraph Cosmos DB
Full-text search
Graph styles customization
Graph filtering
Graph editing
Access rights management
Custom graph queries
Custom query templates
Alerts
Shortest path analysis

Feature details

 Deploying on premise: Technical requirements

Linkurious Enterprise is a Web-application server. It needs to be installed on a server and can then be accessed by multiple users using their Web browser.

Linkurious Enterprise Server

Technical requirements for the machine used to install the Linkurious Enterprise Web-application server:

Hardware

Linkurious Enterprise hardware requirements change according to your needs and setup. Here are some scenarios with their suggested minimum hardware configurations.

Scenario 1

Project up to 20 users and few alerts.

Using the embedded Elasticsearch1:

Not using the embedded Elasticsearch:

Scenario 2

Project up to 100 users and tenth of alerts.

Using the embedded Elasticsearch1:

Not using the embedded Elasticsearch:

Scenario 3

Project with more than 100 users and several alerts.

To maintain stable performance, it is necessary to move heavily loaded components to well-dimensioned dedicated servers/clusters:

Hardware requirements only for the Linkurious Enterprise server:

Extra information:

Linkurious Enterprise requires a 64-bit system to run.

1The embedded Elasticsearch is not recommended when dealing with large amounts of data, see Elasticsearch documentation.

2Some extra space is required for the Elasticsearch full-text index. This space is proportional to the size of your graph database. A (very) rough estimate could be 50% of your graph database (it also depends on the actual data density).

3It is possible to configure Elasticsearch for higher memory usage, please contact us.

4It is possible to configure Linkurious Enterprise for higher memory usage more, please contact us.

Please keep in mind that these technical requirements are for Linkurious Enterprise server only. For hardware requirements regarding your graph database, please refer to these guides:

Elasticsearch

Linkurious Enterprise includes an embedded Elasticsearch instance for search capabilities. Please keep in mind that this embedded instance will only work for smaller graphs (less than 50M nodes + edges). For larger graphs, you will need to deploy an Elasticsearch cluster. Please refer to Elasticsearch's hardware requirements guide for details.

Operating System

Linkurious Enterprise server can be deployed on the following platforms:

Node.js and GLIBC 2.28

Linkurious Enterprise depends on Node.js that requires a Linux kernel >= 4.18 and a GLIBC >= 2.28.

You can check the Linux kernel and the GLIBC version available on your system on http://distrowatch.com.

 Deploying on premise: Downloading

Where to download from

The latest version of Linkurious Enterprise can be downloaded from https://get.linkurio.us/.

Log in with the username and password created during the purchase process and then go to the download section for the specific license (in case of multiple one), it will be possible to download the package for the correct platform.

Archive content

The ZIP file contains:

Staying up-to-date

Please see the Linkurious Enterprise version compatibility matrix and our documentation on how to update Linkurious Enterprise.

 Deploying on premise: Installing

Security considerations

To work properly, Linkurious Enterprise only need permissions (including write access) on the whole application directory, no administrative rights are needed.

The only exception may be related to Operating Systems' security policies preventing any standard user to bind applications on the first 1024 port numbers, see web server configuration to learn more on the issue and how prevent to grant administrative rights.

As best practice, it is advised to create a dedicated service account (e.g. linkurious) with the minimum level of permissions.

Linux systems

  1. Unzip Linkurious Enterprise archive: > unzip linkurious-linux-v4.0.27.zip
  2. Adjust securities to ensure access to the user executing the process
  3. Enter the Linkurious Enterprise folder: > cd linkurious-linux
  4. Check the configuration file at linkurious-linux/data/config/production.json (see how to configure a data-source)

See how to start Linkurious Enterprise on Linux.

Windows systems

  1. Remove eventual Windows security lock on the downloaded file (right-click on the file, then "Property" / "Unblock" / "OK")
  2. Unzip Linkurious Enterprise archive (right-click on the file, then "Extract all")
  3. Adjust securities to ensure access to the user executing the process
  4. Enter the linkurious-windows folder
  5. Check the configuration file at linkurious-windows/data/config/production.json (see how to configure a data-source)

See how to start Linkurious Enterprise on Windows.

Mac OS systems

  1. Unzip Linkurious Enterprise archive: > unzip linkurious-osx-v4.0.27.zip
  2. Adjust securities to ensure access to the user executing the process
  3. Enter the Linkurious Enterprise folder: > cd linkurious-osx
  4. Check the configuration file at linkurious-osx/data/config/production.json (see how to configure a data-source)

See how to start Linkurious Enterprise on Mac OS.

Docker Linux

  1. Load the docker image > docker load -i linkurious-docker-v4.0.27.tar.gz
  2. Port configuration

The Linkurious Enterprise docker image exposes the ports 3000 and 3443 for http and https connections respectively. These ports should be mapped on the host machine to allow user connections.

Please visit the docker documentation to learn how publish the ports of a container.

  1. Volume configuration

Even if not strictly necessary, the best practice is to define external named volumes to store application data outside the container.

The Linkurious Enterprise docker image doesn't declare any volume, however below folders should be maintained when upgrading Linkurious Enterprise and therefore should be mapped to external volumes:

Please visit the docker documentation to learn how the configure volumes.

Here is an example to create named volumes (an arbitrary name can be chosen):

docker volume create lke-data
docker volume create lke-elasticsearch
  1. Now you need to install your Linkurious Enterprise license, following the steps to manage your license.

See how to start Linkurious Enterprise with docker.

Install as a service

In order to run Linkurious Enterprise automatically when the operating system starts, it is possible to install it as a system service on Linux, Mac OS and Windows.

Open the administration menu by running menu.sh, menu.bat or menu.sh.command in the Linkurious Enterprise folder. Click on Install Linkurious as a system service (administrative rights may be needed to successfully complete the task).

Linkurious Enterprise automatically detects the owner of the folder and will use that user as the Process owner.

It is possible to use a different user by running the menu script with the option --user=USER (where USER is the desired Process owner with adequate permissions).

Uninstall from services

When Linkurious Enterprise is installed as a service, the administration menu (by running menu.sh, menu.bat or menu.sh.command in the Linkurious Enterprise folder) will show the current status of the service as well as a new entry to Uninstall Linkurious from system services.

 Deploying on premise: Starting Linkurious

Linux systems

To start Linkurious Enterprise, run the start.sh script in the linkurious-linux directory.

Alternatively, run the menu.sh script and click Start Linkurious.

By default, Linkurious Enterprise server will listen for connection on port 3000. However, some firewalls block network traffic ports other than 80 (HTTP). See the Web server configuration documentation to learn how to make Linkurious Enterprise listen on port 80.

Windows systems

To start Linkurious Enterprise, run the start.bat script in the linkurious-windows directory.

Alternatively, run the menu.bat script and click Start Linkurious.

The firewall of Windows might ask you to authorize connections to Linkurious Enterprise. If so, click on Authorize access.

Content of the linkurious-windows directory:

Linkurious Enterprise starting up on Windows:

Mac OS systems

Mac OS prevents you from running applications downloaded from the internet.
To solve this problem, please run the following command before starting Linkurious Enterprise.
This will remove the attributes used by the operating system to identify Linkurious Enterprise files as untrusted.

xattr -rc <Linkurious_home_directory>

To start Linkurious Enterprise, run the start.sh.command script in the linkurious-osx directory.

Alternatively, run the menu.sh.command script and click Start Linkurious.

Docker Linux

To start a Linkurious Enterprise docker image, please use the docker run command. Here is an example:

 docker run -d --rm \
     -p 3000:3000 \
     --mount type=volume,src=lke-data,dst=/data \
     --mount type=volume,src=lke-elasticsearch,dst=/elasticsearch \
     linkurious:4.0.27

Bind mounts

If you choose to mount a host machine folder as a volume please make sure that the user within the container has read and write access to the volume folders. By default Linkurious Enterprise runs ath the linkurious user (uid: 2013). You can do that by adding a --user option to the docker run command. The folders that you want to mount must exist before starting Docker, otherwise Linkurious Enterprise will fail to start due to permissions errors. Please read the docker documentation to learn more.

Here is an example:

 docker run -d --rm \
     -p 3000:3000 \
     --mount type=bind,src=/path/to/my/data/folder,dst=/data \
     --mount type=bind,src=/path/to/my/elasticsearch/folder,dst=/elasticsearch \
     --user "$(id -u):$(id -g)" \
     linkurious:4.0.27

If no user is set, the Linkurious Enterprise container will check for appropriate file permissions and change file permissions if necessary. By default, Linkurious Enterprise runs as the user linkurious who only exists in the container, not on the host. As a consequence, is is not trivial to to set up mount folders on the host which this new user has write permissions for. To make this process easier, file permissions will be set automatically if you run the container as root, and a helpful error message will be printed if file permissions cannot be fixed automatically.

Memory limits

If you are setting memory limits on the running container, using the argument --memory 1024m you will possibly need to adapt the quantity of memory used by the Linkurious Enterprise instance. When setting '--max-old-space-size' please take into account the full NodeJs process memory, subtracting roughly 50m to the allocated memory of the container. Considering you are not using the embedded Elasticsearch instance:

 docker run -d --rm \
     -p 3000:3000 \
     --mount type=bind,src=/path/to/my/data/folder,dst=/data \
     --memory 1024m \
     -e NODE_OPTIONS='--max-old-space-size=984' \
     linkurious:4.0.27

We do not recommended using embedded ES in a memory limited container.

You may also pass in environment variables that can be expanded in the configuration

Kubernetes

Please read the previous section on starting a Linkurious Enterprise instance using docker, and the section on fault tolerance.

A simple way to test out Linkurious Enterprise using Kubernetes is to create a simple deployment, using only one replica, and allocate a PersistentVolume for both of the volumes (lke-data, lke-elasticsearch) described above.

In production however you would want to follow the fault tolerance guide and use a StatefulSet, with a main/failover strategy, and the appropriate strategy configured for your load-balancer or ingress.

 Deploying on premise: Stopping Linkurious

Linux systems

Run the stop.sh script in the linkurious-linux directory.

Alternately, run menu.sh and click Stop Linkurious.

Windows systems

Run the stop.bat script in the linkurious-windows directory.

Alternately, run menu.bat and click Stop Linkurious.

Mac OS systems

Run the stop.sh.command script in the linkurious-osx directory.

Alternately, run menu.sh.command and click Stop Linkurious.

 Configuring

To edit the Linkurious Enterprise configuration, you can either edit the configuration file located at linkurious/data/config/production.json or use the Web user-interface:

Using an administrator account, access the Admin > Global configuration menu to edit the Linkurious Enterprise configuration:

Some configuration change requires a restart to be applied. Linkurious Enterprise will notify you about it and offer you to restart from the Web UI only if you made the changes from the Web UI itself. If you modified the production.json file manually, changes won't get applied immediately and you will need to restart Linkurious Enterprise.

Configuration keys are divided by category.

Password fields will always be hidden from the Web UI, but they can be edited.

Variable expansion

You can also pass variables to the configuration, that will in turn expand to their appropriate value from environment variables or files. For example using : $ENV:NEO4J_PASSWORD in the configuration will expand to the value of the environment variable NEO4j_PASSWORD.

Expandable variables are:

In the configuration object, you can use the following syntax:

When you are finished changing, click Save.

Limitation: There are some limitations with the "$ENV-JSON" expansion,

$ENV-JSON does not work when used at the root level or at the first level of the configuration (for example for the whole server.* configuration key.)

$ENV-JSON does not work when used at any level within the dataSource.* configuration key.

 Troubleshooting: Checking Linkurious status

Process monitoring

Linkurious Enterprise starts 3 separate processes when launched:

Check if these processes are alive by opening the menu from the Linkurious Enterprise directory (see how to open it on each operating system below):

Linux systems

Run menu.sh. Alternately, run menu.sh status.

Windows systems

Run menu.bat. Alternately, run menu.bat status.

Mac OS systems

Run menu.sh.command. Alternately, run menu.sh.command status.

API status

The status of the API can be retrieved using a browser or a command line HTTP client like cURL.

To retrieve the API status, send a GET request to http://127.0.0.1:3000/api/status (replace 127.0.0.1 and 3000 with the actual host and port of your server).

// example response
{
  "status": {
    "code": 200,
    "name": "initialized",
    "message": "Linkurious ready to go :)",
    "uptime": 8633
  }
}

API version

To retrieve the API status, send a GET request to http://127.0.0.1:3000/api/version (replace 127.0.0.1 and 3000 with the actual host and port of your server).

// example response
{
  "tag_name": "4.0.27",
  "name": "Brilliant Burrito",
  "prerelease": false,
  "enterprise": true
}

 Troubleshooting: Reading the logs

The logs of the application are located in linkurious/data/manager/logs folder:

For a structured version of the Linkurious Enterprise server logs in JSONL format, see the linkurious/data/logs folder:

 Troubleshooting: Getting support

Introduction

As part of your license, you have access to a customer service, which will help you resolve issues discovered while using our products.

If you are a commercial partner, you also have access to the support service, and can submit demands on behalf of customers too.

Unless your organization has a premium support agreement, the support service team will provide a first answer within 2 working days (timezone: France, 9 hours per day, 5 days per week, excluding French public holidays).

If you face issues while working with Linkurious Enterprise or require assistance using our product, you can submit your request as described below.

For the best experience, it is suggested to open a new request via our online support portal. In this way you can benefit from:

As an alternative, you can still submit a new request by sending an email to support@linkurio.us, however you will not benefit from the above-mentioned features.

Online support portal

You can access your online support portal at https://support.linkurious.com.

To authenticate, use your Linkurious Customer Center credentials (if you do not have access, you can ask your team to invite you).

After logging into the online support portal, you will see your dashboard from where you can:

By clicking on the request's subject, you can access the full history and interact with the support team as needed.

Submitting a support request

After logging into the online support portal, you will be able to submit a new request.

When submitting a new request, it is suggested to follow a few best practices to minimize the resolution time:

Here is an example of a suitable request (you can either embed images in the description or attach additional files separately).

After pressing Submit, you will receive an automatic confirmation email. You can reply to it to add more contents or follow up with the support team.

Troubleshooting report

The Linkurious Enterprise report is an archive that contains all the information needed to enable our support team to provide a resolution as quickly as possible.

The archive contains system logs, Linkurious Enterprise configurations, and does not contain any sensitive data related to your graph database.

There are two possible ways of collecting the report:

Collecting automatically generated report

You can download an automatically generated report from the Web user interface via the Admin > Global configuration menu:

At the end of the page, click Download Report:

Collecting logs manually

It can happen that the system fails to start due to an error. In that case, the following files should be added manually to a compressed archive:

Collecting extra logs

In some cases the support team may need some extra logs or data only accessible from your browser, please follow the below steps to collect them.

Collecting browser console logs

  1. Open your browser Development Tools. You usually find this option in your browser’s menu (refer to its documentation in case of doubts). If you are working on Chrome, you can use the following shortcuts: Option + + J (on macOS); Shift + CTRL + J (on Windows/Linux).
  2. Access the Console tab and clear the current page
  3. Refresh the page
  4. Re-perform all the steps that lead to the error
  5. Share the contents of the Console tab (screenshots and/or copy paste of the error message are good options)

Collecting browser network logs

  1. Open your browser Development Tools. You usually find this option in your browser’s menu (refer to its documentation in case of doubts). If you are working on Chrome, you can use the following shortcuts: Option + + J (on macOS); Shift + CTRL + J (on Windows/Linux).
  2. Access the Network tab, clear the current page, enable Preserve log and start recording (those actions may vary depending on your browser)
  3. Refresh the page
  4. Re-perform all the steps that bring to the error
  5. Right click on any line in the network tab
  6. Click on "Save all as HAR with content"

This file may contain sensitive data, this is usually not asked if not for specific complex issues. Always be careful when sharing this file. In case of doubts on those steps we suggest involving your internal IT / security team.

 Troubleshooting: Managing licenses

Managing licenses

Install the license

When running Linkurious Enterprise for the first time, you are asked to provide a valid license. You can download your license file from our Customer center.

Once you have provided a valid license, we ask you to create your Admin account.

Check if the license has expired

When your license expires, you are notified within the Linkurious Enterprise interface and asked to upload a new one.

To manually check your license expiry date:

Update the license

If your license with Linkurious has expired, please contact our sales team. In case your license has already been renewed, you can update the license. To achieve this:

 Troubleshooting: Vulnerabilities

How we prevent vulnerabilities

Linkurious Enterprise is scanned continuously for vulnerabilities both in the application code and in third-party dependencies using static code analysis tools and dependency scanning tools.

While doing that, we regularly have Linkurious Enterprise tested by independent third-party security specialists to test it for exploitable vulnerabilities (a.k.a. pentesting).

How we handle new vulnerabilities

When a security vulnerability is discovered in Linkurious Enterprise:

  1. We launch an internal task-force to evaluate the impact of the vulnerability and define its severity (see Severity levels).
  2. If the severity level of the vulnerability is high or critical, we publish a vulnerability report in our online vulnerability list. The report that we publish is updated continuously. It contains assessment, workaround and mitigation instructions.
    • For critical severity: a report is published within 2 working days
    • For high severity: a report is published within 10 working days
  3. If the severity is critical, we notify all potentially impacted customers by e-mail as soon as the report is published.
  4. We publish a software patch. Customers are notified by e-mail as soon as the patch is available.

Severity levels

Our vulnerability reports include a severity level. This severity level is based on our self-calculated CVSS score (Common Vulnerability Scoring System) for each specific vulnerability. CVSS is an industry standard vulnerability metric (learn more about CVSS).

For CVSS v3, we use the following severity rating system:

CVSS v3 score range Report severity level
0.1 - 3.9 Low
4.0 - 6.9 Medium
7.0 - 8.9 High
9.0 - 10.0 Critical

Below are a few examples of vulnerabilities which may result in a given severity level. Please keep in mind that this rating does not take into account details of your installation and are to be used as a guide only.

Severity Level: Critical

Critical severity vulnerabilities usually have most of the following characteristics:

For critical vulnerabilities, it is advised that customers patch or upgrade as soon as possible, unless you have other mitigating measures in place. For example, a mitigating factor could be if your installation is not accessible from the Internet.

Severity Level: High

High severity vulnerabilities usually have some of the following characteristics:

Severity Level: Medium

Medium severity vulnerabilities usually have some of the following characteristics:

Severity Level: Low

Low severity vulnerabilities typically have very little impact on an organization's business. Exploitation of such vulnerabilities usually requires local or physical system access. Vulnerabilities in third party code that are unreachable from Linkurious Enterprise's code may be downgraded to low severity.

Reporting a vulnerability

If you have discovered an unknown security vulnerability in Linkurious Enterprise (or in an associated product or service), please get in touch with us via email: security@linkurious.com

 Importing graph data

Before starting to explore the content of your graph database using Linkurious Enterprise, you need to import data in your graph database.

The following sections will help you import data into your graph:

  1. Neo4j
  2. Memgraph
  3. Amazon Neptune
  4. Cosmos DB
  5. Updating your graph data

If you already have data in your graph database or you don't need to import anything, see how to configure your graph database with Linkurious Enterprise.

 Importing graph data: Neo4j

To import data into Neo4j, you have a number of solutions depending on your needs.

"I need to import a large dataset"

If your data is static:

If you are streaming data, you can use Neo4j Streams Kafka Integration to ingest any kind of Kafka event into your graph.

"I want to load data from a smaller file"

For simple CSV files, to get you quickly up and running, you can use the official Linkurious CSV importer plugin to import data directly through Linkurious Enterprise. The plugin provides a simple user interface to upload CSV files and easily define relationships.

If you are using spreadsheets, you can easily transform the data within to Cypher queries with this tutorial.

Finally, If your data is in JSON format, you could use the
load JSON functionality from APOC

"I want to play with sample data"

By default, a pre-loaded movie database is available in Neo4j Desktop.

You can also get started with Neo4j Sandbox and launch a free Neo4j online instance with an example dataset

"It’s complicated"

If you are still not sure, or your data import needs are more complex, or if you need to get help from professionals, contact us and we will be happy to answer your questions.

 Importing graph data: Memgraph

To import data into Memgraph, you have a several options depending on your needs.

Memgraph has features to:

Please refer to the Memgraph documentation about data import for details.

 Importing graph data: Amazon Neptune

To import data into Amazon Neptune, you have a several options depending on your needs.

Importing data

Neptune supports importing data using:

Migrating data using Amazon Data Migration Service (DMS)

Neptune supports migrating data from another source using Amazon DMS. Please refer to the list of supported sources for data migration.

Migrating data from Neo4j

If you are migrating data from Neo4j to Neptune, the steps are:

  1. Use APOC to dump your Neo4j data in the CSV format
    • Open a Neo4j console or browser
    • Export the graph to CSV by running this Cypher command: CALL apoc.export.csv.all("neo4j-export.csv", {d:','})
  2. Convert your Neo4j dump using the neo4j-to-neptune converter
    • Clone the repository by running git clone git@github.com:awslabs/amazon-neptune-tools.git
    • Build the JAR by running mvn package in ./amazon-neptune-tools/neo4j-to-neptune/
    • Convert the CSV by running java -jar ./amazon-neptune-tools/neo4j-to-neptune/target/neo4j-to-neptune.jar convert-csv -i ./neo4j-export.csv -d output --infer-types
  3. Use the Neptune bulk loader to import the data in Neptune

 Importing graph data: Cosmos DB

Please refer to the Cosmos db online documentation for details on how to load data into Cosmos db.

 Importing graph data: Updating your graph data

When saving a visualization or a case, Linkurious Enterprise only stores the ID references to the nodes and edges stored in your graph database.
When updating your graph data you need to make sure your graph engine preserves those references to avoid any data loss.

There are 2 different strategies for updating your graph data. Each strategy has its own advantages and risks.

1. Updating your graph data incrementally.

This strategy consists in adding, removing or updating the nodes and edges within an existing database.
You can use this strategy when you know exactly the nodes and edges that have changed since your last database update.

After performing this update the following changes will be reflected in Linkurious Enterprise:

Neo4j and ID recycling

When you remove nodes and edges from Neo4j, the IDs of the deleted nodes and edges are recycled when you later create new nodes and edges. The consequence is that your existing visualizations in Linkurious Enterprise may contain references to new nodes and edges unrelated to the existing context.
If you plan to incrementally remove data from Neo4j, we recommend you use alternative identifiers before creating your visualizations.

2. Rebuilding your graph database.

This strategy consists in recreating your graph database from an external source.
You consider the current graph database stale, and you create a new graph database with fresh data.
This strategy is useful when your current infrastructure does not allow you to keep track of which nodes and edges are updated.

When you rebuild your graph database, new IDs will be assigned to all your nodes and edges, consequently breaking the references stored by Linkurious Enterprise. If you are planning to use this strategy, it is very important you configure alternative identifiers before creating your visualizations (only available with Neo4j).

In the unfortunate scenario that you have performed a database rebuild without configuring the alternative identifiers, Linkurious Enterprise will prevent access to your visualizations in an effort to prevent any data loss.

As an administrator, you can perform the following actions:

  1. Restore the previous version of the graph database from a backup
  2. Configure alternative identifiers (only available with Neo4j)
    1. After performing this configuration, you will need to re-open and save each visualization and case individually in order to apply the new configuration.

 Updating Linkurious

We release new versions of Linkurious Enterprise frequently with fixes and improvements.

The following pages will help you check for updates, back-up Linkurious Enterprise before updating, and update Linkurious Enterprise.

 Updating Linkurious: Checking for updates

About menu

Using an administrator account, access the Your Username > About menu to open the Linkurious Enterprise info:

Click Check for updates to see if you are using the latest version.

Public version API

Alternatively, you can check at http://linkurio.us/version/linkurious-enterprise.json

// example response
{
  "tag_name": "v4.0.27", // latest version of Linkurious Enterprise
  "message": null,
  "url": "https://get.linkurio.us/" // where to download the latest version from
}

 Updating Linkurious: Backing up your data

Follow these steps to perform a backup of your Linkurious Enterprise data:

  1. Stop Linkurious Enterprise
  2. Back-up of the linkurious/data folder
  3. Back-up the user-data store
  4. Start Linkurious Enterprise

Please note that this procedure does not back-up your graph data, but only your Linkurious Enterprise configuration and user-data (visualizations, users, etc.).

If you are backing up your data before a system update through a standard installer (i.e. Linux, Windows, Mac OS), make also a copy of the whole linkurious directory to be able to perform an easy rollback in case of problems.

 Updating Linkurious: Update procedure

If you follow this procedure, you will be able to update Linkurious Enterprise to a newer version without loosing your configuration and user-data store. Your data will be automatically migrated to the newer version.

Update

Before updating, make sure that you have backed-up your data in case something unexpected happens.

Even though this procedure is the standard one for a general update, some version (especially major releases) can introduce changes requiring extra attention. Please browse our public resources to verify whether there is something applicable to your specific configuration before proceeding with the update.

Updating with the standard installer

During the update procedure, if Linkurious Enterprise is running, it will be stopped. You will need to re-start Linkurious Enterprise after the update procedure.

  1. Download the newer version you wish to install (see how to download Linkurious Enterprise)
  2. Copy linkurious-xxx-v4.0.27.zip into the root folder of your working Linkurious Enterprise directory (along the start stop and update scripts)
  3. Run the existing update script from the root folder (Linux: update.sh, Mac OS: update.sh.command, Windows: update.bat). In case of failures, run it again to revert the changes.
  4. Done! You can restart Linkurious Enterprise.

If the update script fails, please check the update log located at linkurious/data/update.log for details.

Updating with Docker

If you use the Linkurious Enterprise Docker image, the only step to update Linkurious Enterprise is to use the new Docker image with the existing Linkurious Enterprise data volume.

Rolling back an update

This procedure only allows to undo an update and restore the version of Linkurious Enterprise that was installed just before the update, without loss of data.

This procedure requires that you have performed a full backup of Linkurious Enterprise before the update (see details in our backup guide).

Rolling back with the standard installer

If you are working on Linux, Windows or Mac OS:

  1. Stop Linkurious Enterprise in case it is still running
  2. Rename the current linkurious folder to linkurious_previous (it is needed if you will reach to support for investigation)
  3. Restore the whole linkurious folder from your backup
  4. Restore your user-data store:
    • if you are using the SQLite database (by default), it has been automatically restored with the previous step;
    • otherwise refer to the section about how to back-up the user-data store
  5. Start Linkurious Enterprise

Rolling back with Docker

If you use the Linkurious Enterprise Docker image:

  1. Stop your container
  2. Restore the backup of the container volumes
  3. Restore your user-data store:
    • if you are using the SQLite database (by default), it has been automatically restored with the previous step;
    • otherwise refer to the section about how to back-up the user-data store
  4. Recreate your container using the previous Docker image
  5. Start your container

 Configuring data-sources

A data-source is a conceptual representation of a graph database within Linkurious Enterprise. Visualizations and other user data created within Linkurious Enterprise will be associated their respective data-source.

Supported vendors

Linkurious Enterprise can connect to some of the most popular graph databases:

For more details about supported versions for each vendor, please check our compatibility matrix.

Multi-database support

Linkurious Enterprise is able to connect to several graph databases at the same time and lets you switch from one database to another seamlessly.

Edit the data-source configuration

You can configure your data-sources via the Web user interface or directly on the linkurious/data/config/production.json file.

Using the Web user interface

Using an administrator account, access the Admin > Data menu to edit the current data-source configuration:

Edit the data-source configuration to connect to your graph database:

Submit the changes by hitting the Save configuration button.

Using the configuration file

Edit the configuration file located at linkurious/data/config/production.json.

See details for each supported graph database vendor:

Source Key

Every data-source is uniquely identified with a sourceKey, a string computed when Linkurious Enterprise connects to the database for the first time, based on internal information from the data-source and saved in the configuration file.

Editing or removing the sourceKey of an existing configuration is strongly discouraged and may lead to unexpected behaviours.

 Configuring data-sources: Neo4j

Please check for supported Neo4j versions in our compatibility matrix.

Configuration

To edit the Neo4j data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "neo4j",
        "url": "neo4j://127.0.0.1:7687/",
        "user": "myNeo4jUser",
        "password": "myNeo4jPassword"
      },
      "index": {
        "vendor": "neo4jSearch"
      }
    }
  ]
}

Example configuration using TLS:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "neo4j",
        "url": "neo4j+s://127.0.0.1:7687/",
        "user": "myNeo4jUser",
        "password": "myNeo4jPassword"
      },
      "index": {
        "vendor": "neo4jSearch"
      }
    }
  ]
}

Learn more on how to configure SSL from the Neo4j documentation.

Linkurious connects to Neo4j via the Bolt protocol. To do so, you need to enable the protocol in your Neo4j configuration file. If an HTTP/S URL is configured, Linkurious will automatically upgrade the connection to Bolt.

Supported graphdb options with Neo4j:

Neo4j Aura

Linkurious Enterprise allows using Neo4j instances running on Neo4j Aura as data-sources.

Neo4j Aura is only supported for the Neo4j Aura instances running Neo4j engine v4.0 and later.

Search with Neo4j

In order to have full-text search, you can choose among the following options:

Neo4j credentials

If you just installed Neo4j, these steps will help you create credentials:

  1. Launch the Neo4j server
  2. Open your Web browser at http://127.0.0.1:7474
  3. Follow the instructions to create a new username and password

Alternatively, you can disable credentials in Neo4j by editing the Neo4j configuration at neo4j/conf/neo4j.conf by uncommenting the following line:

dbms.security.auth_enabled=false

Neo4j access rights

Note that configuring access rights is unnecessary on the Neo4j Community edition or if Neo4j credentials are disabled.

In Neo4j, access rights are managed using role-based access control. You can either:

Required privileges for graph exploration

In order to connect to a data-source, Linkurious requires a Neo4j user with the ACCESS, EXECUTE PROCEDURE and EXECUTE FUNCTION privileges. These privileges only allow Linkurious to connect to the data-source. Additional privileges must be granted in order to interact with the graph database. The Neo4j built-in PUBLIC role has these privileges on the default database. These privileges can be granted on a database $name to a custom role $role by running the following Cypher commands:

GRANT ACCESS ON DATABASE $name TO $role;
GRANT EXECUTE FUNCTION * ON DBMS TO $role;
GRANT EXECUTE PROCEDURE * ON DBMS TO $role;

If the data-source is read-only, the MATCH privilege must be granted on part or all of the graph, so that Linkurious can fetch nodes and edges. The Neo4j built-in reader role has this privilege on all databases, except the system one. This privilege can be granted by running the following Cypher commands:

GRANT MATCH {*} ON GRAPH $name TO $role;

If the data-source is read-write and the schema is in strict mode, the WRITE privilege must also be granted on the graph, so that linkurious can create nodes and edges. This corresponds to the Neo4j built-in editor role.

GRANT WRITE ON GRAPH $name TO $role;

Additionally, if the schema is not in strict mode, the NAME MANAGEMENT privilege must also be granted on the graph, so that linkurious can alter the schema. This corresponds to the Neo4j built-in publisher role.

GRANT NAME MANAGEMENT ON DATABASE $name TO $role;

Additional privileges required for full-text search

Neo4j search requires the INDEX MANAGEMENT privilege. This corresponds to the Neo4j built-in architect role.

GRANT INDEX MANAGEMENT ON DATABASE $name TO $role;

Elasticsearch doesn't require any specific privilege if incremental indexing is not used.

However, enabling incremental indexing on Elasticsearch requires the INDEX MANAGEMENT privilege. On Neo4j 5.0 and onward, the EXECUTE ADMIN PROCEDURE privilege is also needed in order to manage Neo4j triggers. And between Neo4j 5.0 and 5.3, the SHOW SERVER privilege is needed in check if the Neo4j server is a standalone instance or a cluster. These privileges correspond to the Neo4j built-in admin role.

GRANT INDEX MANAGEMENT ON DATABASE $name TO $role;
GRANT EXECUTE ADMIN PROCEDURES ON DBMS TO $role; // Only on Neo4j 5.0 and onward
GRANT SHOW SERVER ON DBMS TO $role; // Only between Neo4j 5.0 and 5.3

Configure Alternative Ids indices

Configuring alternative IDs indices is recommended.

The first step is to:

Once we have this information we can create the indices with the following Cypher queries:

CREATE FULLTEXT INDEX `myAlternativeNodeIdIndex` FOR (n:`Company`|`Person`|`City`) ON EACH [n.`myUniqueNodeId`] OPTIONS { indexConfig: { `fulltext.analyzer`: 'keyword' } }

CREATE FULLTEXT INDEX `myAlternativeEdgeIdIndex` FOR ()-[r:`WORKS_FOR`|`LIVES_IN`]-() ON EACH [r.`myUniqueEdgeId`] OPTIONS { indexConfig: { `fulltext.analyzer`: 'keyword' } }

If you are running a version of Neo4j older than v4.3 you may need to use the old syntax:

call db.index.fulltext.createNodeIndex('myAlternativeNodeIdIndex', ['Company', 'Person', 'City'], ['myUniqueNodeId'], {analyzer: 'keyword'})

call db.index.fulltext.createRelationshipIndex('myAlternativeEdgeIdIndex', ['WORKS_FOR', 'LIVES_IN'], ['myUniqueEdgeId'], {analyzer: 'keyword'})

If new node labels or edge types are added to Neo4j, it's necessary to recreate these indices with the full list of categories.

Once the indices are created, we can configure them Linkurious:

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "neo4j",
        "url": "neo4j://127.0.0.1:7687/",
        "user": "myNeo4jUser",
        "password": "nyNeo4jPassword",
        "alternativeNodeId": "myUniqueNodeId",
        "alternativeNodeIdIndex": "myAlternativeNodeIdIndex",
        "alternativeEdgeId": "myUniqueEdgeId",
        "alternativeEdgeIdIndex": "myAlternativeEdgeIdIndex"
      },
      "index": {
        "vendor": "neo4jSearch"
      }
    }
  ]
}

 Configuring data-sources: Amazon Neptune

Please check for supported Amazon Neptune versions in our compatibility matrix.

Network access

By default, Amazon Neptune is not accessible from outside your AWS Virtual Private Cloud (VPC). To allow Linkurious Enterprise to access Neptune, you need have several options:

Configuration

To edit a Neptune data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "name": "neptune",
      "graphdb": {
        "vendor": "neptune",
        "url": "https://neptune-instance-name.c2to76ungguf.us-east-1.neptune.amazonaws.com:8182",
        "accessKeyId": "AKIATWJHFKUGHEKH665AN",
        "secretAccessKey": "O5m1mTcReZ46zesZ/Zty27rfa58/5/SEG"
      },
      "index": {
        "vendor": "neptuneSearch",
        "url": "https://opensearch-instance-name.us-east-1.es.amazonaws.com"
      }
    }
  ]
}

Supported graphdb options with Neptune:

Search with Amazon Neptune

See options to enable full-text search with Amazon Neptune.

 Configuring data-sources: Memgraph

Please check for supported Memgraph versions in our compatibility matrix.

Configuration

To edit the Memgraph data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "memgraph",
        "url": "bolt+s://18.150.10.214",
        "user": "my-memgraph-user",
        "password": "my-memgraph-password"
      },
      "index": {
        "vendor": "elasticsearch",
        "host": "127.0.0.1",
        "port": 9201
      }
    }
  ]
}

Supported graphdb options with Memgraph:

Memgraph cloud

Linkurious Enterprise allows using Memgraph instances running on Memgraph cloud.

Search with Memgraph

See options to enable full-text search with Memgraph.

 Configuring data-sources: Cosmos DB

Cosmos DB is supported by Linkurious.

Configuration

To edit the Cosmos DB data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "cosmosDb",
        "url": "https://your-service.gremlin.cosmosdb.azure.com:443/",
        ".NET SDK URI": "https://your-service.documents.azure.com:443/",
        "database": "your-graph-database",
        "collection": "your-collection",
        "primaryKey": "your-account-primary-key",
        "partitionKey": "your-collection-partition-key"
      },
      "index": {
        "vendor": "azureSearch",
        "url": "https://your-search-service.search.windows.net",
        "apiKey": "your-search-service-admin-api-key",
        "nodeIndexName": "your-node-index",
        "edgeIndexName": "your-edge-index"
      }
    }
  ]
}

Supported graphdb options for Cosmos DB:

Search with Cosmos DB

In order to have full-text search, you can choose among the following options:

 Configuring data-sources: Alternative IDs

Note: alternative IDs are only supported with Neo4j

When you save a visualization in Linkurious Enterprise, only the node and edge identifier are persisted in the user-data store, along with position and style information. When a visualization is loaded, the node and edge identifiers are used to reload the actual node and edge data from the graph database.

If you need to re-generate your graph database from scratch, the graph database will probably generate new identifiers for all nodes and edges, breaking all references to nodes and edges in existing visualizations.

Using a property as a stable identifier

You can configure Linkurious Enterprise to use a node or edge property as stable identifiers. Once set-up, Linkurious Enterprise will use the given property as identifier instead of using the identifiers generated by the database.

Thanks to this strategy, visualizations will be robust to graph re-generation.

Notice that the properties used as identifier should be indexed by the database to allow for a fast lookup by value.

Alternative identifiers configuration

To use alternative node and edge identifiers, edit your data-source database configuration in the configuration file (linkurious/data/config/production.json):

Example of alternative identifier configuration with Neo4j:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "neo4j",
        "url": "http://127.0.0.1:7474/",
        "alternativeNodeId": "STABLE_NODE_PROPETY_NAME",
        "alternativeEdgeId": "STABLE_EDGE_PROPETY_NAME"
      }
      // [...]
    }
  ]
}

If you plan on using a compatible Neo4J version and alternative IDs, we recommend configuring alternative IDs indices.

To achieve better performance with alternative IDs is recommended to configure indices for alternative node and edge IDs.

Refer to the documentation specific to Neo4j on how to configure these indices.

 Configuring data-sources: Merging data-sources

You have the possibility to merge data-sources from the data-source management page with the following steps:

1. Open the data-source management page.

From the dashboard, go to the Admin > Data-sources management menu

2. Select the old data-source to be merged.

The data-source to be merged should be the old data-source now marked as offline because it has been replaced with the freshly generated data-source.

3. Select the new data-source to be updated.

On the resulting modal, select the new data-source then click on the merge button.

The user can choose to perform a normal merge, or an overwrite merge.

a. Normal merge

As a result, the following objects from the old data-source will be merged in the new data-source:

The Data-Source won't be deleted in case the user decides to do an overwrite merge at a later stage.

b. Overwrite merge

To perform an overwrite merge, simply select the "overwrite" check box in the merge modal.

As a result, the objects from the old data-source mentioned above will be merged in the new data-source. Additionally, the following objects will be replaced in the new data-source with the ones from the old data-source:

This action will irreversibly remove any data associated with the old data-source, and the data-source will be deleted.

 Configuring data-sources: Advanced settings

The following advanced data-source settings applies to all data-sources.

To change them, see how to configure Linkurious Enterprise.

General settings

Search engine settings

Graph exploration settings

Worker pool settings

The worker pool is an internal thread pool used to offload computational tasks from the main thread of the Linkurious Enterprise process. It is used to run alerts and custom queries, so that these do not affect the application responsiveness.

Additional Certificate Authorities

If Linkurious Enterprise is installed as a service, the service needs to be uninstalled and re-installed for the change to be taken into account.

Password obfuscation

 Resource management

Resource management

Resource management is where resources, such as (Spaces), are managed in Linkurious Enterprise.

Resource management page

You can go to this page by clicking Admin, Resource management.

Resource management access

 Resource management: Managing spaces

Managing spaces

Spaces are containers of visualizations shared with user groups. By default, the admin and source manager has this right enabled. To provide a user group the right to manage a space, you can enable it in the custom group creation, as shown below.

Manage spaces right

IMPORTANT

User groups that have the Manage access right can create and delete a space. This does not, however, automatically grant them access to all spaces. The spaces have to be shared explicitly to a user group.

Creating a space

You can create a space by clicking the Create Space button on the upper right part of the page. The Name and Share with input fields are required. You can share it with as many built-in groups and custom groups as necessary.

Create space

The space appears in the table once it’s created. Clicking on the name displays a panel that appears on the right (see image below) with the space’s information as well as the buttons to edit and delete.

Space drawer

Deleting a space

To delete a space, you click the name then click the delete button on the right drawer. This operation is irreversible, hence, the popin asks for further confirmation by asking you to type “delete”.

Delete space

Warning To delete a space having visualizations, you have to delete all visualizations within it before you can delete it. If you attempt to delete such a space, the popin informs you that you cannot do it.

 Search index

Linkurious Enterprise allows you to search your graph using natural full-text search.

In order to offer the search feature out-of-the-box, Linkurious Enterprise ships with an embedded Elasticsearch server. This option allow for zero-configuration deployment in many cases.

Indexing your graph data

By default, Linkurious Enterprise uses Elasticsearch for search. This options requires Linkurious Enterprise to index your graph database, which technically means that Linkurious Enterprise will feed the whole content of the graph database to Elasticsearch to make it searchable. The time required to index the graph database increases with the size of the graph and this solution has limits in its scalability.

Indexation typically happens at speeds between 2000 and 20000 nodes or edges per second, depending on the number of properties for nodes and edges, and hardware performances.

Embedded Elasticsearch

By default, Linkurious Enterprise ships with an embedded Elasticsearch server (version 7.16.3). This server only listens for local connections on a non-default port (it binds to 127.0.0.1:9201), for security reasons and to avoid collisions with existing servers.

Use your own Elasticsearch

It is possible to use your own Elasticsearch cluster for performances reasons. Linkurious Enterprise supports Elasticsearch v1.x and v2.x. See details about Elasticsearch configuration options.

Search scalability and alternatives to Elasticsearch

Using Elasticsearch is convenient but may not fit cases where the graph database is big (more than a couple million nodes and edges) and is regularly modified from outside Linkurious Enterprise, which required to re-index the whole database.

In order to offer a scalable search feature on big graphs, Linkurious Enterprise offers alternatives search solution. See details about the different options.

Edit the search configuration

You can configure your search engines via the Web user interface or directly on the linkurious/data/config/production.json file.

Using the Web user interface

Using an administrator account, access the Admin > Data menu to edit the current data-source configuration:

Edit the search engine configuration to connect to your graph database:

Submit the changes by hitting the Save configuration button.

Using the configuration file

Edit the configuration file located at linkurious/data/config/production.json.

See details for each supported search connector.

 Search index: Search Option Comparison

Choosing which full-text search engine to use for a specific graph vendor is not always obvious.

For each graph vendor, this page will help you list your options and compare their pros and cons.

Column names definitions

Feature Definition
Onboarding Does this search option require additional configuration, or can it be used out-of-the-box with the associated graph database?
Fast indexing How fast is indexing? Note that this is a relative metric; while some search options may be faster than others, speed will depend on the complexity of your data model and your hardware limitations.
Automatic index sync Are changes made to the graph DB propagated to the index automatically?
Search scalability How well search queries perform for large graph databases? The actual upper limit on the performance of a given option will vary from vendor to vendor.
Advanced search If advanced search features are available, such as numerical and date range search operators.

Neo4j

Search option Onboarding Fast indexing Automatic index sync Search scalability Advanced search
Embedded Elasticsearch Plug-and-play No No Will not scale beyond ~100M nodes Yes (requires configuration)
External Elasticsearch (v7+) Requires Elasticsearch installation and configuration No No Yes (by adding hardware to Elasticsearch cluster) Yes (requires configuration)
Neo4j Search (v4.0.2+) Plug-and-play Yes Yes Limited No
Elasticsearch Incremental Indexing Requires External Elasticsearch (versions compatible with Linkurious Enterprise) and Neo4j v4.0.2 and above Yes (except the first full indexing) Yes (requires configuration) Yes (by adding hardware to Elasticsearch cluster) Yes (requires configuration)

Amazon Neptune

Search option Onboarding Fast indexing Automatic index sync Search scalability Advanced search
Embedded Elasticsearch Plug-and-play No No Will not scale beyond ~100M nodes Yes (requires configuration)
External Elasticsearch (v7+) Requires Elasticsearch installation and configuration No No Yes (by adding hardware to Elasticsearch cluster) Yes (requires configuration)
OpenSearch for Amazon Neptune Requires configuration in Amazon Neptune & OpenSearch Yes Yes Yes (by adding resources in OpenSearch) No

Memgraph

Search option Onboarding Fast indexing Automatic index sync Search scalability Advanced search
Embedded Elasticsearch Plug-and-play No No Will not scale beyond ~100M nodes Yes (requires configuration)
External Elasticsearch (v7+) Requires Elasticsearch installation and configuration No No Yes (by adding hardware to Elasticsearch cluster) Yes (requires configuration)

Cosmos DB

Search option Onboarding Fast indexing Automatic index sync Search scalability Advanced search
AzureSearch Requires AzureSearch setup (easy) Yes Yes Yes No
Embedded Elasticsearch Plug-and-play No No Will not scale beyond ~1M nodes (missing backpressure) Yes (requires configuration)
External Elasticsearch (v7+) Requires Elasticsearch installation and configuration No No Will not scale beyond ~1M nodes (missing backpressure) Yes (requires configuration)

 Search index: Neo4j Search

The neo4jSearch connector is a solution for full-text search with Neo4j. neo4jSearch is supported since version 3.5.1 of Neo4j.

Neo4j search integration

Linkurious can use the builtin search indices managed by Neo4j itself. You can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json to set the index.vendor property to the value neo4jSearch.

Configuration

To edit the Neo4j data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "neo4j",
        "url": "http://127.0.0.1:7474/",
        "user": "myNeo4jUser",
        "password": "nyNeo4jPassword"
      },
      "index": {
        "vendor": "neo4jSearch",
        "indexEdges": true
      }
    }
  ]
}

Supported index options with Neo4jSearch:

Note that, in Neo4jSearch, only fields stored in Neo4j as string will be searchable. Numerical and date properties won't be searchable if stored in Neo4j as numbers or native dates.

 Search index: Elasticsearch

Elasticsearch is supported from version 7.x using the elasticSearch connector.

Embedded Elasticsearch

Linkurious Enterprise ships with an embedded Elasticsearch server (version 7.16.3).

ATTENTION: The internal Elasticsearch is not intended to be used for graph databases > 50,000,000 nodes. Though indexation and search performance are ultimately dependent on hardware limitations, it has been configured to prevent horizontal scaling and so is not an efficient choice for large DBs. It is meant instead as a quick indexation strategy for POCs or small deployments.

To use the Linkurious Enterprise embedded Elasticsearch instance, set the following index configurations keys:

Example configuration:

{
  "dataSources": [
    {
      "graph": {
        "vendor": "neo4j"
        "url": "http://127.0.0.1:7474"
      },
      "index": {
        "vendor": "elasticSearch",
        "host": "127.0.0.1",
        "port": 9201
      }
    }
  ]
}

Configuring Elasticsearch

Search connector elasticSearch supports the following options:

Example configuration:

{
  "dataSources": [
    {
      "graph": {
        "vendor": "neo4j",
        "url": "http://127.0.0.1:7474"
      },
      "index": {
        "vendor": "elasticSearch",
        "host": "192.168.1.122",
        "port": 9200,
        "skipEdgeIndexation": true
      }
    }
  ]
}

Enabling search on numerical and date properties

Please check here how to configure search on numerical and date properties.

 Search index: OpenSearch for Amazon Neptune

Amazon OpenSearch is a managed search engine operated by AWS and based on OpenSearch, an open-source Elasticsearch fork maintained by AWS.

Amazon OpenSearch with Amazon Neptune

Amazon OpenSearch is a good option as for full-text search in Amazon Neptune because Amazon provides a built-in integration that allows changes in Amazon Neptune to be automatically synchronized to OpenSearch.

Be aware that you should set up the Neptune-to-OpenSearch integration on an empty Neptune graph. If you set up the integration after you already added data to Neptune, existing data will not be automatically synchronized to OpenSearch.

If you already have data in your graph, check out how to export Neptune to OpenSearch

See the AWS documentation for how to set up the Neptune to OpenSearch integration

A simplified guide is provided here as a quick start guide:

  1. Make sure the IAM role running Neptune can also run queries in OpenSearch
  2. Enable Neptune streams
    • Open the "parameter groups" section in your Neptune console)
    • Click the "create new parameter group" button
    • Set the "type" to "DB cluster parameter group"
    • Click the "edit parameter" button
    • Set neptune_streams to 1
    • Save this new parameter group
    • Edit your Neptune instance to use the parameter group you just created
  3. Create an OpenSearch instance
    • Open your OpenSearch console
    • Create a new OpenSearch instance (choose either Elasticsearch 7.10 or OpenSearch 1.3)
    • Choose network settings that allow Neptune and OpenSearch to communicate (i.e. same VPC, same subnet)
  4. Set up the Neptune-to-OpenSearch synchronization

 Search index: Azure Search

Azure search is the recommended full text search solution for Cosmos DB.

Azure search integration

Linkurious requires an index on nodes to perform a search. If you do not have a configured index yet, you can create one via the azure portal.

Additionally, you can create an index on edges if you want search them as well with Linkurious.

Please review the description of each index attributes and make sure the label field is marked as filterable. Linkurious will not be able to use the index otherwise.

Configuration

To edit the AzureSearch data-source configuration, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "dataSources": [
    {
      "graphdb": {
        "vendor": "cosmosDb",
        "url": "https://your-service.gremlin.cosmosdb.azure.com:443/",
        "database": "your-graph-database",
        "collection":  "your-collection",
        "primaryKey": "your-account-primary-key"
      },
      "index": {
        "vendor": "azureSearch",
        "url": "https://your-search-service.search.windows.net",
        "apiKey": "your-search-service-admin-api-key",
        "nodeIndexName": "your-node-index-name",
        "edgeIndexName": "your-edge-index-name"
      }
    }
  ]
}

Supported index options with Azure search:

Please refer to the Azure search online documentation for details on how to load data into Azure search.

Note that today, in Azure Search, it's not possible to search on numbers or dates. If you are interested in this feature, please get in touch.

 Search index: Incremental Indexing

Incremental indexing allows you to keep in sync your Elasticsearch index and your Neo4j graph database.

Linkurious Enterprise will index at a regular interval new and updated items from your database. This way, you avoid a complete reindex every time you update your data.

This is achieved by keeping track of a timestamp on every node and edge in the database, hereby allowing the indexer to only consider the nodes with newer timestamps and consequently reducing the indexing time.

You should consider this option if your database holds a significant number of items and needs to be updated frequently.

Requirements

1. Compatible Neo4j & Linkurious Enterprise versions

Here some important considerations when choosing incremental indexing:

2. APOC

Linkurious Enterprise relies on APOC triggers to ensure that every node and edge created or updated has a timestamp.

You need to make sure that you have installed APOC correctly and enabled APOC triggers. You can find all the information you need to install APOC from Neo4j documentation.

You can quickly verify that you have installed everything correctly by executing the following command from your Neo4j browser:

CALL apoc.trigger.list()

3. A property name

Your need to carefully choose the property that will hold the timestamp on every node/edge of your database. The consequence of this choice is that Linkurious Enterprise will create triggers that will store a timestamp on this property for all new and updated nodes/edges.

This means that any information stored on that property will be overwritten by the trigger

Enabling incremental indexing with Elasticsearch

After you have installed and configured APOC, you can enable incremental indexing from the data-source configuration page or by editing the configuration file with the following options:

After you have enabled incremental indexing for the first time, Linkurious Enterprise requires to perform a complete re-indexing of the data-source to ensure that every item has been indexed. You simply need to click on the "Start indexing" button to complete the configuration.

Linkurious Enterprise will index your data-source incrementally from that point forward using the timestamps generated by the APOC triggers.

Scheduling incremental indexing

Once you have set up the incremental indexation, you can configure the frequency at which it will be triggered. You can customize this schedule by adding a cron expression to your Elasticsearch configuration.

You can make this change from the configuration file located at linkurious/data/config/production.json under datasources.index for each dataSource.

By default, we have set all incremental indexing to be launched every Sunday at 12PM, but you can change it to the frequency that most suits your needs. We advise that you schedule your increments to run after you have updated your database with new information. Here are some examples of cron expressions:

If you need to index your data-source at non-regular intervals:

Indexing by clicking the "Update index" button (or using the equivalent update index API endpoint) only performs an incremental update of the index. Note that you can also rebuild your index from scratch by clicking the "Re-create index" button. It might be useful if the index is inconsistent with the data-source schema (because the latter has changed).

You can disable automatic indexing with the following configuration: "incrementalIndexationCron": "none"

 Search index: Numerical/Date search

Configure search on numerical and date properties

Elasticsearch is required to be able to perform numerical and date search.

To properly configure Elasticsearch for number and date search please follow these steps:

Note that if you change the types after the indexing, you will need to re-index for the changes to apply.

 User-data store

Linkurious Enterprise uses an SQL database to store user-data. The database contains:

This database doesn't store the business data stored in the graph database (except for the widget) which makes it a lightweight database that doesn't need a lot of resources.

By default, the user-data store is a SQLite file-based database. This makes Linkurious Enterprise easy to deploy.

For deployment at scale (more than a couple users), we recommend switching to one of the supported server-based databases:

To see the exact list of supported vendors and versions, please review our compatibility matrix.

Database server requirements

Typical database server requirements for a moderate usage of the system with less than 100 users are:

You may need to allocate more resources in the following scenarios:

If you need to get help from professionals, contact us and we will be happy to answer your questions.

Getting started

In order to get started with Linkurious Enterprise, there are few requirements for user-data store to function properly.

In order to create a new linkurious database and an associated user, refer to your team of database experts to comply with possible internal policies. Below is an example of typical queries you can use (replace SQL_USER_NAME, SQL_PASSWORD, and SQL_HOST by actual values).

On MySQL and MariaDB:

CREATE USER 'SQL_USER_NAME'@'SQL_HOST' IDENTIFIED BY 'SQL_PASSWORD';
CREATE DATABASE linkurious;
GRANT ALL PRIVILEGES ON linkurious.* TO 'SQL_USER_NAME'@'SQL_HOST';

Please note that custom sql_mode in MariaDB and MySQL is not supported. Linkurious Enterprise only supports the default value for sql_mode.

On Microsoft SQL Server:

CREATE DATABASE linkurious;
CREATE LOGIN SQL_USER_NAME WITH PASSWORD = 'SQL_PASSWORD', DEFAULT_DATABASE = linkurious;
USE linkurious;
CREATE USER SQL_USER_NAME FOR LOGIN SQL_USER_NAME;
EXEC sp_addrolemember 'db_owner', SQL_USER_NAME;

Database configuration

Linkurious Enterprise provides many options which can be used to configure user-data store connection. Below, you can find the configuration documentation and configuration examples for popular DBMS solutions.

In the Linkurious Enterprise configuration file, it is possible to configure the database connection under db key.

Configure with SQLite

SQLite if the default user-data store of Linkurious Enterprise.

"db": {
    "name": "linkurious",
    "options": {
      "dialect": "sqlite",
      "storage": "server/database.sqlite"
    }
}

Configure with MySQL

"db": {
    "name": "linkurious",
    "username": "MYSQL_USER_NAME",
    "password": "MYSQL_PASSWORD",
    "options": {
      "dialect": "mysql",
      "host": "MYSQL_HOST",
      "port": 3306
    }
}

Configure with MySQL and enforce ssl

"db": {
    "name": "linkurious",
    "username": "MYSQL_USER_NAME",
    "password": "MYSQL_PASSWORD",
    "options": {
      "dialect": "mysql",
      "dialectOptions": {
        "ssl": {
          "require": true
        }
      }
      "host": "MYSQL_HOST",
      "port": 3306
    }
}

See advanced dialect options.

Configure with Microsoft SQL Server

"db": {
    "name": "linkurious",
    "username": "MSSQL_USER_NAME",
    "password": "MSSQL_PASSWORD",
    "options": {
      "dialect": "mssql",
      "host": "MSSQL_HOST",
      "port": 1433
    }
}

Configure with MariaDB

"db": {
    "name": "linkurious",
    "username": "MARIADB_USER_NAME",
    "password": "MARIADB_PASSWORD",
    "options": {
      "dialect": "mariadb",
      "host": "MARIADB_HOST",
      "port": 3306
    }
}

 User-data store: Migrating to an external database

The default storage system for Linkurious Enterprise is SQLite.

Configuring Linkurious Enterprise to work with MySQL is a really easy procedure if you don't need to migrate data from SQLite.

Migrating data from SQLite to an external database is possible but it is a procedure we would recommend only if restarting from scratch with the new configuration is not a viable option.

Our public resources contain a specific tool needed to perform the migration from SQLite to one of the supported databases, as well as the detailed list of steps to use and eventually configure the tool.

If you need help with the procedure please contact us.

 User-data store: Backing-up your store

If you are using the SQLite database (by default), you only need to follow the standard Linkurious Enterprise backup procedure.

If you are using another database to store the Linkurious Enterprise user-data, please refer to one of the following guides:

 Web server

The web server of Linkurious Enterprise delivers the application to end users through HTTP/S. It is configured in the server configuration key within the configuration file (linkurious/data/config/production.json):

General

Within the server key:

Some firewalls block network traffic ports other than 80 (HTTP). Since only root users can listen on ports lower than 1024, you may want reroute traffic from 80 to 3000 as follows:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

If you use SSL, you can add a second rule to redirect 3443 to 443:

sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3443

Serving Linkurious Enterprise under a custom path

Within the server key:

In some cases, you may want to host Linkurious Enterprise on a path other than root for a particular domain. For example, if you want Linkurious Enterprise to be reachable at http(s)://HOST:PORT/linkurious you should set baseFolder equal to linkurious.

Link generation

Within the server key:

In some cases, Linkurious Enterprise needs to generate links to itself (for example when generating a link to a widget). For that, the server needs to know its public domain and port to generate those links.

The public port can be different from the actual port if you use traffic rerouting (using a firewall or a reverse-proxy). In the example above (traffic rerouting), the actual HTTP port (listenPort) is 3000, but the public HTTP port (publicPortHttp) is 80.

Cookies

Within the server key:

Cross-origin resource sharing (CORS)

Within the server key:

Allow to render Linkurious Enterprise embedded in another Web page

Linkurious Enterprise can be embedded in another Web page via an iframe under certain technical conditions. This can be tricky due to modern Web browser security mechanisms.

Follow these steps:

  1. The embedding Web page and Linkurious Enterprise must be served using the same scheme (e.g. both on HTTPS)
  2. The embedding Web page and Linkurious Enterprise must have the same domain, e.g. if the embedding Web page can be served under https://app.example.com (domain: example.com), then Linkurious Enterprise must be served under another subdomain of example.com, e.g. https://linkurious.example.com.
  3. If you are using a modern Web browser, set server.cookieSameSite to "none" in the configuration (see why).
  4. In the configuration, set server.allowFraming to true. This will tell Linkurious Enterprise to disable the default iframe protection by not setting the X-Frame-Options:SAMEORIGIN HTTP header.

Custom HTTP Headers

Within the server key:

Example:

"customHTTPHeaders": {
  "header1": "value1",
  "header2": "value2"
}

Note: Some header keys are reserved for Linkurious Enterprise and will be overwritten by the server to default values.

Image cross-origin (client-side)

Within the ogma.settings.render key:

Disabling compression for dynamic content

It is possible to disable the gzip compression for dynamic content that is returned by the Linkurious Enterprise server.

Within the server key:

Content Security Policy (CSP)

If you want to enable content-security-policy for Linkurious Enterprise, you need to use the custom HTTP Headers option of the Web server. The policies required for the application to work are:

As a consequence, the recommended CSP policy is:

"customHTTPHeaders": {
  "Content-Security-Policy": "default-src 'self' 'unsafe-inline' blob: data:"
}

SSL

Within the server key:

External communications with the Linkurious Enterprise server can be secured using SSL without installing third-party software.

If the Linkurious Enterprise server, graph database, and the search index are installed on different machines, we recommend using secure communication channels between these machines (e.g. HTTPS or WSS). Please refer to the data-source documentation and search index documentation to learn how to enable HTTPS.

To use custom Certificate Authorities (CA), please check how to use additional Certificate Authorities in Linkurious Enterprise.

TLS versions

The TLS protocol versions supported by Linkurious Enterprise are v1.0, v1.1, v1.2 and v1.3. By default, TLS v1.0 and v1.1 are disabled.

If you want to change the enabled versions of the TLS protocol:

Available options (source):

To customize the exact list of ciphers used by the TLS protocol, see tlsCipherList in the server configuration above.

 Authentication: Getting started

When Linkurious Enterprise is started for the first time, authentication has to be set up so that users can access the platform.

There are 2 possible authentication options:

Local authentication

By default, when you access Linkurious Enterprise for the first time, you need to create a local administrator account, unless an external authentication provider has been configured and an external group is mapped into the admin group (see group mapping). In order to create this first admin account, you need to provide a valid license as a proof of ownership of your Linkurious Enterprise instance.

Once this local administrator account has been created, it can be used to connect to Linkurious Enterprise and create other user accounts (see how to create users).

Password hashing

Passwords of local users are hashed with the PBKDF2 algorithm and the following parameters:

External authentication

When using an external source for authentication, users are automatically created in Linkurious Enterprise when they connect for the first time.

These shadow users allow to store specific data such as preferences, groups, and visualizations.

Passwords of external users are never stored within Linkurious Enterprise.

Authentication services

Linkurious Enterprise supports the following external authentication services:

If your company uses an authentication service that Linkurious Enterprise does not support yet, please get in touch.

If you enable a Single-Sign-On (SSO) capable authentication service (OAuth/OpenID Connect or SAML2), your users don't need to sign in directly in Linkurious Enterprise. They instead sign in by clicking the SSO button and are then redirected to the identity provider for authentication.

img

Group mapping

If an external source already organizes users into groups, it's possible to use this information to automatically map external groups into Linkurious groups. To do so, you have to set the access.externalUsersGroupMapping configuration key to be an object with the external group IDs as keys and the internal group IDs, group names, or a combination of both as values (you can map both built-in and custom groups).

For example, if you want to provide group mapping for Microsoft Active Directory:

{ // under the access configuration key
  // ...
  "externalUsersGroupMapping": {
    "Administrators": 1 // any Active Directory admin is a Linkurious admin ("1" being the id of the admin built-in group)
    "DataAnalysts": "analyst" // any Active Directory data analyst will be assigned to the "analyst" custom group of each data source(s) containing a group with that name
    "ProductManagers": [3, "product manager"] // any Active Directory product manager will be assigned to the group with id "3" and to the "product manager" custom group of each data source(s) containing a group with that name
  }
  // ...
}

The built-in group names that you can use are the following:

Group name case sensitivity depends on the user-data-store vendor and collation.

For some identity providers, the external group IDs are an actual name; for others, it is an ID:

To exclude some groups of users from signing in into Linkurious, set up a list of authorized groups in the configuration key access.externalUsersAllowedGroups.

{ // under the access configuration key
  // ...
  "externalUsersAllowedGroups": [
    "CN=Administrators,CN=Users,DC=linkurious,DC=local",
    "CN=Analysts,CN=Users,DC=linkurious,DC=local"
  ]
  // ...
}

By default, when an external user is connected for the first time, their external groups are mapped once. So any change in the user's group in the external source would not be reflected in the Linkurious Enterprise user. However, setting autoRefreshGroupMapping to true makes an external user's groups to be reset according to externalUsersGroupMapping, each time the external user signs in.

{ // under the access configuration key
  // ...
  "autoRefreshGroupMapping": true,
  // ...
}

Note that when autoRefreshGroupMapping is true updating external users' groups from within Linkurious Enterprise is not allowed.

When using SSO to sign in to Linkurious Enterprise, if the identity provider groups are mapped to more than one built-in group, Linkurious Enterprise will choose the one with the highest permissions per data-source and ignore the other groups. If admin built-in group is used, it will override the other groups.

 Authentication: LDAP / Active Directory

If Linkurious Enterprise is connected to an LDAP service, users will be authenticated using the external service at each log-in.

If you have a LDAP service running in your network, you can use it to authenticate users in Linkurious Enterprise.

Contact your network administrator to ensure that the machine where Linkurious Enterprise is installed can connect to the LDAP service.

OpenLDAP

For OpenLDAP compatible providers, add or edit the existing ldap section inside the access configuration.

Allowed options in access.ldap:

The bindDN and bindPassword are optional. If specified they will be used to bind to the LDAP server.

Example LDAP configuration:

"access": {
  // [...]
  "ldap": {
    "enabled": true,
    "url": "ldap://ldap.forumsys.com:389",
    "bindDN": "cn=read-only-admin,dc=example,dc=com",
    "bindPassword": "password",
    "baseDN": ["dc=example,dc=com"],
    "usernameField": "uid",
    "emailField": "mail",
    "groupField": "group"
  }
}

Connect to multiple LDAP services

You can configure Linkurious Enterprise to connect to multiple LDAP services.

During the authentication process, Linkurious Enterprise will validate the user credentials against each LDAP service and use the identity resolved by the first successful attempt, following the order in which they appear in the configuration.

Example with multiple LDAP configurations:

"access": {
  // [...]
  "ldap": [
    {
        "enabled": true,
        "url": "ldap://linkurious.fr:389",
        "bindDN": "cn=read-only-admin,dc=example,dc=com",
        "bindPassword": "password",
        "baseDN": ["dc=example,dc=com"],
        "usernameField": "uid",
        "emailField": "mail",
        "groupField": "group"
    },
    {
        "enabled": true,
        "url": "ldap://linkurious.com:389",
        "bindDN": "cn=read-only-admin,dc=example,dc=com",
        "bindPassword": "password",
        "baseDN": ["dc=example,dc=com"],
        "usernameField": "uid",
        "emailField": "mail",
        "groupField": "group"
    }
  ]
}

Active Directory

For Microsoft Active Directory, add a msActiveDirectory section inside the access configuration.

Allowed options in access.msActiveDirectory:

Users can authenticate with their userPrincipalName or their sAMAccountName.

Use the domain configuration key to avoid your users to specify the domain part of their userPrincipalName. Use the netbiosDomain configuration key to avoid your users to specify the NetBIOS domain part of their sAMAccountName.

Example Active Directory configuration:

"access": {
  // [...]
  "msActiveDirectory": {
    "enabled": true,
    "url": "ldaps://ldap.lks.com:636",
    "baseDN": "dc=ldap,dc=lks,dc=com",
    "domain": "ldap.lks.com",
    "netbiosDomain": "LINKURIO",
    "tls": {
      "rejectUnauthorized": true,
      "enableTrace": false
    }
  }
}

In alternative is possible to use your on premises Active Directory in conjunction with Azure Active Directory to provide SSO to your users. Please refer to Prerequisites for Azure AD Connect for more information and to SSO with Azure AD to know how to setup Azure AD as an identity provider.

Connect to multiple Active Directory services

You can configure Linkurious Enterprise to connect to multiple Active Directory services.

During the authentication process, Linkurious Enterprise will validate the user credentials against each Active Directory service and use the identity resolved by the first successful attempt, following the order in which they appear in the configuration.

Example with multiple Active Directory configurations:

"access": {
  // [...]
  "msActiveDirectory": [
    {
        "enabled": true,
        "url": "ldaps://ldap.lks.us:636",
        "baseDN": "dc=ldap,dc=lks,dc=us",
        "domain": "ldap.lks.us",
        "netbiosDomain": "LINKURIOUS",
        "tls": {
          "rejectUnauthorized": true
        }
    },
    {
        "enabled": true,
        "url": "ldaps://ldap.lks.fr:636",
        "baseDN": "dc=ldap,dc=lks,dc=fr",
        "domain": "ldap.lks.fr",
        "netbiosDomain": "LINKURIOUS"
    }
  ]
}

 Authentication: SSO with Azure AD

Linkurious Enterprise supports Microsoft Azure Active Directory as an external authentication provider.

Configuration

To set up Linkurious Enterprise authentication with Microsoft Azure Active Directory, follow these steps:

  1. Create a new app called Linkurious in Azure Active Directory on Azure Portal
  2. Assign the Directory.Read.All access right to the new app (notice: an Azure admin's approval is needed)
  3. From the Azure Portal, obtain the following parameters:
    • authorizationURL, e.g. https://login.microsoftonline.com/60d78xxx-xxxx-xxxx-xxxx-xxxxxx9ca39b/oauth2/authorize
    • tokenURL, e.g. https://login.microsoftonline.com/60d78xxx-xxxx-xxxx-xxxx-xxxxxx9ca39b/oauth2/token
    • clientID, e.g. 91d426e2-xxx-xxxx-xxxx-989f89b6b2a2
    • clientSecret, e.g. gt7BHSnoIffbxxxxxxxxxxxxxxxxxxtyAG5xDotC8I=
    • tenantID, (optional, required only for group mapping) e.g. 60d78xxx-xxxx-xxxx-xxxx-xxxxxx9ca39b
  4. Add or edit the existing oauth2 section inside the access section in linkurious/data/config/production.json

Example access.oauth2 configuration with Microsoft Azure Active Directory:

"access": {
  // [...]
  "oauth2": {
    "enabled": true,
    "provider": "azure",
    "authorizationURL": "https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/oauth2/authorize",
    "tokenURL": "https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/oauth2/token",
    "clientID": "XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX",
    "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "azure": {
      "tenantID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    }
  }
}

Oauth2 redirect URL

The OAuth2 redirect URL of Linkurious Enterprise is the following: http(s)://HOST:PORT/api/auth/sso/return.

 Authentication: SSO with Google

Linkurious Enterprise supports Google as an external authentication provider with Single Sign-On.

Since Google implements the OpenID Connect standard, it can be configured as an OpenID Connect provider in Linkurious Enterprise.

Configuration

To set up Linkurious Enterprise authentication with Google, follow these steps:

  1. Create the credentials on your Google Developers console. You may have to fill in the OAuth consent screen.
  2. From the portal, obtain the following parameters:
    • authorizationURL, e.g. https://accounts.google.com/o/oauth2/v2/auth
    • tokenURL, e.g. https://www.googleapis.com/oauth2/v4/token
    • clientID, e.g. 1718xxxxxx-xxxxxxxxxxxxxxxx.apps.googleusercontent.com
    • clientSecret, e.g. E09dQxxxxxxxxxxxxxxxxSN
  3. Add or edit the existing oauth2 section inside the access section in linkurious/data/config/production.json

To limit the access to the Google accounts from your domain, use the hd query parameter in the authorizationURL with your domain as value.

Example access.oauth2 configuration with Google:

"access": {
  // [...]
  "oauth2": {
    "enabled": true,
    "provider": "openidconnect",
    "authorizationURL": "https://accounts.google.com/o/oauth2/v2/auth?hd=YOUR_DOMAIN",
    "tokenURL": "https://www.googleapis.com/oauth2/v4/token",
    "clientID": "XXXXXXXXXX-XXXXXXXXXXXXXXXX.apps.googleusercontent.com",
    "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXX"
  }
}

OAuth2 redirect URL

The OAuth2 redirect URL of Linkurious Enterprise is the following: http(s)://HOST:PORT/api/auth/sso/return. This redirect url will need to be added in the Authorized redirect URls section of the credentials section on your Google Developers console

google sso return url config

 Authentication: SSO with OpenID Connect

Linkurious Enterprise supports any OpenID Connect compatible provider as external authentication providers.

What is OpenID Connect?

OpenID Connect is an identity layer on top of the OAuth2 protocol. It allows applications (like Linkurious Enterprise) to verify the identity of End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable manner.

Configuration

To set up Linkurious Enterprise authentication with an OpenID Connect provider, you need to obtain the following parameters from the provider:

Example access.oauth2 configuration with any OpenID Connect provider:

"access": {
  // [...]
  "oauth2": {
    "enabled": true,
    "provider": "openidconnect",
    "authorizationURL": "https://accounts.google.com/o/oauth2/v2/auth",
    "tokenURL": "https://www.googleapis.com/oauth2/v4/token",
    "clientID": "XXXXXXXXXX-XXXXXXXXXXXXXXXX.apps.googleusercontent.com",
    "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXX"
  }
}

OAuth2 redirect URL

The OAuth2 redirect URL of Linkurious Enterprise is the following: http(s)://HOST:PORT/api/auth/sso/return.

Group mapping in OIDC

To set up group mapping in OpenID Connect is necessary to specify additional configuration keys:

For example if you want to set up OIDC with Okta:

"access": {
  // [...]
  "oauth2": {
    "enabled": true,
    "provider": "openidconnect",
    "authorizationURL": "https://XXXXXXXXXX.oktapreview.com/oauth2/v1/authorize",
    "tokenURL": "https://XXXXXXXXXX.oktapreview.com/oauth2/v1/token",
    "clientID": "XXXXXXXXXXXXXXXXXXXXXXX",
    "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXX",
    "openidconnect": {
      "userinfoURL": "https://XXXXXXXXXX.oktapreview.com/oauth2/v1/userinfo",
      "scope": "openid profile email groups",
      "groupClaim": "groups"
    }
}

 Authentication: SSO with SAML2 / ADFS

Linkurious Enterprise supports any SAML2 compatible provider as external authentication providers.

Configuration

To set up Linkurious Enterprise authentication with a SAML2 provider, you need to obtain the following parameters from the provider:

groupAttribute is the attribute of the SAML response containing the array of groups a user belongs to.

emailAttribute is the attribute of the SAML response that should contain the email address if the NameID format of the SAML response is not already an email.

Example access.saml2 configuration with any SAML2 provider:

"access": {
  // [...]
  "saml2": {
    "enabled": true,
    "url": "https://example.com/adfs/ls",
    "identityProviderCertificate": "/Users/example/linkurious/saml.pem",
    "groupAttribute": "Groups"
  },
}

Assertion consumer service

To complete the login process, you need to configure your identity provider to return the SAML response to Linkurious Enterprise at the following URL: http(s)://HOST:PORT/api/auth/sso/return.

Please note that encrypted assertions are not supported by Linkurious Enterprise.

ADFS Configuration

In particular, ADFS (Active Directory Federation Services) is a SAML2 provider that offers Single-Sign-On towards an Active Directory service, see more on Microsoft documentation.

To set up Linkurious Enterprise authentication with ADFS, Linkurious Enterprise has to be configured as a Relying Party Trust in ADFS (see how to configure the ADFS on the Microsoft documentation).

To set up group mapping, the list of groups associated to a user should be passed in the SAML2 response. See how to configure a claim for the groups on the Microsoft documentation.

 Authentication: Configuration

The authentication is configured within the access configuration key in the configuration file (linkurious/data/config/production.json):

Local vs. external authentication

To access Linkurious Enterprise when authRequired is true, users need accounts in Linkurious Enterprise. Administrators can create accounts directly in Linkurious Enterprise (see how to create users) or rely on an external authentication service.

Linkurious Enterprise supports the following external authentication services:

If your company uses an authentication service that Linkurious Enterprise does not support yet, please get in touch.

When opting for external authentication, it is recommended to have at least one local administrator account configured as a fallback in case the third party authentication provider is unavailable.

Disabling authentication

Authentication can be disabled by setting authRequired to false. When user authentication is disabled, all actions are performed under the special account named Unique User. The unique user has unrestricted access and does not require a password, so anyone can access the platform.

We strongly discourage you to disable user authentication, as this leaves your data accessible to anyone. This option should only be considered in the case of a standalone local installation for evaluation or demonstration purposes.

Enabling authentication

If local authentication is disabled, it can be enabled from Linkurious Enterprise user interface.

Once local authentication is enabled, users need an account to access Linkurious Enterprise. Administrators can create accounts directly in Linkurious Enterprise (see how to create users).

To enable authentication use the Web user interface via the Admin > Users menu:

Enabling authentication, step 1

The following screen will be prompted if authentication is disabled. Click Enable Authentication.

Enabling authentication, step 2

Create an admin account and click Save and enable.

Enabling authentication, step 3

Floating licenses

When access.floatingLicenses is defined, this is the behavior when a new user tries to log into the server while it is full:

 Access control: Managing users

User management page

This page is accessed via Admin > Users & Groups in the main menu. The page lists all users, both local and external.

User management operations available to Administrators are the following:

Listing users

Deleting a user and transferring their shared assets

When deleting a user who has shared assets, admins are able to transfer these to an eligible user. Shared assets are visualisations, widgets, queries, custom actions or alerts which have been shared with at least one other user. Eligible users, are all admins and users who share the same access right group(s) as the to-be-deleted user.

Deleting users

Below, useful information on the characteristics of each asset and their sharing options can be found:

Assigning users to groups

In order to be able to access Linkurious Enterprise, users need to be assigned to at least 1 user group.

A user can be assigned to:

Group assignment can be done either while creating or editing a user account.

Editing a user

Assigning users to groups can be automated if you are using external authentication, using group mapping.

 Access control: Managing groups

Role-based access control

Linkurious Enterprise relies on a role-based access control model:

Group management page

This page is accessed via Admin > Users & Groups in the main menu.

This page lists:

Group management operations available to the Administrators are the following:

Listing groups

Built-in groups rights

Creating a group

Creating a group is a 2-step process:

  1. "General & Admin rights": define access-rights on the features.
  2. "Access-rights": define access-rights on the data.

Editing a group

General & Admin rights

Features access-rights description

Queries access-rights

Custom actions access-rights

Alert access-rights


IMPORTANT

Please note that users who don’t have access to specific node categories and/ or edge types (see Queries access rights) can still create/access queries that return such information and display it in the case columns/attributes. They will not see the node and/ or edges in the visualization/case view but the data will still be displayed in the alert columns.


Admin access-rights

Users and groups

Data-source

Resource management

Access-rights with multiple groups

For users that belong to multiple groups, access-rights are cumulative. In other words, a user can do something if at least one of their groups allows them to do it.

For example if user belongs to 2 groups: one having No access and the other Process Alerts for the Alert rights, then they have the right to Process Alerts because one of their groups allows them to do so.

Access-rights on the data

There are 2 available options. You can read about them in their dedicated sections:

 Access control: Standard access-rights

Definition of Standard access rights

standard-access-rights-panel

Example

As a result: user Foo has EDIT access on node-category CONTRACT

 Access control: Property-key access-rights

Enabling Property-key access rights

property-key-access-rights-switch

Defining property-key access rights

To define property-key access rights, the administrator needs to create (or edit) a custom group: after the access-rights configuration page, with the property-key access rights feature switched on, a second panel will be displayed.

property-key-access-rights-panel

From here:

Example

As a result, user Foo has:

 Guest mode: Guest mode

What is the Guest mode

The Guest mode is a way to share graphs with people who do not have an account on Linkurious Enterprise.

Key characteristics:

Standard user interface: Standard waorkspace

Guest mode user interface: Guest user workspace

Enabling the Guest mode

By default, the Guest mode is disabled. Enabling the Guest mode is done on a per-source basis so that you can manage the access rights associated with the Guest mode at the source level.

Enabling it is a 3-steps process:

  1. In the Configuration screen (Menu > Admin > Global configuration), enable the Guest mode
  2. A new user is created in the user list with the email guest@linkurio.us. By default, it is not associated with any user group. Assign the Guest user to the Read-Only group, or any custom group if you need to restrict its rights (see the security warnings below).
  3. Repeat step 2 for each source on which you want to enable the Guest mode as its access rights are managed on a source per source basis.

Once enabled, the Guest mode is available at http://your-domain.com/guest (replace your-domain.com with the actual host and port of your server).

Configuring the Guest mode

By default, guest users won't be allowed to search, export and use the design, filter and edge grouping panel.

If you want to allow guest users to use these features, you can go to the Configuration screen (Menu > Admin > Global configuration) and, under the Guest Mode configuration, change the following values:

Security warnings

All people who have access to /guest will be able to browse the whole database (in read-only mode), even if nobody has explicitly shared a specific visualization with them. You may want to check who has access to /guest before enabling the Guest mode.

If you have assigned the Guest user to the Read Only built-in user group, all node categories and edge types will be available to see by the people who can access /guest. If the database contains sensitive data, you should create a custom group with limited rights on the data and assign the Guest user to that group.

Even if the Guest user is assigned to a group that has "Write" or "Delete" permissions, Guest mode users will not be able to write or edit data.

When initialized with a visualization, the Guest mode allows the user to expand the graph beyond the content of that visualization. Consider restricting the Guest user access rights if that is an issue.

Populating the Guest mode workspace

Accessing /guest directly will return an empty workspace.

Using parameters in the URL you can populate the Guest mode workspace with:

The Guest user sees the current state of a visualization. Any change to a visualization from an authenticated user will be automatically applied to the public link shared to the Guest user.

 Data Schema

What is the schema?

Linkurious Enterprise uses a data schema to deliver some of its features. However, most graph databases are schema-less. As a consequence, Linkurious Enterprise automatically detects the data schema from each data-source. The automatically detected schema is:

The schema can be extended manually. An administrator can:

The schema has two modes:

The Partial mode is flexible and incremental, whereas the Strict schema is stable and normative. Therefore the Partial mode is a better fit in early projects when the data schema is poised to change. The Strict mode is a better fit for production-ready projects that require a more controlled environment.

IMPORTANT

Statements made in the schema DO NOT alter the data in the database:

Accessing the schema

The schema can be reached through the Admin menu.

Overview

Structure

The schema is presented as two columns:

Switch search/visibility for categories, types and properties

The "eye" icon next to node categories, edge types and properties allows to switch the visibility to View & Search, Only view or No access. See the dedicated section for more details.

Create node-categories, edge-types and properties manually

The schema may be incomplete. Or you may want to add a category, type or property that is not yet in the data. You can create them manually through action links available at the bottom the list.

Remove nodes or edges from search results

Some node-categories or edge-types are unlikely to be searched for. As a consequence they pollute the search results.

You can disable the search by clicking on the "eye" icon and select Only view option. The nodes or the edges will then be not searchable but stay visible.

You can also remove them from the search by selecting No access option. The nodes or the edges will then be not searchable and not visible.

The "eye" icon will be updated by the selected search/visibility option

Switch to Strict mode

The button "Switch to strict mode" allows you to switch to a strict mode. See the dedicated section for more information.

Reset the schema

If the schema has changed a lot and you want to start fresh, it is possible to "Reset the schema": this will remove any schema declaration, and trigger a new sampling of the database.

Add more sampling

If the schema is too incomplete (due for example to a recent import in the graph database with lots of new node categories / edge types / properties) it's possible to launch manually another sampling round to detect the missing categories / types / properties, using the Re-launch detection option in the Options menu.

Sample size

The sampling of the database will scan only part of the database. The larger the sample, the more accurate but the longer the detection.

The default setting for the sampling size is 500 nodes per node category, 500 edges per edge type. You can change this by editing the value of sampledItemsPerType in the Advanced section of the configuration (via Admin > Global configuration).

Fix search inconsistencies

When Linkurious indexes your data, it will only index nodes and edges whose categories and properties are marked as searchable.

On the Linkurious interface to set a category/ property to be searchable, you need to select the (view & search) option, However if you want a category/ property to be non-searchable you need to select the (view-only) option.

If for example in the schema I declare:

In search, I will be able to search by "last_name" but not by "first_name". In case, I want to enable search also by "first_name", I will need to mark this property as searchable, however if I do this after the indexation has occurred, I will see a warning in the schema configuration page telling me that there are inconsistencies I will need to solve in order to search for some properties. In order to fix the issue, a full indexation is required.

In case a property has been changed from searchable to visible, another information is shown, telling us that, the current search index is not optimized, which means there are more properties indexed than what are really needed to search. Running a full indexation should optimize the search index.

 Data Schema: Property types

The type of a property can be set by clicking on the "Set a type" button next to a property's name. A popup allows you to choose a type.

Once a property type has been set, the type is displayed next to the property name, and it is possible to change it using the "Edit" link.

IMPORTANT

Setting a property type in Linkurious Enterprise will not change the type of the corresponding values in the graph database. The consequences are explained below for each property type.

Property types

String

Settings

Setting a property type as String does not require any additional information:

Consequences

Once a property type has been set as a String, all values for that property are processed as a String.

In the Workspace Filter panel:

Number

Settings

Setting a property type as Number does not require any additional information:

Consequences

Once a property type has been set as a Number, values for that property fall into 2 categories:

In the Workspace Property panel, invalid values are displayed as string with a warning.

In the Workspace Filter panel:

When editing or creating a node/edge, properties set as Number can only accept a valid number.

Enum

Settings

Setting a property type as "Enum" requires to enter a list of authorized values:

Consequences

Once a property type has been set as Enum, values for that property fall into 2 categories:

In the Workspace Property panel, invalid values are displayed as string with a warning.

In the Workspace Filter panel:

When editing or creating a node/edge, the user pick the value of an Enum property from the list of the authorized values.

True/False

Settings

Setting a property type as True/false does not require any additional information:

Consequences

Once a property type has been set as a True/false, values for that property fall into 2 categories:

In the Workspace Property panel, invalid values are displayed as string with a warning.

In the Workspace Filter panel:

When editing or creating a node/edge, the user picks the value of a True/false property from a list containing "true" and "false".

Date

Settings

Setting a property type as Date requires to select the storage format of the date in the graph database:

Consequences

Once a property type has been set as Date, values for that property fall into 2 categories:

In the Workspace Property panel:

Anywhere a date value is displayed (including the Property panel):

In the Workspace Filter panel:

When editing or creating a node/edge, the user picks the value of a Date property from a Date picker.

Date-time

Settings

Setting a property type as Datetime requires to select the storage format of the date in the graph database:

In case the Date-time is stored as Native type:

Consequences

Once a property type has been set as Datetime, values for that property fall into 2 categories:

In the Workspace Property panel:

Anywhere a date value is displayed (including the Property panel):

In the Workspace Filter panel:

When editing or creating a node/edge, the user picks the value of a Datetime property from a Date picker.

Currency

Settings

Setting a property type as Currency requires to select the currency symbol and the display format of values in Linkurious Enterprise:

Consequences

Once a property type has been set as Currency, values for that property fall into 2 categories:

In the Workspace Property panel, invalid values are displayed as string with a warning.

In the Workspace, displayed currency values are formatted according to their property type configuration.

In the Workspace Filter panel:

When editing or creating a node/edge, properties set as Currency can only accept a valid number.

Mandatory properties

Each property can be set as "Mandatory" by clicking the corresponding checkbox in the property type popup.

Consequences of making a property mandatory:

In the Workspace Property panel:

When editing or creating a node/edge, the value of a mandatory property cannot be empty.

Property type conflict

When nodes have multiple categories, it is possible that a property can be given 2 different types. For example:

When such conflicts arise:

 Data Schema: Hiding data

Switching search/visibility options for node-categories and edge-types

The schema allows to switch the search/visibility options for node-categories and edge-types by clicking on the "eye" icon next to the category/type name.

Node-categories and edge-types search option can be set to "Search & view", "View only" or "No access"

Switching the visibility off of a node-category (or an edge-type) can be useful when some data is stored in the database for technical reasons but is useless for the users.

Switching a node-category (or an edge-type) to "Only view" will make them not searchable, but they can still appear in the visualisation as result of a query or of a graph expansion.

Switching a node-category (or an edge-type) to "No access" is equivalent to setting it to the "No Access" access right for all existing and future User Groups. Nobody will have access to this category / type.

When switching a node-category (or an edge-type) to "No access", a warning is displayed, since it may be used in some existing visualizations, and may impact users.

Switching properties search options

Switching a property search options can be done by clicking on the "eye" icon next to the property name.

Properties can be hidden from all users by switching them to "No access". A "No access" property:

Properties can be only visible and not searchable by switching them to "Only view". A "Only view" property:

 Data Schema: Strict mode

Strict editing / creation templates

Contrary to the "partial mode", when in "strict mode", you cannot deviate from the data schema when creating or editing a node or an edge.

More specifically, since all properties are typed, you cannot enter a value that is inconsistent with the schema or add arbitrary properties to nodes and edges.

A property must be declared in the schema first, before being available to users.

Switching to "strict mode"

The schema can be switched to "strict mode" by clicking on the "Switch to strict mode" button.

The "strict mode" requires to have types declared for all properties. As a consequence, when enabling "strict mode", all properties that do not have a type are switched to No access.

When switching to "strict mode", a warning is displayed with the list of properties that are being automatically switched to No access.

Changing the schema in "strict mode"

A schema in "strict mode" cannot evolve without an explicit action from the administrator. That means that any node-category, edge-type or property that would be detected after switching to "strict mode" would be added to the schema but be switched to No access by default.

A schema administrator can add new node-categories, edge-types or properties manually.

A schema in "strict mode" should be stable, so it is non-editable by default. To enable schema edition, the schema administrator needs to click on the corresponding toggle button.

 Alerts

Introduction

Alerts is Linkurious Enterprise' response to the need behind automating pattern detection through a rule-based system. Imagine there's a pattern on a datasource that repeats itself multiple times. Instead of manually detecting each occurrence of the said pattern, users can delegate this to the system. With the use of alerts, Linkurious Enterprise is responsible for automatically detecting the pattern and consequently creating cases based on it.

Automated detection of patterns in the graph database

More information on how to set up and use alerts can be found in the user documentation.

The next section walks you through how to configure the feature.

Feature support

Alerts are currently supported with the following graph vendors:

If you are using a different graph vendor, please get in touch.

 Alerts: Configuration

How to enable, disable and customise alerts?

Alerts can be configured and customised on the Global Configuration page that can be accessed under the Admin menu.

The following

Example of alerts configuration:

alerts: {
  "enabled": true,
  "maxMatchesLimit": 5000,
  "maxRuntimeLimit": 600000
}

 Email Notifications

What are email notifications?

Linkurious Enterprise supports email notifications for the following events, when they are correctly configured by admins.

 Email Notifications: Configuration

To enable, disable and customise the email notifications go to Admin > Global configuration.

The following options are available in the email configuration key:

Example of email configuration

{
  "alertNotifications": true,
  "newCasesDigestNotificationFrequency": "0 0 9 * * ?",
  "caseAssignmentNotificationFrequency": "*/10 * * * *",
  "caseMentionNotificationFrequency": "*/10 * * * *",
  "visualizationNotifications": true,
  "visualizationMentionNotificationFrequency": "* * * * *",
  "fromEmail": "john@myCompany.com",
  "mailer": {
    "type": "smtp",
    "host": "127.0.0.1",
    "port": 25,
    "ssl": false,
    "allowSelfSigned": false,
    "auth": {
      "user": "user@serviceProvider.com",
      "password": "password"
    }
  }
}

 Visualizations appearance

Linkurious Enterprise allows you to modify the visualizations appearence by modifying the ogma.options settings.

To edit the Ogma settings, you can either use the Web user-interface or edit the configuration file located at linkurious/data/config/production.json.

Example configuration:

{
  "renderer": "webgl",
  "options": {
    "styles": {
      "node": {
        "nodeRadius": 5,
        "shape": "circle",
        "text": {
          "minVisibleSize": 24,
          "maxLineLength": 35,
          "backgroundColor": null,
          "font": "roboto",
          "color": "#000",
          "size": 14,
          "maxTextLength": 60
        }
      },
      "edge": {
        "edgeWidth": 1,
        "shape": "arrow",
        "text": {
          "minVisibleSize": 4,
          "maxLineLength": 35,
          "backgroundColor": null,
          "font": "roboto",
          "color": "#000",
          "size": 14,
          "maxTextLength": 60
        }
      }
    },
    "interactions": {
      "zoom": {
        "modifier": 1.382
      },
      "pan": {
      },
      "rotation": {
        "enabled": false
      }
    },
    "backgroundColor": "rgba(240, 240, 240, 0)"
  }
}

Supported ogma.options settings are available here.

In addition to what you find in the Ogma documentation, Linkurious Enterprise allows the following extra configuration keys:

 Visualizations appearance: Default styles

In Linkurious Enterprise you can customize the default visual aspect of nodes, edges, and edge groups for new visualizations. Your users can then jump head first into the exploration of their data.

Styles can be configured individually by each user using the Design panel. Default values can be configured for all users by an administrator.

Styles belong to one particular data-source. To set the default styles of a data-source, you have two options:

By default, every node category has a pre-assigned color.

Inside Default Styles, the nodes, edges, and edgeGroup sections define the default styles for nodes, edges, and edge groups respectively.

A style rule has the following elements:

All grouped edges of a data-source are styled with the same configuration. If we want to customize their style we need to specify directly the color, shape, and width within the apposite section (see the Style edge groups section for details). In this case the Selector is not needed.

The input field is an array containing a sequence of strings identifying the path to an item in the JSON representation of a visualization object (node or relationship). Supported paths are:

For example:

{
  "index": 3,
  "itemType": "COMPANY",
  "type": "is",
  "input": ["properties", "name"],
  "value": "linkurious",
  "style": {
    "color": "blue"
  }
}

The above rule will apply the style {"color": "blue"} to all nodes with category "COMPANY" where the name is "linkurious".

{
  "index": 4,
  "type": "range",
  "itemType": "COMPANY",
  "input": ["statistics", "degree"],
  "value": {
    ">": 20
  },
  "style": {
    "size": "150%"
  }
},
{
  "index": 5,
  "type": "novalue",
  "itemType": "COMPANY",
  "input": ["statistics", "degree"],
  "style": {
    "size": "200%"
  }
}

The above rule will apply the style {"size": "150%"} to all nodes with category "COMPANY" that are connected to more that 20 other nodes and the style {"size": "200%"} to all supernodes with category "COMPANY".

index has to be unique. It is currently required for technical reasons. This will be made more user-friendly in future releases.

Selectors

The selector is used to specify to which items the style is applied to. For example, you can configure all the "COMPANY" founded more than 12 years ago to have a particular style. To do so, we use a style rule with a range type and with value:

{
  ">": 12
}

The overall style rule will look like the following (assuming we want to color the nodes in red):

{
  "index": 3,
  "type": "range",
  "itemType": "COMPANY",
  "input": ["properties", "age"],
  "value": {
    ">": 12
  },
  "style": {
    "color": "red"
  }
}

For range queries, you can use one or more among the following operators: >, <, >=, <=.

Supported selectors

In addition to type, input, and value, you must always specify itemType to filter by node category or edge type except if type is any.

Styles

Colors

Set under the style property key an object with one key, color, e.g:

"style": {
  "color": "blue" // or "#0000FF", "rgba(0, 0, 255, 1)"
}
"style": {
  "color": {
    "type": "auto", 
    "input": ["properties", "propertyName"]
  }
}

The color style for nodes, edges, and edge groups has the same format.

Sizes

For nodes, set under the style property key an object with one key, size, e.g:

"style": {
  "size": "220%"
}

For edges, it is quite similar: set under the style property key an object with one key, width, e.g:

"style": {
  "width": "220%"
}

Dynamic sizing

Similar to setting the size manually, it is also possible to set a dynamic sizing rule based on a property, e.g:

"style": {
  "size": {
    "type": "autoRange",
    "input": ["properties", "age"],
    "scale": "linear"
  }
}

scale attribute can take two values:

If scale is not defined, linear is applied by default.

In the example above, all selected nodes and edges are scaled linearly based on the property age.

Nodes will be sized between the range of 50% (the smallest) and 500% (the biggest).

Edges will be sized between the range of 50% (the smallest) and 200% (the biggest).

Shapes

Set under the style property key an object with one key, shape.

For nodes, set the shape of the node. Possible values are: "circle" (default), "cross", "diamond", "pentagon", "equilateral", "square" or "star".

"style": {
  "shape": "star" // "circle", "cross", "diamond", "pentagon", "equilateral", "square" or "star"
}

For edges and edge groups, set the shape of the edge. Possible values are: "arrow" (default), "dashed", "dotted", "line" or "tapered".

"style": {
  "shape": "dotted" // "arrow", "dashed", "dotted", "line" or "tapered"
}

Custom node icons

You can host your custom icons in Linkurious Enterprise itself by storing them in the folder located in linkurious/data/server/customFiles/icons.

Users will find them in the Design panel:

If you want to edit style rules manually, the style rules to access these images would look like:

"style": {
  "image": {
    "url": "/icons/company.png"
  }
}

Advanced custom node icons

Nodes can be filled with an image if one of their property is a URL to an image. Available image formats are PNG, JPG, GIF, and TIFF.

The following style will set an image:

Example:

"style": {
  "image": {
    "url": "http://example.com/img/company.png"
  }
}

To assign dynamically an image to a node, for example if the logo is stored in a node property called "logo_url", you just need to set the following style:

"style": {
  "image": {
    "url": {
      "type": "data",
      "path": [
       "properties",
       "logo_url" // change it to the property key where your image urls are stored
      ]
    }
  }
}

If you want to resize your images in a node you can you use the additional properties scale, fit and tile, e.g.:

"style": {
  "image": {
    "url": ... // one of the above
    "scale": 0.8, // scale the image in the node
    "fit": false, // if true, fill the node with the image
    "tile": false // if true, repeat the image to fill the node
  }
}

Style edge groups

Within the edgeGroup property key, we can directly set the color, shape, and width that will apply to all grouped edges of a data-source.

"edgeGroup": {
  "color": "red",
  "shape": "dashed", // "arrow", "dashed", "dotted", "line" or "tapered"
  "width": "320%"
 }

Editing the default styles in the data-source page automatically changes captions for existing users for newly created visualizations. These changes are not applied to existing visualizations.

 Visualizations appearance: Default captions

In Linkurious Enterprise, node and edge captions are the texts displayed next to a node or an edge.

Captions, as for Styles, can be configured individually by each user using the Design panel.

As for Styles, an administrator can set the default values from its own workspace or by editing them from the data-source configuration page.

Inside Default Captions, the nodes and the edges sections define the default captions for nodes and edges respectively.

Each of these two sections is an object where the keys are node categories or edge types and the values are objects with the following keys:

Example:

"defaultCaptions": {
  "nodes": {
    "CITY": {
      "active": true,
      "displayName": true,
      "properties": ["name"]
    },
    "COMPANY": {
      "active": true,
      "displayName": false,
      "properties": ["name", "country"]
    }
  },
  "edges": {
    "INVESTED_IN": {
      "active": true,
      "displayName": true,
      "properties": ["funded_month"]
    }
  }
}

Editing the default captions in the data-source page does automatically change captions for existing users for newly created visualizations. Existing visualizations are not touched.

 Visualizations appearance: Default properties order

In Linkurious Enterprise, you can configure the properties order per data-source that will be displayed in the following:

You will need “Manage data-source default styles” access right or be an administrator to edit them in the data-source settings page.

To do so, you will need to add an object with the properties that you want to see in the top of the list for each category and/or edge type.

Example:

{
  "node": {
    "SENDER": ["SendId", "FullName"],
    "BENEFICIARY": ["BenId", "Country"]
  },
  "edge": {
    "TRANSACTION": ["Amount", "Currency"]
  }
}

What happens to the properties that are not defined in JSON?

Properties not defined in JSON will remain alphabetically-ordered, and will appear after the defined properties.

What happens when a node has multiple categories?

The category order is always alphabetical and is case-sensitive:

 Visualizations appearance: Geographic tiles

Linkurious Enterprise supports displaying nodes with geographic coordinates (latitude and longitude) on a map.

Users are able to switch a visualization to geo mode when geographic coordinates are available on at least one node of the visualization. The map tiles layer used in geo mode can be customized by users.

By default, Linkurious Enterprise comes pre-configured with several geographical tile layers. Administrators change the available geographical tile layers by editing the leaflet section in the configuration file (linkurious/data/config/production.json). The leaflet key is an array of geographical tile layer configurations. Each entry has the following attributes:

Geographical tile layers and overlay layers can be found at https://leaflet-extras.github.io/leaflet-providers/preview/.

Example configuration:

"leaflet": [
  {
    "overlay": true,
    "name": "Stamen Toner Lines",
    "thumbnail": "",
    "urlTemplate": "http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lines/{z}/{x}/{y}.png",
    "attribution": "Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>",
    "subdomains": "abcd",
    "id": null,
    "accessToken": null,
    "minZoom": 2,
    "maxZoom": 20
  },
  {
    "name": "MapBox Streets",
    "thumbnail": "/assets/img/MapBox_Streets.png",
    "urlTemplate": "https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}",
    "attribution": "Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery &copy <a href="http://mapbox.com">Mapbox</a>",
    "subdomains": null,
    "id": "mapbox.streets",
    "accessToken": "pk.eyJ1Ijoic2hleW1hbm4iLCJhIjoiY2lqNGZmanhpMDAxaHc4bTNhZGFrcHZleiJ9.VliJNQs7QBK5e5ZmYl9RTw",
    "minZoom": 2,
    "maxZoom": 20
  }
]

 Audit trail

Audit trails are detailed logs about the operations performed by your users on your graph databases, when using the search bar in the visualization workspace and when using Linkurious Enterprise plugins. Because they have the potential to take up a substantial amount of memory depending on the number of users and the operations performed, they are disabled by default.

Configuration

Audit trails can be enabled and configured in linkurious/data/config/production.json. They are found under the auditTrail key, which contains the following options:

Performances

Enabling the audit trail can impact performances negatively.

Here are options to consider to improve performances:

 Audit trail: Log format

The audit trail log files contain JSON lines in JSONL format.

You can easily bind a log-management system like Logstash to interpret them.

Each log line contains the following information when the action is a graph request:

Each log line contains the following information when the action is a plugin request:

Lines are written to the log as follows:

{"mode":"WRITE","date":"2017-01-09T17:34:07.446Z","user":"simpleUser@example.com","sourceKey":"e8890b53","action":"createEdge","params":{"createInfo":{"source":4328,"target":4332,"type":"ACTED_IN","data":{"tata":"toto"}}},"result":{"edge":{"id":5958,"data":{"tata":"toto"},"type":"ACTED_IN","source":4328,"target":4332}}}
{"mode":"READ","date":"2017-01-09T17:34:07.478Z","user":"simpleUser@example.com","sourceKey":"e8890b53","action":"getNode","params":{"id":4330},"result":{"node":{"id":4330,"data":{"tagline":"Welcome to the Real World","title":"The Matrix","released":1999,"nodeNoIndexProp":"foo"},"categories":["Movie","TheMatrix"]}}}
{"mode":"READ","date":"2017-01-09T17:34:07.507Z","user":"simpleUser@example.com","sourceKey":"e8890b53","action":"getEdge","params":{"edgeId":5950},"result":{"edge":{"id":5950,"data":{"edgeNoIndexProp":"bar","roles":["Neo"]},"type":"ACTED_IN","source":4313,"target":4330}}}
{"mode":"READ WRITE","date":"2017-01-09T17:34:12.253Z","user":"user@linkurio.us","sourceKey":"e8890b53","action":"rawQuery","params":{"query":"MATCH (n:Person) RETURN n","dialect":"cypher"},"result":{"nodes":[{"id":4357,"data":{"born":1967,"name":"Andy Wachowski"},"categories":["Person"],"edges":[]},{"id":4359,"data":{"born":1967,"name":"Carrie-Anne Moss"},"categories":["Person"],"edges":[]},{"id":4360,"data":{"born":1954,"name":"James Cameron"},"categories":["Person"],"edges":[]},{"id":4361,"data":{"born":1964,"name":"Keanu Reeves"},"categories":["Person"],"edges":[]},{"id":4362,"data":{"born":1965,"name":"Lana Wachowski"},"categories":["Person"],"edges":[]},{"id":4364,"data":{"born":1901,"name":"Phillip Cameron"},"categories":["Person"],"edges":[]},{"id":4365,"data":{"born":1976,"name":"Sam Worthington"},"categories":["Person"],"edges":[]}]}}
{"mode":"PLUGIN","date":"2022-04-21T12:37:40.339Z","user":"user@linkurio.us","action":"pluginRequest","params":{"pluginName":"data-table","requestMethod":"POST","requestUrl":"/plugins/table/api/runQueryByIDPlugin","requestBody":"{\"query\":{\"id\":1,\"sourceKey\":\"d80aefa8\",\"name\":\"test\",\"content\":\"match (n:TEST) return n\",\"dialect\":\"cypher\",\"description\":\"\",\"sharing\":\"private\",\"type\":\"static\",\"write\":false,\"createdAt\":\"2022-04-21T12:02:55.124Z\",\"updatedAt\":\"2022-04-21T12:02:55.124Z\",\"builtin\":false,\"right\":\"owner\",\"owner\":{\"name\":\"Unique user\",\"email\":\"user@linkurio.us\"}},\"queryParams\":{\"global\":{\"queryId\":\"1\",\"sourceKey\":\"d80aefa8\"},\"templateFields\":{}}}"},"result":""}

Each line is a JSON objects in the following format (with logResult set to true):

{
  "mode": "WRITE",
  "date": "2017-01-09T17:34:07.446Z",
  "user": "simpleUser@example.com",
  "sourceKey": "e8890b53",
  "action": "createEdge",
  "params": {"createInfo":{"source":4328,"target":4332,"type":"ACTED_IN","data":{"tata":"toto"}}},
  "result": {"edge":{"id":5958,"data":{"foo":"bar"},"type":"BAZ","source":4328,"target":4332}}
}

The params key contains the parameters of the operation being performed. In this case, the user has run as createEdge action; params then contains the source and target IDs of the edge, as well as the edge type and a data key which holds the properties set on that edge.

result contains a JSON representation of the edge produced by the action. As can be seen, there is a substantial amount of duplication between the information in params and in data. This may not be a consideration with operations on single nodes, but with larger collections can mean that log size increases substantially. Consider the example below:

{
  "mode": "READ WRITE",
  "date": "2017-01-09T17:34:12.289Z",
  "user": "user@linkurio.us",
  "sourceKey": "e8890b53",
  "action": "rawQuery",
  "params": {
    "query": "MATCH (n1)-[r:DIRECTED]->(n2) RETURN n1, r",
    "dialect": "cypher"
  },
  "result":{"nodes":[{"id":4357,"data":{"born":1967,"name":"Andy Wachowski"},"categories":["Person"],"edges":[{"id":6009,"data":{},"type":"DIRECTED","source":4357,"target":4366},{"id":6010,"data":{},"type":"DIRECTED","source":4357,"target":4367},{"id":6011,"data":{},"type":"DIRECTED","source":4357,"target":4368}]},{"id":4358,"data":{"tagline":"Return to Pandora","title":"Avatar","released":1999},"categories":["Avatar","Movie"],"edges":[{"id":6034,"data":{},"type":"DIRECTED","source":4360,"target":4358}]},{"id":4360,"data":{"born":1954,"name":"James Cameron"},"categories":["Person"],"edges":[{"id":6034,"data":{},"type":"DIRECTED","source":4360,"target":4358}]},{"id":4362,"data":{"born":1965,"name":"Lana Wachowski"},"categories":["Person"],"edges":[{"id":6020,"data":{},"type":"DIRECTED","source":4362,"target":4366},{"id":6021,"data":{},"type":"DIRECTED","source":4362,"target":4367},{"id":6022,"data":{},"type":"DIRECTED","source":4362,"target":4368}]},{"id":4366,"data":{"tagline":"Welcome to the Real World","title":"The Matrix","released":1999,"nodeNoIndexProp":"foo"},"categories":["Movie","TheMatrix"],"edges":[{"id":6020,"data":{},"type":"DIRECTED","source":4362,"target":4366},{"id":6009,"data":{},"type":"DIRECTED","source":4357,"target":4366}]},{"id":4367,"data":{"tagline":"Free your mind","title":"The Matrix Reloaded","released":2003},"categories":["Movie","TheMatrixReloaded"],"edges":[{"id":6021,"data":{},"type":"DIRECTED","source":4362,"target":4367},{"id":6010,"data":{},"type":"DIRECTED","source":4357,"target":4367}]},{"id":4368,"data":{"tagline":"Everything that has a beginning has an end","title":"The Matrix Revolutions","released":2003},"categories":["Movie","TheMatrixRevolutions"],"edges":[{"id":6022,"data":{},"type":"DIRECTED","source":4362,"target":4368},{"id":6011,"data":{},"type":"DIRECTED","source":4357,"target":4368}]}]}
}

In this case, we've used a raw query to read nodes from the database without making any changes to them. The results of the query are returned to us in result, and include a substantial number of nodes and edges. To maximize the usefulness of audit trails and to minimize their footprint, it might be advisable to exclude unnecessary data, including passive queries such as these. Disabling logResult and setting mode to "w" (logging only operations which perform write operations to the database) is one strategy for accomplishing this.

 Webhooks

Webhooks

Thanks to webhooks, investigation workflow is improved by integrating the results of Linkurious-generated alerts into a third party case management system in real time. You can also subscribe to events to monitor usage of Linkurious’ alert system within a third party dashboarding tool.

Webhook events and payloads

You can create webhooks that subscribe to the events listed below.

To limit the number of HTTP requests made to your server, take care to subscribe only to the events you wish to use.

Case created

This event will be triggered when an alert create a new case.

{
  eventType: 'newCase',
  sourceKey: 'b4675b85',
  data: {
    alert: {
      id: 1,
      title: 'Example alert',
      description: 'This is an example'
    },
    case: {
      id: 2,
      createdAt: '2024-02-26T15:07:20.333Z',
      target: {
        nodes: ['1', '2', '3'],
        edges: ['4', '5']
      },
      url: 'https://example.com/alerts/1/case/2'
    }
  }
}

Case updated

This event will be triggered when a new match is found for an existing case.

{
  eventType: 'newMatch',
  sourceKey: 'b4675b85',
  data: {
    alert: {
      id: 1,
      title: 'Example alert',
      description: 'This is an example'
    },
    case: {
      id: 2,
      createdAt: '2024-02-26T15:07:20.333Z',
      updatedAt: '2024-02-27T13:00:49.020Z',
      target: {
        nodes: ['1', '2', '3'],
        edges: ['4', '5']
      },
      url: 'https://example.com/alerts/1/case/2'
    }
  }
}

Case status changed

This event will be triggered when a user will change the status of a case.

{
  eventType: 'caseStatusChange',
  sourceKey: 'b4675b85',
  data: {
    alert: {
      id: 1,
      title: 'Example alert',
      description: 'This is an example'
    },
    case: {
      id: 2,
      createdAt: '2024-02-26T15:07:20.333Z',
      updatedAt: '2024-02-27T14:09:30.207Z',
      status: "confirmed",
      url: 'https://example.com/alerts/1/case/2'
    },
    user: {
      id: 3,
      username: 'john.doe',
      email: 'john.doe@linkurious.com'
    },
    comment: 'The case is confirmed!'
  }
}

Managing webhooks

You can subscribe, unsubscribe and list the configured webhooks by using API.

Only users with the built-in Admin role can manage webhooks.

POST /api/admin/webhooks : Create a webhook. Webhooks can subscribe to one or more events for one or many datasources.

GET /api/admin/webhooks : Return the list of all webhooks.

DELETE /api/admin/webhooks/:webhookId : Delete a specific webhook.

You can find all details on these API in the Rest-client documentation.

Handling deliveries

To handle deliveries, you must configure a HTTP endpoint that can handle POST requests and answer with a 2xx status response. The body of the POST request contains the payload of the event subscribed.

You should ensure that your server uses an HTTPS connection.

In order to give the recipient endpoint the ability to authenticate hook deliveries, a secret is attached to each webhook. This secret is used to compute the HMAC hex digest of the delivery payload, using the SHA-256 hash function. This HMAC is attached in the X-Payload-HMAC HTTP header (see https://nodejs.org/api/crypto.html##class-hmac).

Troubleshooting

Two specific API are available for you to test and ensure that webhooks and your integration are correctly configured.

POST /api/admin/webhooks/:webhookId/ping : Trigger a ping pseudo-event on a given webhook (details here)

GET /api/admin/webhooks/:webhookId/deliveries : Return the list of the deliveries for a given webhook (details here)

 Observability

Metrics

Linkurious Enterprise can be monitored using Prometheus, which is an open source monitoring tool. When metrics are enabled, Linkurious Enterprise will provide an API endpoint on /metrics that can be scrapped by Prometheus.

Configuration

Metrics can be enabled and configured in linkurious/data/config/production.json. They are found under the metrics key, which contains the following options:

You will then need to configure Prometheus to scrap this endpoint. If you are not familiar with Prometheus, please refer to their "getting started" guide.

Dashboard

Once metrics are ingested by Prometheus, you could set up a dashboard using Grafana to visualize these metrics. An example Grafana dashboard is provided here.

This dashboard can be imported by following the official grafana documentation and using the link above.

Example data

As an illustration of the available metrics and data format, this is an example response from the /metrics API endpoint:

# HELP process_cpu_user_seconds_total Total user CPU time spent in seconds.
# TYPE process_cpu_user_seconds_total counter
process_cpu_user_seconds_total 82.296112

# HELP process_cpu_system_seconds_total Total system CPU time spent in seconds.
# TYPE process_cpu_system_seconds_total counter
process_cpu_system_seconds_total 30.634486

# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 112.930598

# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1693901797

# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 182259712

# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 11938127872

# HELP process_heap_bytes Process heap size in bytes.
# TYPE process_heap_bytes gauge
process_heap_bytes 246452224

# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 47

# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1048576

# HELP nodejs_eventloop_lag_seconds Lag of event loop in seconds.
# TYPE nodejs_eventloop_lag_seconds gauge
nodejs_eventloop_lag_seconds 0

# HELP nodejs_eventloop_lag_min_seconds The minimum recorded event loop delay.
# TYPE nodejs_eventloop_lag_min_seconds gauge
nodejs_eventloop_lag_min_seconds 0.006279168

# HELP nodejs_eventloop_lag_max_seconds The maximum recorded event loop delay.
# TYPE nodejs_eventloop_lag_max_seconds gauge
nodejs_eventloop_lag_max_seconds 58.988691455

# HELP nodejs_eventloop_lag_mean_seconds The mean of the recorded event loop delays.
# TYPE nodejs_eventloop_lag_mean_seconds gauge
nodejs_eventloop_lag_mean_seconds 0.010528417698386331

# HELP nodejs_eventloop_lag_stddev_seconds The standard deviation of the recorded event loop delays.
# TYPE nodejs_eventloop_lag_stddev_seconds gauge
nodejs_eventloop_lag_stddev_seconds 0.0949220590624985

# HELP nodejs_eventloop_lag_p50_seconds The 50th percentile of the recorded event loop delays.
# TYPE nodejs_eventloop_lag_p50_seconds gauge
nodejs_eventloop_lag_p50_seconds 0.010330111

# HELP nodejs_eventloop_lag_p90_seconds The 90th percentile of the recorded event loop delays.
# TYPE nodejs_eventloop_lag_p90_seconds gauge
nodejs_eventloop_lag_p90_seconds 0.010510335

# HELP nodejs_eventloop_lag_p99_seconds The 99th percentile of the recorded event loop delays.
# TYPE nodejs_eventloop_lag_p99_seconds gauge
nodejs_eventloop_lag_p99_seconds 0.011575295

# HELP nodejs_active_resources Number of active resources that are currently keeping the event loop alive, grouped by async resource type.
# TYPE nodejs_active_resources gauge
nodejs_active_resources{type="PipeWrap"} 12
nodejs_active_resources{type="ProcessWrap"} 10
nodejs_active_resources{type="TCPServerWrap"} 2
nodejs_active_resources{type="TCPSocketWrap"} 5
nodejs_active_resources{type="Timeout"} 11
nodejs_active_resources{type="Immediate"} 1

# HELP nodejs_active_resources_total Total number of active resources.
# TYPE nodejs_active_resources_total gauge
nodejs_active_resources_total 41

# HELP nodejs_active_handles Number of active libuv handles grouped by handle type. Every handle type is C++ class name.
# TYPE nodejs_active_handles gauge
nodejs_active_handles{type="Socket"} 7
nodejs_active_handles{type="Pipe"} 10
nodejs_active_handles{type="ChildProcess"} 10
nodejs_active_handles{type="Server"} 2

# HELP nodejs_active_handles_total Total number of active handles.
# TYPE nodejs_active_handles_total gauge
nodejs_active_handles_total 29

# HELP nodejs_active_requests Number of active libuv requests grouped by request type. Every request type is C++ class name.
# TYPE nodejs_active_requests gauge

# HELP nodejs_active_requests_total Total number of active requests.
# TYPE nodejs_active_requests_total gauge
nodejs_active_requests_total 0

# HELP nodejs_heap_size_total_bytes Process heap size from Node.js in bytes.
# TYPE nodejs_heap_size_total_bytes gauge
nodejs_heap_size_total_bytes 89440256

# HELP nodejs_heap_size_used_bytes Process heap size used from Node.js in bytes.
# TYPE nodejs_heap_size_used_bytes gauge
nodejs_heap_size_used_bytes 81652264

# HELP nodejs_external_memory_bytes Node.js external memory size in bytes.
# TYPE nodejs_external_memory_bytes gauge
nodejs_external_memory_bytes 5334109

# HELP nodejs_heap_space_size_total_bytes Process heap space size total from Node.js in bytes.
# TYPE nodejs_heap_space_size_total_bytes gauge
nodejs_heap_space_size_total_bytes{space="read_only"} 0
nodejs_heap_space_size_total_bytes{space="old"} 62533632
nodejs_heap_space_size_total_bytes{space="code"} 7024640
nodejs_heap_space_size_total_bytes{space="map"} 2891776
nodejs_heap_space_size_total_bytes{space="large_object"} 14950400
nodejs_heap_space_size_total_bytes{space="code_large_object"} 991232
nodejs_heap_space_size_total_bytes{space="new_large_object"} 0
nodejs_heap_space_size_total_bytes{space="new"} 1048576

# HELP nodejs_heap_space_size_used_bytes Process heap space size used from Node.js in bytes.
# TYPE nodejs_heap_space_size_used_bytes gauge
nodejs_heap_space_size_used_bytes{space="read_only"} 0
nodejs_heap_space_size_used_bytes{space="old"} 57058280
nodejs_heap_space_size_used_bytes{space="code"} 5979200
nodejs_heap_space_size_used_bytes{space="map"} 2025864
nodejs_heap_space_size_used_bytes{space="large_object"} 14768216
nodejs_heap_space_size_used_bytes{space="code_large_object"} 972544
nodejs_heap_space_size_used_bytes{space="new_large_object"} 0
nodejs_heap_space_size_used_bytes{space="new"} 861432

# HELP nodejs_heap_space_size_available_bytes Process heap space size available from Node.js in bytes.
# TYPE nodejs_heap_space_size_available_bytes gauge
nodejs_heap_space_size_available_bytes{space="read_only"} 0
nodejs_heap_space_size_available_bytes{space="old"} 4319168
nodejs_heap_space_size_available_bytes{space="code"} 603072
nodejs_heap_space_size_available_bytes{space="map"} 813112
nodejs_heap_space_size_available_bytes{space="large_object"} 0
nodejs_heap_space_size_available_bytes{space="code_large_object"} 0
nodejs_heap_space_size_available_bytes{space="new_large_object"} 1030976
nodejs_heap_space_size_available_bytes{space="new"} 169544

# HELP nodejs_version_info Node.js version info.
# TYPE nodejs_version_info gauge
nodejs_version_info{version="v18.16.1",major="18",minor="16",patch="1"} 1

# HELP nodejs_gc_duration_seconds Garbage collection duration by kind, one of major, minor, incremental or weakcb.
# TYPE nodejs_gc_duration_seconds histogram
nodejs_gc_duration_seconds_bucket{le="0.001",kind="minor"} 145
nodejs_gc_duration_seconds_bucket{le="0.01",kind="minor"} 553
nodejs_gc_duration_seconds_bucket{le="0.1",kind="minor"} 560
nodejs_gc_duration_seconds_bucket{le="1",kind="minor"} 560
nodejs_gc_duration_seconds_bucket{le="2",kind="minor"} 560
nodejs_gc_duration_seconds_bucket{le="5",kind="minor"} 560
nodejs_gc_duration_seconds_bucket{le="+Inf",kind="minor"} 560
nodejs_gc_duration_seconds_sum{kind="minor"} 0.9594195639983442
nodejs_gc_duration_seconds_count{kind="minor"} 560
nodejs_gc_duration_seconds_bucket{le="0.001",kind="incremental"} 28
nodejs_gc_duration_seconds_bucket{le="0.01",kind="incremental"} 34
nodejs_gc_duration_seconds_bucket{le="0.1",kind="incremental"} 35
nodejs_gc_duration_seconds_bucket{le="1",kind="incremental"} 35
nodejs_gc_duration_seconds_bucket{le="2",kind="incremental"} 35
nodejs_gc_duration_seconds_bucket{le="5",kind="incremental"} 35
nodejs_gc_duration_seconds_bucket{le="+Inf",kind="incremental"} 35
nodejs_gc_duration_seconds_sum{kind="incremental"} 0.027089656999247376
nodejs_gc_duration_seconds_count{kind="incremental"} 35
nodejs_gc_duration_seconds_bucket{le="0.001",kind="major"} 0
nodejs_gc_duration_seconds_bucket{le="0.01",kind="major"} 4
nodejs_gc_duration_seconds_bucket{le="0.1",kind="major"} 21
nodejs_gc_duration_seconds_bucket{le="1",kind="major"} 21
nodejs_gc_duration_seconds_bucket{le="2",kind="major"} 21
nodejs_gc_duration_seconds_bucket{le="5",kind="major"} 21
nodejs_gc_duration_seconds_bucket{le="+Inf",kind="major"} 21
nodejs_gc_duration_seconds_sum{kind="major"} 0.42418163500053924
nodejs_gc_duration_seconds_count{kind="major"} 21

# HELP http_request_duration_seconds duration histogram of http responses labeled with: status_code, method, path
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.003",status_code="304",method="GET",path="/"} 0
http_request_duration_seconds_bucket{le="0.03",status_code="304",method="GET",path="/"} 3
http_request_duration_seconds_bucket{le="0.1",status_code="304",method="GET",path="/"} 3
http_request_duration_seconds_bucket{le="0.3",status_code="304",method="GET",path="/"} 4
http_request_duration_seconds_bucket{le="1.5",status_code="304",method="GET",path="/"} 4
http_request_duration_seconds_bucket{le="10",status_code="304",method="GET",path="/"} 4
http_request_duration_seconds_bucket{le="+Inf",status_code="304",method="GET",path="/"} 4

# HELP up 1 = up, 0 = not up
# TYPE up gauge
up 1

 Plugins

What is a plugin?

A plugin is software running on top of Linkurious Enterprise extending its capabilities. For example, a plugin that adds the functionality of importing your data to Linkurious Enterprise via CSV files.

What is an official Linkurious Enterprise plugin?

Official plugins are plugins built, distributed, and maintained by Linkurious team. Customers and 3rd party developers can easily create their own plugins using our detailed Plugins Development Guide.

What are the currently available official Linkurious Enterprise Plugins?

How do I install plugins?

The preferred way is to perform the installation through the Plugin Manager web interface (by default accessible from /plugins/plugin-manager). It requires an admin account.

In case you need to perform a manual installation, you can proceed as follow:

Make sure to have write access to the Linkurious Enterprise installation folder of as well as an application admin account.

  1. Obtain the .lke file of the plugin you need to install, for official plugins you can download it from the Releases section of the plugin page
  2. Copy the .lke file to the following path <linkurious>/data/plugins
  3. From the Linkurious Enterprise dashboard, go to Admin -> Global configuration
  4. Scroll to the Plugins settings field
  5. Add a space at the end of the Plugins settings section
  6. Click "Save". This will restart all the plugins to apply the new configurations.

How do I automatically install official plugins?

If you want the system to automatically install official plugins, you can set the LKE_PLUGINS environment variable as an array of strings for every plugin to be deployed. The valid strings are available in the list of official plugins.

If you are using Docker, the environment variable needs to be set for the container.

If the variable is not defined, the system will consider the below as default (deploying the Plugin Manager and the Image Export plugins).

LKE_PLUGINS=["plugin-manager","image-export"]

The version that will be installed depends on your Linkurious Enterprise version. Be sure to keep the system up to date to have the latest version of the plugins installed.

How do I configure plugins?

  1. From the Linkurious Enterprise dashboard, go to Admin -> Global configuration
  2. Scroll to the Plugins settings field
  3. Find the name of your plugin in the Plugins settings section (if the plugin has never started before you will not find it, you can either add the configuration manually or start the plugin first)
  4. Add the relevant configurations, for official plugins you can find details in the plugin page
  5. Click "Save". This will restart all the plugins to apply the new configurations.

You can configure multiple instances of a single plugin by adding a new JSON object to the plugin's array.

Configuration keys supported by all the plugins:

Key Type Description Example      
basePath string (optional) A base path on which the plugin will be mounted. Defaults to the plugin name defined in the manifest. "my-path"
debugPort number (optional) A debug port on which to attach a debugger for the plugin NodeJS process. If not specified, the plugin won't be started in debug mode. 9230

The following example will deploy:

{
  "my-plugin": [
  ],
  "my-second-plugin": [
    {
      "basePath": "my-path"
    },
    {
      "basePath": "my-other-path",
    }
  ]
}

How do I uninstall plugins?

To completely uninstall a plugin from the system (i.e. all the deployed instances), you can either use the Plugin Manager or remove the file manually added through the manual installation.

After the above procedure, any configuration for to the removed plugin will be ignored by the system. If you are not foreseeing to reuse the plugin in the future, you may want to clear the related plugin's configurations to only keep active ones.

If you have deployed several instances of a plugin and want to uninstall some of them, edit the plugins configuration and remove the entries for the instances you want to remove.

What do I need to be able to use the plugin?

Once installed and configured, any Linkurious Enterprise authenticated user can use the plugin. Additional restrictions may be imposed by the plugin itself.

We recommend configuring a custom action in Linkurious Enterprise to avoid building the link to the plugin manually.

Are plugins compatible with all versions of Linkurious Enterprise?

Compatibility is mentioned on the download page of each plugin. You can easily identify that by looking at the minimal and maximal supported Linkurious Enterprise version.

What can I expect about maintenance and bug fixes?

If you are facing problems with a plugin follow the next steps:

If you are still facing problems, please get in touch with support while keeping this in mind:

 Deep link

Deep link

Using query-string parameters, you can create visualizations on the go to integrate Linkurious Enterprise in your workflow.

Sandbox

To open a visualization pre-filled with data, you need to use the /workspace/new URL.

Then, by adding query-string parameters, you can fill your visualization with a specific nodes & edges:

e.g. http://localhost:3000/workspace/new?populate=nodeId&item_id=45869

This URL will open a visualization containing the node with ID 45869.

Please find below the list of supported parameters.

Parameter Description Accepted values
key Key of the data-source. A valid source key (default is the first connected data source)
populate Describes how the sandbox should be populated. visualizationId, expandNodeId, nodeId, edgeId, queryId, searchNodes, searchEdges, pattern, caseId
item_id ID of the node, edge, query, pattern or visualization to load (required when populate is one of visualizationId, queryId, nodeId, edgeId, expandNodeId). The ID of the resource to load
case_id ID of alert case to load (required when populate is caseId). An existing alert case ID
search_query Search query to search for nodes or edges (required when populate is one of searchNodes or searchEdges). Any string of characters
search_fuzziness Search query fuzziness (when populate is one of searchNodes or searchEdges). Any number between 0 and 1 (default is 0.1)
pattern_query Pattern query to match nodes and/or edges (required when populate is pattern). Any valid Cypher or Gremlin query (depending of the datasource query language)
pattern_dialect Query dialect to use (required when populate is pattern). cypher or gremlin
query_parameters Template query parameters (required when populate is queryId and the query is a template). Any valid template query parameters in JSON format (e.g. {"param1": "abc", "param2": 123}
geo_mode Whether the sandbox should be opened with geo mode activated true or false (default is false)

Visualization

You can also open a visualization by using the /workspace/:id URL.

You can use specific parameters to customize it.

e.g. http://localhost:3000/workspace/5

This URL will open the visualization with ID 5.

Parameter Description Accepted values
id ID of the visualization. An existing visualization ID
geo_mode Whether the visualization should be opened with geo mode activated true or false (default is false)