Example: short-lived R2 credentials for a bucket¶
Goal¶
Give people, CI jobs and pods S3 credentials for one R2 bucket that expire in minutes, with no long-lived R2 secret.
What you need¶
secrets.source: ssm.- A Cloudflare minter token (account token, Account API Tokens Read and Write only) stored at
internal/cloudflare/main/minter, and a disabled prototype token holding Bucket Item Read and Write on the bucket. Custody of the minter is the account owner's: it can mint anything the owner can, and sluis's refusal list is the only guard.
The policy snippet¶
Service document, the preset:
cloudflare:
accounts:
main:
id: <account-id>
minter: internal/cloudflare/main/minter
presets:
r2-archive:
account: main
prototype: <R2 prototype token id>
description: Archive bucket, read and write
endpoint: https://<account-id>.r2.cloudflarestorage.com
lifetime: 15m
rotation: 5m
Policy document, who may ask:
cloudflare:
grants:
- group: all:infra:archive-users
presets: [r2-archive]
The exchange / command¶
sluisctl login
sluisctl aws-config # adds the profile r2-archive@r2 per granted R2 preset
aws --profile r2-archive@r2 s3 ls s3://example-archive/
The profile runs sluisctl cloudflare r2 r2-archive as its credential_process and sets endpoint_url,
region = auto, the two checksum settings as when_required, and path-style addressing. A pod that gets
external/cloudflare/r2-archive from a secrets operator uses
credential_process = sluisctl cloudflare r2 r2-archive --file /var/run/secrets/cloudflare/r2-archive.json, which refuses
an expired document.
Verify¶
The listing succeeds; on any other bucket the credentials are refused (403). sluisctl whoami lists the granted presets.
The audit trail has roster.cloudflare.token.minted. The alert SluisCloudflareRotationStale fires when the stored
credential is older than twice its rotation.
Undo¶
Remove the grant row (an unknown preset and an ungranted one give the same answer). Revoke a live token by id from the
console or CLI; remove the preset to stop rotation. Delete <config>/cloudflare/ to drop cached credentials.
Source: the how-to mint short-lived Cloudflare tokens and the
sluisctl cloudflare reference. Snippets follow those pages; the
policy grant renders with sluisctl policy render (checked against master, 2026-10-09).