Skip to content

Commit 2e4cfc5

Browse files
committed
fix: provision temporary Cloudflare DNS token
1 parent 0dce628 commit 2e4cfc5

1 file changed

Lines changed: 61 additions & 1 deletion

File tree

.github/workflows/email-provider-migration.yml

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ jobs:
1212
permissions:
1313
contents: read
1414
env:
15+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
1516
CLOUDFLARE_API_TOKEN_PROVISIONER: ${{ secrets.CLOUDFLARE_API_TOKEN_PROVISIONER }}
1617
CLOUDFLARE_R2_PROVISIONER: ${{ secrets.CLOUDFLARE_R2_PROVISIONER }}
18+
CLOUDFLARE_API_TOKEN_OWNER: ${{ vars.CLOUDFLARE_API_TOKEN_OWNER }}
1719
steps:
1820
- name: Add authenticated Resend records
1921
shell: bash
@@ -23,8 +25,66 @@ jobs:
2325
api="https://api.cloudflare.com/client/v4"
2426
zone_id=""
2527
token=""
28+
temporary_token_id=""
29+
token_owner="${CLOUDFLARE_API_TOKEN_OWNER:-account}"
2630
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
2888
if [[ -z "$candidate" ]]; then
2989
continue
3090
fi

0 commit comments

Comments
 (0)