We were using permanent tokens to access R2 buckets. However, we found that we could only create 50 permanent API tokens. Given we create tokens for each customer/bucket, this approach isn't scalable. Unfortunately, there's no easy way to increase this limit. While an enterprise account allows for more tokens, upgrading is not practical for us. We learned from the community that temporary tokens don't have this restriction [^1] [^2]. Thus, we've decided to switch to temporary tokens. Another future benefit is that temporary tokens allow us to set more specific permissions at the bucket, prefix, and object levels. We've chosen to use temporary tokens for accessing R2 buckets. Unlike permanent tokens, this requires sending a session_token with each request, and we must refresh the token before it expires. I've implemented refreshing part in the next commit. [^1]: https://developers.cloudflare.com/r2/api/s3/tokens/#temporary-access-credentials [^2]: https://developers.cloudflare.com/api/operations/r2-create-temp-access-credentials
24 lines
790 B
Ruby
24 lines
790 B
Ruby
# frozen_string_literal: true
|
|
|
|
require "excon"
|
|
require "json"
|
|
|
|
class CloudflareClient
|
|
def initialize(api_key)
|
|
@connection = Excon.new("https://api.cloudflare.com", headers: {"Authorization" => "Bearer #{api_key}"})
|
|
end
|
|
|
|
def create_temporary_token(bucket_name, permission, ttl)
|
|
path = "/client/v4/accounts/#{Config.github_cache_blob_storage_account_id}/r2/temp-access-credentials"
|
|
body = {
|
|
bucket: bucket_name,
|
|
parentAccessKeyId: Config.github_cache_blob_storage_access_key,
|
|
permission: permission,
|
|
ttlSeconds: ttl
|
|
}
|
|
response = @connection.post(path: path, body: body.to_json, expects: 200)
|
|
data = JSON.parse(response.body)
|
|
[data["result"]["accessKeyId"], data["result"]["secretAccessKey"], data["result"]["sessionToken"]]
|
|
end
|
|
end
|