diff --git a/script/generate-permission-policies b/script/generate-permission-policies new file mode 100755 index 0000000..43fd715 --- /dev/null +++ b/script/generate-permission-policies @@ -0,0 +1,156 @@ +#!/usr/bin/env bash + +# Pull permission groups from Cloudflare's API +# Generate policy output for pasting into generatePolicy() + + +if [[ ! -z "${CLOUDFLARE_API_TOKEN}" ]]; then + auth_headers=( -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" ) + +elif [[ ! -z "${CLOUDFLARE_EMAIL}" && ! -z "${CLOUDFLARE_API_KEY}" ]]; then + auth_headers=( -H "X-Auth-Email: $CF_EMAIL" + -H "X-Auth-Key: $CF_API_KEY" ) + +else + >&2 echo -e "ERROR: CLOUDFLARE_API_TOKEN or (CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY) should be set in the environment.\n " + exit 1 +fi + +groups=$(curl -s "https://api.cloudflare.com/client/v4/user/tokens/permission_groups" \ + "${auth_headers[@]}") + +if [[ "$(echo "${groups}" | jq -r '.success')" != "true" ]]; then + echo "Error fetching permission groups:" + echo "${groups}" | jq + exit 1 +fi + +declare -A account_read zone_read user_read +declare -A account_write zone_write user_write + +# account +while IFS=\| read id name; do + if [[ "${name}" =~ (^|[^[:alnum:]_])Read([^[:alnum:]_]|$) ]]; then + account_read+=([${id}]=${name}) + else + account_write+=([${id}]=${name}) + fi +done < <(echo "${groups}" | jq -r '.result[] | select(.scopes[] | contains("com.cloudflare.api.account")) | "\(.id)|\(.name)"') + +# zone +while IFS=\| read id name; do + if [[ "${name}" =~ (^|[^[:alnum:]_])Read([^[:alnum:]_]|$) ]]; then + zone_read+=([${id}]=${name}) + else + zone_write+=([${id}]=${name}) + fi +done < <(echo "${groups}" | jq -r '.result[] | select(.scopes[] | contains("com.cloudflare.api.account.zone")) | "\(.id)|\(.name)"') + +# user +while IFS=\| read id name; do + if [[ "${name}" =~ (^|[^[:alnum:]_])Read([^[:alnum:]_]|$) ]]; then + user_read+=([${id}]=${name}) + elif [[ "${name}" == "API Tokens Write" ]]; then + # Tokens can't have this permission + : + else + user_write+=([${id}]=${name}) + fi +done < <(echo "${groups}" | jq -r '.result[] | select(.scopes[] | contains("com.cloudflare.api.user")) | "\(.id)|\(.name)"') + + +# +# Read-only +# +cat <<"EOF" + readOnlyPolicy := []policy{ + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.account.*": "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!account_read[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${account_read[$key]}" +done | sort + +cat <<"EOF" + }, + }, + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.account.zone.*": "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!zone_read[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${zone_read[$key]}" +done | sort + +cat <<"EOF" + }, + }, + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.user." + userID: "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!user_read[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${user_read[$key]}" +done | sort + +cat <<"EOF" + }, + }, + } +EOF + + +# +# Write everything +# +cat <<"EOF" + + writeEverythingPolicy := []policy{ + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.account.*": "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!account_write[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${account_write[$key]}" +done | sort + +cat <<"EOF" + }, + }, + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.account.zone.*": "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!zone_write[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${zone_write[$key]}" +done | sort + +cat <<"EOF" + }, + }, + { + Effect: "allow", + Resources: map[string]interface{}{"com.cloudflare.api.user." + userID: "*"}, + PermissionGroups: []permissionGroup{ +EOF + +for key in "${!user_write[@]}"; do + echo -e "\t\t\t\t{ID: \"${key}\"}, // ${user_write[$key]}" +done | sort + +cat <<"EOF" + }, + }, + } +EOF