Skip to content

Fix Cloudflare Access IDP lookup and JSON body issues #4

Fix Cloudflare Access IDP lookup and JSON body issues

Fix Cloudflare Access IDP lookup and JSON body issues #4

Workflow file for this run

name: Deploy to Cloudflare Pages
on:
push:
branches: ["main"]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
name: Deploy to Cloudflare Pages
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install Wrangler
run: npm install -g wrangler
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Determine Project Name
id: meta
run: echo "NAME=$(echo ${{ github.repository }} | cut -d'/' -f2)" >> $GITHUB_OUTPUT
- name: Create Project (if not exists)
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
PROJECT_NAME: ${{ steps.meta.outputs.NAME }}
run: wrangler pages project create "$PROJECT_NAME" --production-branch main || true
- name: Publish to Cloudflare Pages
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
PROJECT_NAME: ${{ steps.meta.outputs.NAME }}
run: wrangler pages deploy . --project-name "$PROJECT_NAME" --branch main
- name: Get Assigned Pages Subdomain
id: project_details
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
PROJECT_NAME: ${{ steps.meta.outputs.NAME }}
run: |
RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects/$PROJECT_NAME" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json")
SUBDOMAIN=$(echo "$RESPONSE" | jq -r '.result.subdomain')
echo "Cloudflare assigned subdomain: $SUBDOMAIN"
echo "SUBDOMAIN=$SUBDOMAIN" >> $GITHUB_OUTPUT
- name: Assign Custom Domain (via API)
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
PROJECT_NAME: ${{ steps.meta.outputs.NAME }}
DOMAIN: "${{ steps.meta.outputs.NAME }}.apps.owid.io"
run: |
echo "Linking domain $DOMAIN to project $PROJECT_NAME..."
curl -f -X POST "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects/$PROJECT_NAME/domains" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"name\":\"$DOMAIN\"}" || true
- name: Force DNS Record Creation
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
DOMAIN: "${{ steps.meta.outputs.NAME }}.apps.owid.io"
TARGET: ${{ steps.project_details.outputs.SUBDOMAIN }}
ZONE_NAME: "owid.io"
run: |
echo "Ensuring DNS record for $DOMAIN points to $TARGET..."
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$ZONE_NAME" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$DOMAIN" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
if [ "$RECORD_ID" == "null" ]; then
echo "Creating CNAME: $DOMAIN -> $TARGET"
curl -f -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"CNAME\",\"name\":\"$DOMAIN\",\"content\":\"$TARGET\",\"proxied\":true,\"ttl\":1}"
else
echo "Record exists. Skipping."
fi
- name: Restrict Access to OWID Staff
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.WEBSITE_STARTER_CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
DOMAIN: "${{ steps.meta.outputs.NAME }}.apps.owid.io"
run: |
# Check if an Access application already exists for this domain
EXISTING_APP=$(curl -s -X GET \
"https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
| jq -r --arg domain "$DOMAIN" '.result[] | select(.domain == $domain) | .id')
# Find the Google identity provider ID (skip the OTP provider)
IDP_RESPONSE=$(curl -s -X GET \
"https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/identity_providers" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json")
echo "Identity providers response: $(echo "$IDP_RESPONSE" | jq -c '{success: .success, result_count: (.result | length), types: [.result[]?.type]}')"
GOOGLE_IDP=$(echo "$IDP_RESPONSE" \
| jq -r '(.result // [])[] | select(.type == "google" or .type == "google-apps" or (.name | test("google";"i"))) | .id' | head -1)
if [ -n "$GOOGLE_IDP" ]; then
echo "Found Google identity provider: $GOOGLE_IDP"
IDP_EXTRA="\"allowed_idps\": [\"$GOOGLE_IDP\"], \"auto_redirect_to_identity\": true,"
else
echo "Warning: Could not find Google identity provider. Login screen will show all providers."
IDP_EXTRA=""
fi
if [ -n "$EXISTING_APP" ]; then
echo "Access application already exists for $DOMAIN (ID: $EXISTING_APP). Updating to restrict identity providers..."
curl -f -s -X PUT \
"https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps/$EXISTING_APP" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"$DOMAIN\",
\"domain\": \"$DOMAIN\",
\"type\": \"self_hosted\",
\"session_duration\": \"24h\",
$IDP_EXTRA
\"tags\": []
}"
echo "Updated Access application."
exit 0
fi
echo "Creating Access application for $DOMAIN..."
APP_RESPONSE=$(curl -f -s -X POST \
"https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"$DOMAIN\",
\"domain\": \"$DOMAIN\",
\"type\": \"self_hosted\",
\"session_duration\": \"24h\",
$IDP_EXTRA
\"tags\": []
}")
APP_ID=$(echo "$APP_RESPONSE" | jq -r '.result.id')
echo "Created Access application: $APP_ID"
echo "Adding policy to allow @ourworldindata.org emails..."
curl -f -s -X POST \
"https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps/$APP_ID/policies" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"Allow OWID Staff\",
\"decision\": \"allow\",
\"include\": [{
\"email_domain\": {
\"domain\": \"ourworldindata.org\"
}
}]
}"
echo "Access restriction enabled for $DOMAIN"