Provider-neutral Git LFS batch gateway for S3-compatible object stores. This is a fork of twilligon/git-lfs-s3-proxy, changed so storage credentials stay server-side.
Git clients call one stable endpoint:
Git LFS client → LFS gateway → short-lived presigned URL → S3-compatible storage
The gateway handles only Git LFS batch metadata and SigV4 signing. Object bytes transfer directly between the client and the configured storage provider.
- Downloads can be public.
- Uploads require a separate LFS token.
- S3 credentials are Worker secrets and are never sent to Git clients.
- Provider migration changes Worker configuration, not repository
.lfsconfigfiles.
Public downloads need only the gateway URL:
[lfs]
url = https://lfs.openpencil.devAuthorized writers configure a local override with the separate upload token:
git config --local lfs.url \
'https://openpencil:<LFS_UPLOAD_TOKEN>@lfs.openpencil.dev'The username is ignored. The Basic-auth password is compared with LFS_UPLOAD_TOKEN. Bearer authentication is also accepted.
All S3_* and LFS_* bindings are deployment configuration. None are committed in wrangler.jsonc, so this repository remains independent of any provider, bucket, or environment.
Required bindings:
| Variable | Description |
|---|---|
S3_ENDPOINT |
HTTPS endpoint for an S3-compatible service |
S3_REGION |
SigV4 region |
S3_BUCKET |
Bucket containing objects named by their SHA-256 OID |
S3_SERVICE |
SigV4 service, normally s3 |
S3_FORCE_PATH_STYLE |
true for endpoint/bucket/oid, false for virtual-host style |
LFS_PRESIGN_EXPIRY_SECONDS |
Signed URL lifetime, default 3600 |
LFS_MAX_BATCH_SIZE |
Maximum objects per batch, default 100 |
Configure non-secret bindings in the deployment platform or an untracked Wrangler configuration. Configure secrets separately:
bunx wrangler secret put S3_ACCESS_KEY_ID
bunx wrangler secret put S3_SECRET_ACCESS_KEY
bunx wrangler secret put LFS_UPLOAD_TOKENThe storage key needs object read/write access. It does not need to be exposed to repository users.
GET /health— deployment health checkPOST /objects/batch— Git LFS Batch API fordownloadanduploadGET /— redirects to this repository
Uploads receive a 401 response without a valid upload token. Downloads do not require authentication.
bun install
bun test
bun run check
bunx wrangler devUse .dev.vars for local secrets; it is ignored by Git.
The deploy workflow runs on master and uses repository secrets:
CLOUDFLARE_ACCOUNT_IDCLOUDFLARE_API_TOKEN
S3 and upload-token secrets are configured directly on the Cloudflare Worker and persist across deployments.
The upstream project is dedicated to the public domain under CC0. See LICENSE.