Private Satis Repository CloudFlare Worker

This is a CloudFlare Worker that allows you to host your own private Composer repository directly from a CloudFlare R2 Storage bucket, without the need to run any servers. Authentication is done using usernames and passwords stored in CloudFlare KV.

GitHub Repository

Deployment

To deploy this worker, you need to clone repository, update wrangler.toml configuration file and run wrangler deploy command.

git clone git@github.com:kduma-OSS/CFW-serverless-satis-worker.gitcd CFW-serverless-satis-workernpm install# Update wrangler.toml filenpm run deploy

Worker Configuration

You need to update wrangler.toml file with your own values:

Variable NameDescription
nameName of your CloudFlare Worker
vars.PUBLIC_ACCESS_TO_INDEXIf true, index page will be accessible without authentication
vars.PUBLIC_ACCESS_TO_JSONIf true, JSON indexes will be accessible without authentication
vars.CHECK_FILE_RESTRICTIONSSee Selective Access
vars.CHECK_EXTRA_JSON_RESTRICTIONSSee Selective Access
vars.STORE_PASSWORDS_HASHEDSee Authentication
vars.ENABLE_USER_ENDPOINTSee User Endpoint
routes.patternDomain you want to expose your private repository on (need to use CloudFlare DNS)
kv_namespaces.idNamespace ID of your Worker KV to read users from
r2_buckets.bucket_nameName of private bucket where are stored files generated by s3-satis tool
name = "<name>"
main = "src/index.ts"
compatibility_date = "2023-12-06"

[vars]
PUBLIC_ACCESS_TO_INDEX = false
PUBLIC_ACCESS_TO_JSON = false
CHECK_FILE_RESTRICTIONS = false
CHECK_EXTRA_JSON_RESTRICTIONS = false
STORE_PASSWORDS_HASHED = false
ENABLE_USER_ENDPOINT = false

[[routes]]
pattern = "<domain>"
custom_domain = true

[[kv_namespaces]]
binding = "AUTH"
id = "<kv_id>"

[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "<bucket_name>"

Authentication

Authentication is done using usernames and passwords stored in CloudFlare KV. You need to create a KV namespace and bind it to AUTH variable in wrangler.toml file. Worker will read usernames and passwords from KV namespace and use them to authenticate users.

When adding new users to KV, please set username as a key and password as a value. If STORE_PASSWORDS_HASHED is set to true, you need to hash passwords with SHA-256 before adding them to KV. If STORE_PASSWORDS_HASHED is set to false, passwords are stored in plain text.

User Endpoint

When ENABLE_USER_ENDPOINT is set to true, you can use https://<domain>/user.json endpoint to check logged-in user, and get list of assigned permissions (for more details see Selective Access)

Selective Access

If you want to restrict users to access only specific packages or version, you can use file-restrictions-map-generator extension of s3-satis tool, to generate a map of file packages and versions. Then, you need to set vars.CHECK_FILE_RESTRICTIONS to true and deploy the Worker.

After doing that, you can edit your user in KV. To specify which packages and versions are accessible to user, edit value field, add a new line after users password and list tags (delimited by a comma) of packages and versions you want to allow access to.

For example:

password 
vendor/package-1:1.x,vendor/package-2:2.0.0.0,vendor/package-3:dev-master

If user tries to access a package or version that is not listed in KV, the request will be rejected with 403 Forbidden error.

If you want to remove packages to which user doesn't have access from json files (so the composer won't complain about not having access to them when upgrading), you cen enable extra-json option in file-restrictions-map-generator extension of s3-satis tool, and set vars.CHECK_EXTRA_JSON_RESTRICTIONS to true.