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.