Skip to main content

Cloudflare

Purpose: CDN, security, DNS management, and performance layer for Pacing Agency domains. Also provides Zero Trust authentication and access control via Cloudflare Access.

Client access best practice​

  • Prefer client-owned Cloudflare with Pacing added as Super Admin (or least-privilege where possible) via the client’s Cloudflare account.
  • Avoid shared credentials. Role-based access gives cleaner ownership boundaries and an audit trail.

Current use​

  • DNS management for three domains: pacing.agency, pacingagency.com, pacingagency.co.uk.
  • CDN and proxy in front of AWS hosting; HSTS enabled; SSL via Cloudflare.
  • Cloudflare Browser Insights running for RUM/performance telemetry.
  • Workers and redirect rules (to be documented).
  • Cloudflare Access (Zero Trust) for authentication and access control (see Cloudflare Access section below).

Domains managed​

DomainZone IDPlanStatusPrimary useProxy status
pacing.agency7b33df94002298798689223a84510c73Free WebsiteActiveMain agency website (Webflow)Proxied
pacingagency.comda23822fff12b011ab03601dec1c9430UnknownActiveTwentyCRM instanceNot proxied
pacingagency.co.uk654b10d6d4cfb4c17d37e8339e6758d0UnknownActiveEmail/redirectsMixed

DNS Records​

pacing.agency​

Name servers:

  • cheryl.ns.cloudflare.com
  • greg.ns.cloudflare.com

A Records:

SubdomainIPProxyPurpose
apiforms.pacing.agency134.209.40.56YesAPI forms
comments.pacing.agency91.98.226.29NoComments service
dam.pacing.agency91.98.226.29NoDAM - ResourceSpace
email.pacing.agency91.99.193.35NoNotifuse
forms.pacing.agency134.209.40.56YesForms
headshots.pacing.agency91.98.70.125NoHeadshotAI
images.pacing.agency91.99.193.35NoNotifuse image CDN
n8n.pacing.agency91.98.150.95NoN8n workflow automation
ttluserjourney.pacing.agency34.36.161.3NoUser Journey Tool (Google Cloud Run)

CNAME Records:

SubdomainTargetProxyPurpose
data.pacing.agencyeue.stape.netNoStape sGTM server
form.pacing.agencydomains.opnform.comNoOpenForm
freeagent-mailer.pacing.agencypm.mtasv.netNoFreeAgent mailer
load.data.pacing.agencyleue.stape.netNoStape custom loader
pacing.agencycdn.webflow.comYesMain site (Webflow)
www.pacing.agencycdn.webflow.comYesMain site (Webflow)

MX Records:

SubdomainPriorityTargetPurpose
pacing.agency1aspmx.l.google.comGoogle Workspace
pacing.agency5alt1.aspmx.l.google.comGoogle Workspace
pacing.agency5alt2.aspmx.l.google.comGoogle Workspace
pacing.agency10alt3.aspmx.l.google.comGoogle Workspace
pacing.agency10alt4.aspmx.l.google.comGoogle Workspace
front-mail.pacing.agency100mx.sendgrid.netFrontApp support
send.updates.pacing.agency10feedback-smtp.eu-west-1.amazonses.comCRM1 (TwentyCRM)

TXT Records:

SubdomainValuePurpose
pacing.agencyv=spf1 include:_spf.google.com include:spf.mtasv.net include:_spf.freeagent.com ~allSPF record
pacing.agencygoogle-site-verification=_iYPZPZnfhRF06EI7drtfQHpyOQIgzuQSBc8pbmDRIIGoogle Search Console
pacing.agencygoogle-site-verification=oiSUoEn_XBqNiDth2oE2Xa-WyQNibpclETYyQtvFgmMGoogle Search Console
pacing.agencypinterest-site-verification=240531e3e0e643455f627266dfb9582aPinterest verification
_dmarc.pacing.agencyv=DMARC1; p=none; rua=mailto:15f85ec1560545c6960f494ffb78da31@dmarc-reports.cloudflare.net; fo=1; pct=100; aspf=r; adkim=sDMARC policy
_webflow.pacing.agencyone-time-verification=9c50407e-6e33-4500-8606-303122c4e1a0Webflow verification
google._domainkey.pacing.agencyDKIM key (Google)Email authentication
fnt._domainkey.pacing.agencyDKIM key (FrontApp)Email authentication
20250303124725pm._domainkey.pacing.agencyDKIM keyEmail authentication
front-mail.pacing.agencyv=spf1 include:sendgrid.net ~allSPF (FrontApp)
send.updates.pacing.agencyv=spf1 include:amazonses.com ~allSPF (CRM1)
resend._domainkey.updates.pacing.agencyDKIM key (Resend)Email authentication

pacingagency.com​

Name servers:

  • cheryl.ns.cloudflare.com
  • greg.ns.cloudflare.com

A Records:

SubdomainIPProxyPurpose
pacingagency.com49.13.82.194NoTwentyCRM instance
*.pacingagency.com49.13.82.194NoWildcard (TwentyCRM)

MX Records:

SubdomainPriorityTargetPurpose
pacingagency.com1smtp.google.comEmail

TXT Records:

SubdomainValuePurpose
pacingagency.comgoogle-site-verification=iHHzz4QGTEp6CwDG_fZCXxevCBr_zXMYr6n9N3-7lIEGoogle Search Console

pacingagency.co.uk​

Name servers:

  • cheryl.ns.cloudflare.com
  • greg.ns.cloudflare.com

A Records:

SubdomainIPProxyPurpose
pacingagency.co.uk192.0.2.1YesMain redirect (Cloudflare Rules)
mail.pacingagency.co.uk157.90.126.220NoMail server

CNAME Records:

SubdomainTargetProxyPurpose
autoconfig.pacingagency.co.ukmail.pacingagency.co.ukNoEmail autoconfig
autodiscover.pacingagency.co.ukmail.pacingagency.co.ukNoEmail autodiscover
mta-sts.pacingagency.co.ukmail.pacingagency.co.ukNoMTA-STS

MX Records:

SubdomainPriorityTargetPurpose
pacingagency.co.uk10mail.pacingagency.co.ukEmail

TXT Records:

SubdomainValuePurpose
pacingagency.co.ukv=spf1 mx a:mail.pacingagency.co.uk -allSPF record
_dmarc.pacingagency.co.ukv=DMARC1; p=reject; rua=mailto:postmaster@pacingagency.co.ukDMARC policy (reject)
_mta-sts.pacingagency.co.ukv=STSv1; id=20241204MTA-STS

Infrastructure notes​

Hetzner Cloud IPs:

  • 91.98.226.29 - Comments, DAM (ResourceSpace)
  • 91.99.193.35 - Email (Notifuse), Images (Notifuse CDN)
  • 91.98.70.125 - Headshots (HeadshotAI)
  • 91.98.150.95 - N8n
  • 49.13.82.194 - TwentyCRM (pacingagency.com)
  • 157.90.126.220 - Mail server (pacingagency.co.uk)

Other IPs:

  • 134.209.40.56 - API forms, Forms (likely DigitalOcean or similar)
  • 34.36.161.3 - User Journey Tool (Google Cloud Run)

Automation Scripts and Resources​

  • scripts/resources/cloudflare/cloudflare-fetch-zones.sh: Fetches zone information, DNS records, SSL settings, Workers routes, and redirect rules for all three domains via Cloudflare API.
  • Output files: cloudflare-zones-full.json, cloudflare-zones-output.json (stored in scripts/resources/cloudflare/).

n8n Automations​

Cache Clearing on Webflow Publish​

Three active workflows automatically clear Cloudflare cache when Webflow sites are published:

WorkflowZone IDTagsPurpose
Pacing Website - Cache Clear On Publish7b33df94002298798689223a84510c73Pacing, Webflow, CloudflareClears cache for pacing.agency on publish
TTL Website - Cache Clear On Publish(TTL zone)TTL, Webflow, CloudflareClears cache for TTL client site on publish
HML Website - Cache Clear On Publish(HML zone)HML, Webflow, CloudflareClears cache for HML client site on publish

How it works:

  • Webflow sends a webhook to n8n when a site is published
  • n8n workflow receives the webhook and triggers a Cloudflare API call
  • Cloudflare cache is purged using POST /zones/{zone_id}/purge_cache with {"purge_everything": true}
  • Ensures fresh content is served immediately after Webflow publishes

Workflow IDs:

  • Pacing: N11idwXDFWNwGYDh
  • TTL: KowT1FqN6Xk6UoRE
  • HML: lQvLaJJihWpebP6c

See tools/n8n.md for complete workflow documentation and scripts/resources/n8n/ for workflow backups.

Dependencies​

  • DNS and proxy configuration for all three domains.
  • Downstream: GTM loader delivered over Cloudflare edge via Stape.
  • Webflow CDN for main site.
  • Various self-hosted services on Hetzner Cloud.

Zone Configuration​

SSL/TLS Settings​

DomainSSL ModeCertificate StatusLast Modified
pacing.agencyFullActive2025-05-08
pacingagency.comStrictActive2025-10-07
pacingagency.co.ukFlexibleActive2024-07-22

Security Settings​

  • All domains: Security Level set to "Medium"
  • HSTS enabled on main domain

Workers​

pacing.agency​

Route PatternWorker ScriptPurpose
*pacing.agency/sgtm*stape-pacingStape server-side GTM routing

Note: The worker stape-pacing handles requests to /sgtm* paths on the main domain, likely for server-side Google Tag Manager processing via Stape.

Call Tracking System Worker​

Worker Name: pacing-call-tracking
Subdomain: pacing-call-tracking.hello-837.workers.dev
Purpose: Edge API for dynamic number insertion (DNI) and PPC call tracking

Features:

  • Number pool allocation and management
  • Session tracking with Cloudflare KV
  • Attribution data storage (gclid, UTM parameters)
  • Reporting API for call analytics
  • Integration with Twilio Functions for call handling

Storage:

  • KV Namespaces: SESSIONS, CLIENTS, POOL
  • R2 Bucket: pacing-call-records (permanent call record storage)

Related Documentation:

Redirect Rules​

pacingagency.co.uk β†’ pacing.agency​

The redirect from pacingagency.co.uk to pacing.agency is configured via DNS (A record pointing to 192.0.2.1 with proxy enabled). The actual redirect logic is handled by Cloudflare's proxy layer or a Worker (to be confirmed).

Current configuration:

  • DNS A record: pacingagency.co.uk β†’ 192.0.2.1 (proxied)
  • Comment in DNS: "Main Redirect - pacing.agency"
  • No Transform Rules or Bulk Redirects found via API

Page Rules and Cache Rules​

  • No Page Rules currently configured on any domain
  • Cache rules to be documented (if any)

Cloudflare Access (Zero Trust)​

Cloudflare Access provides authentication and access control for internal applications without exposing them to the public internet. It integrates with identity providers like Google OAuth to control who can access protected resources.

Key Features:

  • Google OAuth integration for single sign-on
  • Domain and email-based access policies
  • Edge-based authentication (no code changes required)
  • Session management and access logs
  • Free tier supports up to 50 users

Protected Applications​

Docusaurus Documentation Site​

Application: Tech Stack Docs
Domain: docs.pacing.agency
Application type: Self-hosted (Cloudflare Pages)

Authentication:

  • Identity provider: Google OAuth
  • Login method: Google (with PKCE enabled)
  • Session duration: 24 hours

Access Policy: PacingDocs1

  • Action: Allow
  • Rule: Emails ending in @pacing.agency
  • Additional rules: Can be extended with specific email addresses or other domains

TechStackAnalyser​

Application: TechStackAnalyser
Domain: techstack.pacing.agency
Application type: Self-hosted (Google Cloud Run)

Authentication:

  • Web Interface: Google OAuth (same as Docusaurus)
  • API Access: Service tokens for n8n workflow automation
  • Service Token: See Service Tokens section below

Access Policy: Similar to Docusaurus

  • Action: Allow
  • Rule: Emails ending in @pacing.agency
  • Service Tokens: Separate authentication method for API access

Google OAuth Setup​

Google Cloud Console:

  • Project: pacingdocs
  • OAuth Client ID: 842963103058-2mtfd6kec86botcm4pq123pifknp8v9t.apps.googleusercontent.com
  • Authorised redirect URI: https://pacingagency.cloudflareaccess.com/cdn-cgi/access/callback
  • Authorised JavaScript origin: https://pacingagency.cloudflareaccess.com

Cloudflare Zero Trust:

  • Identity provider: Google
  • PKCE: Enabled (recommended for security)
  • Email claim: Default (email)

Application Settings​

Application name: Tech Stack Docs
Public hostname: docs.pacing.agency
Session duration: 24 hours
Login methods: Google (explicitly selected)

Advanced settings:

  • CORS: Allow all origins (default)
  • HTTP Only cookies: Optional (can be enabled for additional security)
  • Cookie path enforcement: Default

Service Tokens for API Access​

Service tokens are used for programmatic API access to protected applications (e.g., n8n workflows accessing TechStackAnalyser API).

TechStackAnalyser Service Token:

Add these to the root .env file (/.env) for n8n workflow automation:

# Cloudflare Access Service Token for TechStackAnalyser API
CF_ACCESS_CLIENT_ID=
CF_ACCESS_CLIENT_SECRET=

Important Notes:

  • ⚠️ Client secret is only displayed during creation - Save it immediately
  • Add to root .env file only (see docs/ENVIRONMENT_VARIABLES.md in the repo)
  • Used by n8n workflows to authenticate with TechStackAnalyser API
  • Never commit .env files to git (they are gitignored)

Creating New Service Tokens:

  1. Go to Cloudflare Zero Trust β†’ Access β†’ Service Auth
  2. Click "Create Service Token"
  3. Configure token name and expiration
  4. Copy Client ID and Client Secret immediately (secret only shown once)
  5. Add to root .env file for use in automation scripts

Usage in API Requests:

CF-Access-Client-Id: <client-id>
CF-Access-Client-Secret: <client-secret>

See TechStackAnalyser documentation for API usage examples.

Access Policies​

Policies define who can access protected applications. Policies are evaluated in order, and the first matching policy determines access.

Current policy structure:

  1. PacingDocs1: Allows emails ending in @pacing.agency

Adding users:

  • Domain-based: Add "Emails ending in" rule with domain (e.g., @automates.tech)
  • Specific users: Add "Email" rule with individual email addresses
  • Multiple rules: Use OR logic (user needs to match any rule)

Policy actions:

  • Allow: Grants access if rules match
  • Deny: Blocks access (evaluated first)
  • Bypass: Skips authentication (use with caution)

Testing​

Test access:

  1. Visit https://docs.pacing.agency/ in an incognito window
  2. Should redirect to Google OAuth login
  3. After authentication, access is granted if email matches policy
  4. Session persists for 24 hours (or configured duration)

Troubleshooting:

  • OTP shown instead of Google: Check that Google is selected in application login methods
  • "Account does not have access": Verify email matches access policy rules
  • Login loop: Clear browser cookies and try again
  • Policy not working: Use Policy Tester in Zero Trust dashboard to verify user attributes

Management​

Adding new users:

  1. Go to Access β†’ Applications β†’ Tech Stack Docs
  2. Edit the policy (or create a new one)
  3. Add email or domain rule
  4. Save (changes take effect immediately)

Viewing access logs:

  • Zero Trust β†’ Access β†’ Logs
  • Shows login attempts, successful authentications, and denied access

Session management:

  • Users can log out via the Access login page
  • Sessions expire after configured duration
  • Force logout: Revoke access in policy or remove user from allowed list

Troubleshooting – Cloudflare Pages + Docusaurus​

  • Symptom: Cloudflare Pages build for techstackdocs succeeds, but deploy fails with Missing entry-point to Worker script or to assets directory and logs show Executing user deploy command: npx wrangler deploy.
  • Why: This project is a static Docusaurus site on Pages. npx wrangler deploy is for Workers and expects either a Worker entry file (main) or an explicit assets.directory, which we do not configure here.
  • Fix:
    • Keep Root directory = docusaurus, Build command = npm run build, Output directory = build.
    • Set the Deploy command in the Pages settings to a harmless command that always exits 0, for example:
      • echo "Cloudflare Pages will deploy the docusaurus/build output"
    • (Optional) Use the same echo command for the non‑production branch deploy command.
    • Avoid npx wrangler deploy unless you explicitly configure a Worker or assets.directory for a different project.

Security Notes​

  • PKCE is enabled for additional security against CSRF attacks
  • Access is enforced at the edge before requests reach the application
  • No code changes required in the protected application
  • Access logs provide audit trail of who accessed what and when
  • Free tier suitable for small teams (up to 50 users)

Dashboard: https://one.dash.cloudflare.com/
Team domain: pacingagency.cloudflareaccess.com
Account owner: Ben Power
Plan: Free tier (up to 50 users)

TODO​

  • Document zone IDs and basic configuration
  • Document SSL/TLS settings
  • Document Workers routes
  • Document Cloudflare Access (Zero Trust) setup
  • Investigate redirect mechanism for pacingagency.co.uk (likely Worker or Transform Rule not visible via standard API)
  • Document Browser Insights config and sampling
  • Note WAF, bot, and rate-limit rules if active
  • Document cache rules and page rules
  • Document any additional Workers beyond stape-pacing