Configuration
System Configuration
CARTA backend permissions
The user under which the CARTA controller is running (assumed to be carta) must be given permission to use sudo to start carta_backend processes as any authenticated user and stop running carta_backend processes belonging to authenticated users. We provide a kill script which is only able to kill processes matching the name carta_backend. This makes it possible to restrict what processes the carta user is permitted to kill:
#!/bin/bash
# This script is a safe way to allow a user to kill specific commands of other users via sudo
COMMAND_TO_MATCH="carta_backend"
# The backend is started with sudo, and there may be multiple nested sudo processes,
# so we recursively search for a child process with the correct name.
# Start with the PID that was passed in
PID=$1
while : ; do
# Get the command name of the process
COMMAND_OF_PID=`ps -p $PID -o comm=`
# If this is the backend process, try to kill it
if [ "$COMMAND_OF_PID" == "$COMMAND_TO_MATCH" ]; then
kill -9 $PID
exit $?
fi
# Otherwise look for a child
CHILD_PID=`pgrep -P $PID`
# If there's no child, exit with an error
if [ -z "${CHILD_PID}" ]; then
echo "Could not find child process named $COMMAND_TO_MATCH."
exit 1
fi
# Otherwise start over with the child process
PID=$CHILD_PID
done
To provide the carta user with these privileges, you must make modifications to the sudoers configuration. An example sudoers config is provided. This example allows the carta user to run carta_backend only as users belonging to a specific group (assumed to be carta-users), in order to deny access to unauthorized accounts:
# customise this file to fit your environment using visudo /etc/sudoers.d/carta_controller
# carta user can run the carta_backend command as any user in the carta-users group without entering password
carta ALL=(%carta-users) NOPASSWD:SETENV: /usr/bin/carta_backend
# carta user can run the kill script as any user in the carta-users group without entering password
carta ALL=(%carta-users) NOPASSWD: /usr/bin/carta-kill-script
Please ensure that the paths to the executables in this file match their install locations on your system (especially if you have installed multiple different versions of the backend or the controller).
Warning
Please only edit your sudoers configuration with visudo or equivalent.
Note
Older versions of sudo do not support the --preserve-env=VARIABLE argument. If your version of sudo is too old, set "preserveEnv" to false in your controller configuration, and add Defaults env_keep += "CARTA_AUTH_TOKEN" to your sudoers configuration.
Authentication
The controller signs and validates tokens with SSL keys. You can generate a private/public key pair in PEM format using openssl:
cd /etc/carta
openssl genrsa -out carta_private.pem 4096
openssl rsa -in carta_private.pem -outform PEM -pubout -out carta_public.pem
In addition to the keypair above for authenticating access tokens and refresh tokens, those using OIDC authentication require an additional symmetric encryption key. If you use the default encryption algorithm, you can again use openssl to generate the needed key:
openssl rand -base64 32 > /etc/carta/symm.key
PAM may be configured to use the host’s local UNIX user authentication, or to communicate with a local or remote LDAP server. If the UNIX module is used for authentication, the carta user must be given read-only access to /etc/shadow. This is not required if you use PAM’s LDAP module or the direct LDAP authentication method.
Nginx
We strongly suggest serving over HTTPS and redirecting HTTP traffic to HTTPS, especially if handling authentication internally. If you use nginx as a proxy, you can use this configuration example as a starting point to redirect incoming traffic from port 443 to port 8000:
server {
listen 443 ssl;
ssl on;
server_name carta.example.com;
ssl_certificate /etc/letsencrypt/live/carta.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/carta.example.com/privkey.pem;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:8000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
server_name carta.example.com;
listen 80 ;
listen [::]:80 ;
return 301 https://$host$request_uri;
}
Please ensure that you include a trailing / when hosting the controller on a subdirectory (e.g. location /carta/).
You can also use other HTTP servers, such as Apache. Please ensure that they are set up to forward both standard HTTP requests and WebSocket traffic to the correct port.
Directories
By default, the controller attempts to write log files to the /var/log/carta directory. Please ensure that this directory exists and that the carta user has write permission.
Controller configuration
Controller configuration is handled by a configuration file in JSONC (JSON with JavaScript style comments) format, adhering to the CARTA controller configuration schema. An example controller configuration file is provided:
{
"$schema": "https://cartavis.org/schemas/controller_config_schema_2.json",
"controllerConfigVersion": "2.0",
"authProviders": {
"pam": {
"publicKeyLocation": "/etc/carta/carta_public.pem",
"privateKeyLocation": "/etc/carta/carta_private.pem",
"issuer": "carta.example.com"
}
},
"database": {
"uri": "mongodb://localhost:27017",
"databaseName": "CARTA"
},
"serverPort": 8000,
"serverInterface": "localhost",
"processCommand": "/usr/bin/carta_backend",
"killCommand": "/usr/bin/carta-kill-script",
"rootFolderTemplate": "/home/{username}",
"baseFolderTemplate": "/home/{username}",
"logFile":"/var/log/carta/controller.log",
"dashboard": {
"bannerColor": "#d2dce5",
"backgroundColor": "#f6f8fa",
"bannerImage": "/usr/lib/node_modules/carta-controller/public/images/carta_logo.svg",
"infoText": "Welcome to the CARTA server.",
"loginText": "<span>Please enter your login credentials:</span>",
"footerText": "<span>If you have any problems, comments or suggestions, please <a href='mailto:admin@carta.example.com'>contact us.</a></span>"
}
}
By default, the controller assumes the config file is located at /etc/carta/config.json, but you can change this with the --config or -c command line argument when running the controller.
Configuration may also be added in separate files in a config.d directory in the same parent directory as the specified config file. Each file in this directory must be a valid configuration file. Any files found will be processed in alphabetical order, after the main configuration file.
The controller automatically executes the backend with the --no_http flag, to suppress the backend’s built-in HTTP server. If the backendLogFileTemplate configuration option is set, --no_log is also used to suppress user-level logs. --port is used to override the default port. --top_level_folder and a positional argument are used to set the top-level and starting data directories for the user, as specified in the rootFolderTemplate and baseFolderTemplate options, respectively.
To specify additional backend flags, we recommend editing a global backend preferences file. Most commandline arguments to the backend are also recognised as configuration options. The additionalArgs field in the controller configuration file can be used for any debug options which are not, and to disable the local or global configuration files.
If you use an external authentication system, you may need to translate a unique ID (such as email or username) from the authenticated external user information to an internal system user. You can do this by providing a user lookup table, which is watched by the controller and reloaded whenever it is updated:
# comment lines start with a #
user1@institute.ac user1
user2@institute.ac user2
# multiple usernames can be mapped to the same system user
user1_alt@trusted.domain user1
You can alter the controller’s dashboard appearance by adjusting the dashboard field in the config file. You can change the banner image and background, and add login instructions or institutional notices.
The httpOnly flag can be used to disable secure signing of authentication tokens. This should only be used during initial deployment and testing, or debugging.
The controller assumes it is running at the root directory of your subdomain by default. If you would prefer to run on a subdirectory, you will need to specify the dashboardAddress and apiAddress values (relative to your subdomain) explicitly. For example, if you are hosting CARTA at https://subdomain.domain.com/carta/version/latest/, you would need to include the following in your config file:
{
"apiAddress": "/carta/version/latest/api",
"dashboardAddress": "/carta/version/latest/dashboard"
}
The example controller configuration file enables logging to /var/log/carta/controller.log, but the logFile field is optional and by default the controller will log only to the console. For logging to the example logfile location to work, you must ensure that the /var/log/carta directory exists and that the user account which is used to run the server has write permission to the log file. It is also recommended to set up log rotation for this file, to prevent it from growing indefinitely. An example logrotate configuration is provided, which you can place in /etc/logrotate.d/carta-controller:
/var/log/carta/controller.log {
su carta carta
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
Backend configuration
The global configuration file for the CARTA backend is located at /etc/carta/backend.json. A per-user configuration file can also be placed in each user’s local CARTA preferences directory (typically .carta or .carta-beta in the user’s home directory, depending on how the CARTA backend was installed). On a multi-user system, if users have write access to this location, you may wish to disable the use of per-user configuration files, to prevent users from bypassing the root directory configuration set by the controller. This must be done through the additionalArgs field in the controller configuration.
The backend configuration file must adhere to the CARTA backend configuration schema. An example backend configuration file is provided:
{
"$schema": "https://cartavis.org/schemas/preference_backend_schema_2.json",
"backendConfigVersion": "2.0",
"idle_timeout": 14400,
"omp_threads": 8,
"exit_timeout": 0,
"initial_timeout": 30
}
Note
If you use the global configuration file, please ensure that it is readable by all users in the carta-users group, and that the parent /etc/carta/ directory is readable and executable by all users in the carta-users group, otherwise the starting backend processes will not be able to access it.
Testing the configuration
To test the configuration of the controller, you can use the built-in test feature. Run carta-controller --logLevel debug --test <username> as the carta user (or whichever user has the added sudoers permissions). <username> should be a user in the carta-users group. The expected output looks like this:
2025-06-10 16:01:33 [INFO]: Loaded config from /etc/carta/config.json
2025-06-10 16:01:34 [INFO]: Testing configuration with user alice
Password for user alice: 2025-06-10 16:01:37 [INFO]: ✔ Checked PAM connection for user alice
2025-06-10 16:01:37 [INFO]: ✔ Verified uid (1000) for user alice
2025-06-10 16:01:37 [INFO]: ✔ Generated access token for user alice
2025-06-10 16:01:37 [INFO]: ✔ Checked database connection
2025-06-10 16:01:37 [INFO]: ✔ Checked log writing for user alice
2025-06-10 16:01:37 [INFO]: ✔ Read frontend index.html from /usr/lib/node_modules/carta-controller/dist/../node_modules/carta-frontend/build
2025-06-10 16:01:37 [DEBUG]: running sudo --preserve-env=CARTA_AUTH_TOKEN -n -u alice /usr/bin/carta_backend --no_frontend --no_database --debug_no_auth --port 3499 --top_level_folder /home/alice --controller_deployment --no_log /home/alice
[2025-06-10 14:01:37.719Z] [CARTA] [info] /usr/bin/carta_backend: Version 5.0.0-beta.1
[2025-06-10 14:01:37.720Z] [CARTA] [info] Listening on port 3499 with top level folder /home/alice, starting folder /home/alice, and 8 OpenMP worker threads
2025-06-10 16:01:39 [INFO]: ✔ Backend process started successfully
[2025-06-10 14:01:39.634Z] [CARTA] [info] 0x558329a2dd10 ::Session (581674157:1)
[2025-06-10 14:01:39.634Z] [CARTA] [info] Session 581674157 [127.0.0.1] Connected. Num sessions: 1
2025-06-10 16:01:40 [INFO]: ✔ Backend process accepted connection
2025-06-10 16:01:40 [DEBUG]: running sudo -u alice /usr/bin/carta-kill-script 707247
2025-06-10 16:01:41 [INFO]: ✔ Backend process killed correctly
2025-06-10 16:01:41 [INFO]: Controller tests with user alice succeeded
Note
If you run the controller from a source directory using npm, use -- to ensure that any commandline parameters are passed to the controller and not to npm. For example: npm start -- --verbose --test alice.