S3 Access

Pro Experimental S3 access is experimental: its behaviour and the parts of the S3 API it supports may change in later releases.

On Knot Pro, every server with file storage also serves the S3 API, path-style, at <server URL>/s3, so rclone, backup tools, the AWS CLI and SDKs work with your buckets unchanged. Knot Core has the web interface, the knot file commands (including sync) and the API.

Setting Value
Endpoint https://knot.example.com/s3
Access key your username
Secret key one of your API tokens
Addressing path-style
Region any (us-east-1 is reported)

Create a token with the Files scope for S3 clients, so a leaked key can reach your files and nothing else. Any of your full-access tokens work too. Using a token for S3 keeps it alive, as API use does.

rclone

[knot]
type = s3
provider = Other
endpoint = https://knot.example.com/s3
access_key_id = paul
secret_access_key = <files-scoped API token>
force_path_style = true
rclone lsd knot:
rclone sync ./site knot:configs/site
rclone check ./site knot:configs/site

Modification times, checksums, server-side copies and moves and multipart uploads all work.

AWS CLI

export AWS_ACCESS_KEY_ID=paul
export AWS_SECRET_ACCESS_KEY=<files-scoped API token>
aws --endpoint-url https://knot.example.com/s3 s3 ls s3://configs/
aws --endpoint-url https://knot.example.com/s3 s3 cp ./build.tar.gz s3://configs/builds/

Supported operations

ListBuckets, CreateBucket, HeadBucket, DeleteBucket (empty buckets), GetBucketLocation, ListObjects (v1 and v2), GetObject (with ranges and conditions), HeadObject, PutObject, CopyObject, DeleteObject (with If-Match, to delete only the version you saw), DeleteObjects and multipart uploads including UploadPartCopy (server-side copy in parts, used by the AWS CLI, boto3 and rclone for large objects), with signature version 4 in headers or presigned URLs and both signed and unsigned streaming payloads. Bucket sharing, transfer and quotas are managed with knot file bucket rather than S3 policies or ACLs; versioning, lifecycle rules, tagging and object locking are not supported.

Content is served with X-Content-Type-Options: nosniff and a sandboxing Content-Security-Policy, so an HTML or SVG file opened from a presigned URL can display but never run script against the knot server. Responses also carry Cache-Control: no-transform, so a reverse proxy that compresses responses (Caddy’s encode, nginx gzip) leaves them untouched; S3 clients compare the exact bytes, ETags and ranges. File downloads through the API are marked the same way. Listings (of objects, multipart uploads and parts) are the exception: they are sent gzip-compressed to clients that ask with Accept-Encoding: gzip, as Go clients such as rclone do by default, which makes listing a large bucket much quicker.

User metadata (x-amz-meta-* headers) is limited to 2 KB per file, as on AWS (MetadataTooLarge). File keys (up to 1024 bytes), metadata and content types must be valid UTF-8; anything else is refused with 400, as it could not be stored and replicated unchanged. Parts of a multipart upload may be any size; the 5 MB minimum AWS applies is not enforced.

Buckets created over S3 belong to the signing user, as with knot file bucket create; creating configs makes <username>--configs. Bucket names in requests follow the naming rules: a short name is your own bucket, a full name reaches any bucket you have access to.