|
12 | 12 | permissions: |
13 | 13 | contents: read |
14 | 14 | env: |
| 15 | + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
15 | 16 | CLOUDFLARE_API_TOKEN_PROVISIONER: ${{ secrets.CLOUDFLARE_API_TOKEN_PROVISIONER }} |
16 | 17 | CLOUDFLARE_R2_PROVISIONER: ${{ secrets.CLOUDFLARE_R2_PROVISIONER }} |
| 18 | + CLOUDFLARE_API_TOKEN_OWNER: ${{ vars.CLOUDFLARE_API_TOKEN_OWNER }} |
17 | 19 | steps: |
18 | 20 | - name: Add authenticated Resend records |
19 | 21 | shell: bash |
|
23 | 25 | api="https://api.cloudflare.com/client/v4" |
24 | 26 | zone_id="" |
25 | 27 | token="" |
| 28 | + temporary_token_id="" |
| 29 | + token_owner="${CLOUDFLARE_API_TOKEN_OWNER:-account}" |
26 | 30 |
|
27 | | - for candidate in "$CLOUDFLARE_API_TOKEN_PROVISIONER" "$CLOUDFLARE_R2_PROVISIONER"; do |
| 31 | + if [[ "$token_owner" == "user" ]]; then |
| 32 | + token_collection="/user/tokens" |
| 33 | + else |
| 34 | + token_collection="/accounts/$CLOUDFLARE_ACCOUNT_ID/tokens" |
| 35 | + fi |
| 36 | +
|
| 37 | + revoke_temporary_token() { |
| 38 | + if [[ -n "$temporary_token_id" ]]; then |
| 39 | + curl --silent --show-error \ |
| 40 | + --request DELETE \ |
| 41 | + --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN_PROVISIONER" \ |
| 42 | + "$api$token_collection/$temporary_token_id" >/dev/null || true |
| 43 | + fi |
| 44 | + } |
| 45 | + trap revoke_temporary_token EXIT |
| 46 | +
|
| 47 | + permission_groups=$(curl --fail-with-body --silent --show-error \ |
| 48 | + --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN_PROVISIONER" \ |
| 49 | + "$api$token_collection/permission_groups") |
| 50 | + dns_write_id=$(jq -r '.result[] | select(.name == "DNS Write") | .id' <<<"$permission_groups" | head -1) |
| 51 | + zone_read_id=$(jq -r '.result[] | select(.name == "Zone Read") | .id' <<<"$permission_groups" | head -1) |
| 52 | +
|
| 53 | + if [[ -z "$dns_write_id" || -z "$zone_read_id" ]]; then |
| 54 | + echo "Cloudflare DNS permission groups were not available to the token provisioner." >&2 |
| 55 | + exit 1 |
| 56 | + fi |
| 57 | +
|
| 58 | + expires_on=$(date -u -d '+1 hour' '+%Y-%m-%dT%H:%M:%SZ') |
| 59 | + token_payload=$(jq -n \ |
| 60 | + --arg dns_write_id "$dns_write_id" \ |
| 61 | + --arg zone_read_id "$zone_read_id" \ |
| 62 | + --arg expires_on "$expires_on" \ |
| 63 | + '{ |
| 64 | + name: "modtale Resend DNS migration", |
| 65 | + expires_on: $expires_on, |
| 66 | + policies: [{ |
| 67 | + effect: "allow", |
| 68 | + resources: {"com.cloudflare.api.account.zone.*": "*"}, |
| 69 | + permission_groups: [{id: $dns_write_id}, {id: $zone_read_id}] |
| 70 | + }] |
| 71 | + }') |
| 72 | + token_response=$(curl --fail-with-body --silent --show-error \ |
| 73 | + --request POST \ |
| 74 | + --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN_PROVISIONER" \ |
| 75 | + --header "Content-Type: application/json" \ |
| 76 | + --data "$token_payload" \ |
| 77 | + "$api$token_collection") |
| 78 | + token=$(jq -r '.result.value // empty' <<<"$token_response") |
| 79 | + temporary_token_id=$(jq -r '.result.id // empty' <<<"$token_response") |
| 80 | +
|
| 81 | + if [[ -z "$token" || -z "$temporary_token_id" ]]; then |
| 82 | + echo "Cloudflare did not return the temporary DNS token." >&2 |
| 83 | + exit 1 |
| 84 | + fi |
| 85 | + echo "::add-mask::$token" |
| 86 | +
|
| 87 | + for candidate in "$token" "$CLOUDFLARE_API_TOKEN_PROVISIONER" "$CLOUDFLARE_R2_PROVISIONER"; do |
28 | 88 | if [[ -z "$candidate" ]]; then |
29 | 89 | continue |
30 | 90 | fi |
|
0 commit comments