Skip to main content

UNDERSTANDING CLOUDFLARE AUTOMATION IN SWAMP

Cloudflare exposes one API for many different jobs. DNS, firewall rules, edge code, caching and identity-aware access all share the same accounts and tokens. In Swamp, that API reaches the repository through four extensions. Each extension supplies behavior types, and each type's methods map closely onto parts of the Cloudflare API. The sections below cover how the extensions divide the work, how scope and credentials shape the behaviors a team defines, and where the line falls between reading Cloudflare and changing it.

Four extensions, four kinds of work

@webframp/cloudflare covers routine operations. Its zone, dns, waf, worker and cache types each wrap one part of the dashboard, and each method performs one API call: create a record, purge some URLs, deploy a Worker script. @webframp/cloudflare-audit adds no types of its own. It is a workflow and a report that read through those five types and turn what they find into rated findings.

The other two extensions cover Cloudflare One, the Zero Trust product line. @mccormick/cloudflare is deliberately read-only. Its scan method inventories Access applications, policies, identity providers, service tokens and mTLS certificates across every account it is given. A failure on one account or application is recorded as a note and does not stop the scan. @swamp/cloudflare/resource-library takes a different approach. Its applications type treats an Access application as a resource whose state Swamp tracks and reconciles.

The extensions do not compete. A team might audit zones with one, inventory Zero Trust with another, and manage a few Access applications with a third, all from the same repository and the same vault.

Zone scope and account scope

Cloudflare organises most configuration by zone, and the dns, waf and cache types follow that layout: zoneId is a global argument. One behavior therefore serves one zone. A team with three domains defines three DNS behaviors, or one DNS behavior per domain for each type it uses.

Workers are the exception. Scripts belong to the account, not to a zone, so the worker type takes accountId as its global argument. The route methods take zoneId as an input on each call. The zone type sits above both: it needs only a token, and its methods take zoneId per call because listing and comparing zones is its purpose.

This split determines how many behaviors a repository holds. For a handful of zones, defining each behavior by hand is manageable and keeps every definition explicit. For dozens of zones, the factory pattern stamps out one behavior per zone from a shared shape. Then a new zone becomes a data change, not a set of new definitions.

Credentials and vaults

Every type requires a token as a global argument. The @webframp and @swamp types call it apiToken, and the Zero Trust type calls it cloudflareToken. Global arguments are stored in definition files, and definition files usually end up in version control, so the token belongs in a vault. The argument holds a vault.get() expression. Swamp resolves the expression when a method runs and redacts the value wherever it would otherwise appear in output or data. The Storing Secrets tutorial shows this end to end, and the Vaults reference covers the expression and the providers behind it.

Each @webframp type expects a token with different permissions: DNS read and write, Firewall read and write, Workers read and write, Cache Purge, and Zone read and write. A team can issue one broad token and reference it from every behavior. That is simpler to rotate, but anyone who can run any Cloudflare behavior then holds every permission. Alternatively, a team can issue one narrow token per behavior, stored under separate vault keys. This way, a leaked cache token cannot edit DNS. The audit workflow reads through all five types, so it needs a token, or set of tokens, with read access to all of them.

The resource-library type is more flexible. Its apiToken is optional and falls back to the CLOUDFLARE_API_TOKEN environment variable. It also accepts Cloudflare's legacy apiKey and email pair for accounts that still use global API keys. Cloudflare scopes tokens more narrowly than global keys, so tokens are the better default.

Imperative methods and managed state

The @webframp types are imperative. create_rule creates a rule, purge_urls purges, and delete deletes. Swamp records each result as data, but it does not hold a view of what Cloudflare ought to contain. Running create_rule twice creates two rules.

@swamp/cloudflare/resource-library/applications works from state. create, update and delete act on an application whose state Swamp keeps, and sync refreshes that state from Cloudflare. The other two methods bring existing objects under management. adopt imports an existing application by ID. lookup finds one whose attributes match the behavior's global arguments and imports it. This approach suits objects a team wants to declare and keep in line with the declaration. The imperative style suits operational actions such as purges, which have no lasting state to manage. The Data Layer covers how both kinds of result are stored.

What lands in Swamp data

Each type declares the resources it writes. These include DNS records and BIND export, firewall rules and security events, Worker deployment and source, cache purge results and analytics, and the Zero Trust access_app, access_policy and access_summary entries. Because these are versioned data, not terminal output, they can be queried and compared over time. For example, you can compare this week's DNS export with last month's, or see which Access applications appeared since the last scan.

The Zero Trust scan is selective about what it keeps. It records configuration metadata for service tokens and mTLS certificates, never the credential material itself. That makes the scan's output safe to store and share.

Reading and changing production

The methods fall into two groups. The audit workflow, the Zero Trust scan, and methods such as list, export, get_settings and get_security_events only read. Others change live traffic: delete removes a record, pause turns off the proxy for a zone, purge_all sends every request to the origin until the cache refills, and toggle_dev_mode bypasses the cache for three hours.

Where to put controls is a judgement call. Many teams let read-only work run freely, even on a schedule, and put a manual approval gate in front of workflows that delete or pause anything. The Audit System records who ran what. Together with the data each method writes, that answers the question of who changed this zone, and when.

Composing workflows

The audit workflow shows how the pieces combine. Five behaviors, each scoped and credentialed independently, feed one report that has no Cloudflare access of its own. The same structure fits other jobs: export DNS before a migration and after it, or scan Zero Trust and compare the result with the previous scan. The Workflow Execution Model describes how steps run and pass data. Running a workflow on a schedule turns a one-off audit into drift detection: each run's findings land next to the last run's findings, so changes made outside Swamp show up as differences.