Upload providers

Configure file storage with local filesystem, Amazon S3, or Google Cloud Storage.

Edit this page View Markdown

Upload providers handle storage for both challenge file attachments and team avatars. Both share the same provider, so anything you configure here applies to both.

Warning (v2 needs delete permissions)

Unlike rCTF v1, the v2 upload provider needs permission to delete objects, not just upload them. Avatar replacement and the admin-side file deletion flows both depend on it. If you reuse a v1 IAM policy that only grants s3:GetObject / s3:PutObject, add s3:DeleteObject to it (or the GCS equivalent storage.objects.delete).

Configuration

uploadProvider:
name: uploads/s3
options:
bucketName: my-ctf-uploads
awsKeyId: AKIAIOSFODNN7EXAMPLE
awsKeySecret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
awsRegion: us-east-1

You can keep storage credentials out of config files by using environment variables. Set RCTF_UPLOAD_PROVIDER to a provider such as uploads/s3, then provide the settings through the variables listed below. Environment values override the config file.

File handling

  • Files are stored by their SHA256 hash, so uploading the same file content twice doesn’t create a duplicate.
  • All uploaded files are served with immutable cache headers (max-age=31536000).
  • Team avatars are resized to 256x256 pixels and converted to WebP format before upload. The maximum avatar size comes from the maxAvatarSize config option (default 1 MB).

Providers

Stores files on the local filesystem. This is the default provider.

uploadProvider:
name: uploads/local
options:
uploadDirectory: /path/to/uploads # Optional
Option Default Description
uploadDirectory {cwd}/uploads/ Directory for file storage

Files are served by the API server at /uploads/*. Path traversal protection is built in.

Tip

The local provider works well for development and small events. S3 or GCS is a better fit when many participants will download large challenge files, since those downloads no longer pass through the rCTF server.

Terraform templates

Terraform modules under deploy/terraform/storage/ can create an S3 or GCS bucket, its CORS rules, and credentials limited to the permissions rCTF needs. Each module exposes the generated credentials as sensitive Terraform outputs for use in rctf.d/.

Terminal window
cd deploy/terraform/storage/main
terraform init
terraform apply -var="region=eu-west-3" -var="bucket_name=my-ctf-uploads"

Read the credentials for the dedicated rctf-bucket IAM user from the sensitive outputs (rctf_iam_user_arn and bucket are printed to stdout on apply):

Terminal window
terraform output -raw access_key_id
terraform output -raw secret_access_key

Drop the credentials into your config:

rctf.d/03-uploads.yaml
uploadProvider:
name: uploads/s3
options:
bucketName: my-ctf-uploads
awsKeyId: <access_key_id output>
awsKeySecret: <secret_access_key output>
awsRegion: eu-west-3

The module sets up CORS (GET, HEAD from any origin by default, which you can override with -var="cors_allowed_origins=[\"https://ctf.example.com\"]") and grants the IAM user s3:GetObject, s3:PutObject, s3:DeleteObject, plus the matching ACL actions and s3:ListBucket.

Type to search.