Security

Files and assets

21RISK stores two kinds of files, both in Cloudflare R2, in Cloudflare's EU jurisdiction:

  • Customer files: the files users upload in the web-application, for example photos and documents on actions, and report PDFs. Only signed-in users who may see a file can open it. They are kept in a private bucket and served on assets.21risk.com.
  • Public files: 21RISK's own content for our website, documentation and product updates, such as screenshots, and organizations' logos. Anyone can open them. They are kept in a separate public bucket and served on p-assets.21risk.com.

Both hostnames are served by our own Cloudflare Worker, which reads the files from R2 and resizes images on request. Files that could run code in a browser, such as HTML or SVG, are only ever offered as downloads, in a sandbox that blocks scripts. Cloudflare encrypts every file stored in R2 at rest.

Customer files

In the 21RISK web-application, uploading looks like the following:

When a user uploads a file, the following happens:

  1. The user selects a file (or drags a file) onto the 21RISK client.
  2. The client sends a request to the 21RISK server.
  3. The 21RISK server checks that the user has access to the given resource, and if so, records the upload and signs an upload token for exactly that file's size and type.
  4. The 21RISK client uploads the file to our Cloudflare Worker, which checks the token and stores the file in a holding area of the private bucket that is never served.
  5. The client confirms the upload. The 21RISK server checks that the file is the size and type that was signed, and that images, PDFs and videos really are what they say they are. A file that doesn't match is deleted. Otherwise the file is moved to its permanent ID.

The upload token is an HMAC-SHA256 signature. It expires after 6 hours, long enough for the largest file (2 GB) on a slow connection, and an upload without a valid token is rejected. Large files go up in parts, and every part is checked against the same token. Agents connected through the 21RISK MCP server upload files the same way.

Virus scanning

Every uploaded customer file is scanned with ClamAV (an open-source antivirus engine) shortly after its upload, in an isolated sandbox whose virus signatures are refreshed twice a day. A file still waiting for its scan after 15 minutes is picked up by a sweep that runs twice a day. When a file is found infected, the finding is recorded and the file is deleted from storage. As before, a file can be used while it waits for its scan.

Opening files

When an upload is done, we save the file's ID, and the organization (or, for a profile picture, the user) it belongs to, in our application database. Links to the file go through the 21RISK server, which checks that the signed-in user is a member of the organization the file belongs to (for a profile picture, that they are signed in), and then sends them to the file on assets.21risk.com, with a token that is signed for that one file and expires after 24 hours:

https://assets.21risk.com/<file-id>/?token=<signed-token>

The Worker refuses any request for a customer file without a valid token.

Some files, almost all uploaded before October 2026, belong to no organization yet, because no organization's records point to them, or several do. Any signed-in user with a link can still open those, and every time one is opened, we record who opened it and from which page. That tells us which organization each one belongs to, or that nobody uses it any more and it can be deleted.

Backup to Google Cloud Storage

Customer files are backed up off-site, outside Cloudflare, to a Google Cloud Storage bucket in the EU. Twice a day, new files that have passed their virus scan are copied there, and the copies of files that were deleted or found infected are removed. The key we use for the backup can only add and remove files, never read or list them. The bucket keeps removed files for 7 days and no longer, so a file that is deleted or found infected leaves the backup within 7 days of the next backup run.

Compliance

Cloudflare is compliant with SOC 2 Type II and ISO 27001, among other standards. To read more, please refer to Cloudflare's trust hub here. Google Cloud is compliant with SOC 2 and ISO 27001, among other standards; see Google Cloud's compliance resource center here.

Public files

Apart from organization logos (below), only 21RISK administrators can publish public files. When they do, the following happens:

  1. The 21RISK server checks that the user is a 21RISK administrator, and signs an upload for exactly the file's name, size and type. The upload must start within 30 minutes, and Cloudflare R2 rejects any other file.
  2. The file is uploaded directly to Cloudflare R2, to a holding area that is never served.
  3. The 21RISK server checks that the file's content is the type it was uploaded as. Only images, PDF and video are accepted. A file that doesn't match is deleted.
  4. The file is moved to its permanent ID, and is then served on p-assets.21risk.com.

Public files are not virus scanned, since they are made by 21RISK and never by customers.

Organization logos

An organization's logo is the one public file that comes from customers, so that it can also be shown where nobody is signed in. The logo a user uploads is a customer file like any other. When an organization owner saves it as the logo, the 21RISK server has our Worker draw it again as a PNG, and stores that new image in the public bucket, served on p-assets.21risk.com. The uploaded file itself never becomes public, so the published copy doesn't wait for the virus scan. The logo settings tell owners that the logo is public.

Videos

21RISK's own videos are hosted and streamed by Mux, a video platform: the videos on our website, in the documentation and product updates, and the short video introductions in the web-application. Mux stores the videos and streams them to the browser from stream.mux.com, with still images from image.mux.com. To deliver a video, Mux receives what any streaming service does: the viewer's IP address and browser details. Mux Data, Mux's viewer analytics, is turned off, so Mux collects no viewing analytics and sets no cookies. These videos moved from Vimeo to Mux in October 2026.

Training videos are different. A video that a customer uploads for a User Training campaign is a customer file, stored and served like the customer files above: on Cloudflare R2, with the same access checks, virus scan and backup. A customer can instead link to a public video on Vimeo or Mux; that video is then played by the provider's own player, from the customer's own account with that provider.

Compliance

Mux is certified to ISO 27001, is GDPR compliant and takes part in the EU-US Data Privacy Framework. To read more, please refer to Mux's trust center here.