Skip to content

Commit

Permalink
Script to generate permission policies
Browse files Browse the repository at this point in the history
This script enumerates permission policies from Cloudflare's API and then writes them to a format that can be copy & pasted into `add.go` in this project.

It's a bit ugly, it has a bunch of duplication and could be done better, but it gets the job done.

In future, it might be nice for the policies to be externalized into their own files (toml or whatever) that can easily be updated, rather than having to copy/paste sections into a file.
  • Loading branch information
simpson-ross committed Jun 27, 2023
1 parent b12aec5 commit 8efdcbf
Showing 1 changed file with 156 additions and 0 deletions.
156 changes: 156 additions & 0 deletions script/generate-permission-policies
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 8efdcbf

Please sign in to comment.