Skip to content

feat(assume): Cloudflare R2 credentials - #57

Draft
cnuss wants to merge 3 commits into
mainfrom
feat/cloudflare-r2
Draft

feat(assume): Cloudflare R2 credentials#57
cnuss wants to merge 3 commits into
mainfrom
feat/cloudflare-r2

Conversation

@cnuss

@cnuss cnuss commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

Adds the Cloudflare R2 output path to saml-to assume. When the backend returns cloudflareR2 on the assume response (roles under a type: cloudflare-r2 provider), the CLI hands the short-lived credentials to the shell or to an ~/.aws profile. AWS roles are untouched.

$(saml-to assume uploads --provider r2 --headless) && aws s3 sync . s3://uploads/ingest/

Depends on backend PR https://github.com/saml-to/github-sls-rest-api/pull/110. Secret delivery companion: saml-to/config-sync-action#14.

Behaviour

  • --headless: one export line with AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_REGION=auto, AWS_DEFAULT_REGION=auto, AWS_ENDPOINT_URL=<account endpoint>, AWS_REQUEST_CHECKSUM_CALCULATION=when_required, AWS_RESPONSE_CHECKSUM_VALIDATION=when_required. PowerShell output as for AWS.
  • --save <profile>: aws configure set for the same values (region auto, endpoint_url, keys, checksum settings); --headless --save prints AWS_PROFILE.
  • Interactive (no flags): an R2 role has no console to open, so the CLI resolves the chosen role via list-roles; if its issuer is an R2 endpoint it saves a profile named after the bucket. Detection is by issuer host (*.r2.cloudflarestorage.com), which the backend sets for r2 providers.
  • 2FA challenges are handled before the R2 branch, as for AWS.

Changes

  • src/helpers/r2/env.ts (pure: buildR2Env, buildR2ProfileSettings, isR2Issuer) + tests
  • src/helpers/r2/r2Helper.ts: assumeR2 (env / profile)
  • src/commands/assume.ts: cloudflareR2 dispatch in assumeTerminal; findR2Role for the interactive path
  • api/github-sls-rest-api: client regenerated from the backend branch's spec (1.0.105-36); previous client was from 1.0.82-0, hence the size of that diff
  • jest + ts-jest (yarn test); README section; dist/ rebuilt with esbuild

Testing

  • yarn test: 5 unit tests. yarn build: green. Prettier clean on changed files.
  • yarn lint crashes in this repo before this change (@typescript-eslint/experimental-utils vs the installed eslint) — not addressed here.
  • Acceptance tests (acceptance-tests.yml) exercise only the AWS path, which is unchanged.
  • Not run against a live R2 bucket yet (needs the backend PR deployed and a test token).

Release

Merge after the backend is live on nonlive; publish as 3.1.0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01S2Gf535RGgcd9pCSNjGaGU

cnuss and others added 3 commits September 2, 2026 18:32
…ndpoints)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2Gf535RGgcd9pCSNjGaGU
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2Gf535RGgcd9pCSNjGaGU
When the backend returns `cloudflareR2` on an assume response, --headless
exports S3-shaped env vars including AWS_ENDPOINT_URL and AWS_REGION=auto,
and --save writes the same into an ~/.aws profile. Choosing an R2 role
interactively saves a profile named after the bucket since there is no
console to open. AWS roles are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2Gf535RGgcd9pCSNjGaGU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant