Known risks of crew

The crew package has unavoidable risks, and the user is responsible for safety, security, and computational resources. This vignette describes known risks and safeguards, but is by no means exhaustive. Please read the software license.

1 Resources

1.1 Processes

The crew package launches external R processes:

  1. Worker processes to run tasks, which may include expensive jobs on cloud services like AWS Batch or traditional clusters like SLURM.
  2. A local mirai dispatcher process to schedule the tasks. If x is a crew controller, the process ID of the dispatcher is x$client$dispatcher.

In the event of a poorly-timed crash or network error, these processes may not terminate properly. If that happens, they will continue to run, which may strain traditional clusters or incur heavy expenses on the cloud. Please monitor the platforms you use and manually terminate defunct hanging processes as needed. To list and terminate local processes, please use crew_monitor_local() as explained in the introduction vignette. To manage and monitor non-local high-performance computing workers such as those on SLURM and AWS Batch, please familiarize yourself with the given computing platform, and consider using the monitor objects in the relevant third-party plugin packages such as crew.cluster or crew.aws.batch. Example: https://wlandau.github.io/crew.aws.batch/index.html#job-management.

1.2 Crashes

In addition, crew worker processes may crash silently at runtime, or they may fail to launch or connect at all. The reasons may be platform-specific, but here are some common possibilities:

1.3 Ports

In addition, crew occupies one TCP port per controller. TCP ports range from 0 to 65535, and only around 16000 of these ports are considered ephemeral or dynamic, so please be careful not to run too many controllers simultaneously on shared machines, especially in controller group. The terminate() frees these ports again for other processes to use.

2 Security

By default, crew uses unencrypted TCP connections for transactions among workers. In a compromised network, an attacker can read the data in transit, and even gain direct access to the client or host.

2.1 Perimeters

It is best to avoid persistent direct connections between your local computer and the public internet. The host argument of the controller should not be a public IP address. Instead, please try to operate entirely within a perimeter such as a firewall, a virtual private network (VPN), or an Amazon Web Services (AWS) security group. In the case of AWS, your security group can open ports to itself. That way, the crew workers on e.g. AWS Batch jobs can connect to a crew client running in the same security group on an AWS Batch job or EC2 instance.

2.2 Encryption

In the age of Zero Trust, perimeters alone are seldom sufficient. Transport layer security (TLS) encrypts data to protect it from hackers while it travels over a network. TLS is the state of the art of encryption for network communications, and it is responsible for security in popular protocols such as HTTPS and SSH. TLS is based on public key cryptography, which requires two files:

  1. A private key file which lives in a protected location on the host machine.
  2. A public key file which is sent to the remote machine on the other side of the connection.

To use TLS in crew with automatic configuration, simply set tls = crew_tls(mode = "automatic") in the controller, e.g. crew_controller_local().1 mirai generates a one-time key pair and encrypts data for the current crew client. The key pair expires when the client terminates, which reduces the risk of a breach. In addition, the public key is a self-signed certificate, which somewhat protects against tampering on its way from the client to the server.

2.3 Certificate authorities

The signature in a self-signed certificate helps the server verify that the public key has a valid private key somewhere. However, in a “man-in-the-middle” (MITM) attack, that private key could belong to a malicious hacker instead of the true client. A certificate authority (CA) is a trusted third party that vouches for the authenticity of a certificate. A CA-backed certificate is more secure than a self-signed one. To supply a CA-backed certificate to crew:

  1. Create a PEM-formatted private key file and matching PEM-formatted certificate file. Details are in https://www.feistyduck.com/library/openssl-cookbook/online/ Chapter 1.2: Key and Certificate Management. When you are done with this step, you should at least have have a private key file, a matching signed certificate, and the root certificate of the CA. If your private key is encrypted, you will also have a password.
  2. When you create a crew controller, create a TLS configuration object with crew_tls() using the following arguments:
    • mode: "custom".
    • key: file path the private key.
    • pass: Your private key password if the private key is encrypted. Do not hard-code this value into any R code files. Instead, use a package like keyring to mask your password.
    • certificates: Character vector of file paths to certificates. One option is to supply only your own certificate. However, for extra security, you may wish to supply the entire certificate chain. In that case, set certificates to the character vector of the certificate file paths in the order they appear in the chain. Begin with your own certificate, then list the certificate that signed it, then the certificate that signed that one, and so on. The final certificate should be the root certificate of the CA.
  3. As before, supply this crew_tls() object to the tls argument of functions like crew_controller_local() (and for plugin developers, crew_client()).

mirai, nanonext, and NNG manage encryption behind the scenes. For more details about configuring TLS, please read https://github.com/shikokuchuo/mirai#distributed-computing-tls-secure-connections.


  1. Launcher plugins should expose the tls argument of crew_client().↩︎