Cloudflare ExecModule
Overview
CloudflareModule connects ValkyrAI workflows to Cloudflare API v4 through the native map I/O ExecModule ABI. Workflow Studio discovers it as CloudflareModule. A scoped API token resolves only from a bound READY IntegrationAccount; workflow input cannot provide credentials or redirect requests to arbitrary hosts.
The first production operation set focuses on the infrastructure controls most useful to governed agents:
- identity:
verify_token; - zones:
list_zones,get_zone; - DNS:
list_dns_records,get_dns_record,create_dns_record,update_dns_record,delete_dns_record; - cache:
purge_cache; - settings:
get_zone_setting,update_zone_setting.
This surface uses n8n's official Cloudflare node as the functional integration reference and Cloudflare's current zone, DNS, cache, and setting APIs for the production contract. Lists use bounded page pagination. Provider responses and errors are size-limited and redacted. Only GET requests retry automatically; writes run once because their outcome can be ambiguous after a timeout.
Usage
- Create a dedicated Cloudflare API token for the automation identity.
- Grant only the zone, DNS, cache-purge, and zone-setting permissions the workflow needs.
- Restrict the token to the specific Cloudflare account and zones whenever possible.
- Store the token in the encrypted
apiKeyfield of anIntegrationAccountand set its status toREADY. - Bind the account through
ExecModuleConfig.authConfig.integrationAccount. - Use
list_zonesandlist_dns_recordsto resolve current IDs before any mutation.
Inputs
| Name | Type | Requirement | Default | Description and constraints |
|---|---|---|---|---|
operation | string | Required | None | One of the eleven operations above. |
zoneId | string | Zone-scoped operations | None | Cloudflare zone ID, 1–64 letters, digits, _, or -. |
dnsRecordId | string | Get, update, or delete DNS record | None | Cloudflare DNS record ID with the same bound. |
settingId | string | Zone-setting operations | None | One allowlisted setting: always_online, always_use_https, automatic_https_rewrites, brotli, browser_cache_ttl, cache_level, development_mode, http2, http3, min_tls_version, opportunistic_encryption, or ssl. |
settingValue | scalar/object/JSON string | update_zone_setting | None | Provider-compatible setting value, maximum 16 KiB. |
name | string | DNS create; optional list filter/update | None | Bounded DNS name or exact zone-name filter. |
type | string | DNS create; optional list filter/update | None | Supported Cloudflare DNS type such as A, AAAA, CNAME, MX, TXT, CAA, SRV, HTTPS, or SVCB. |
content | string | DNS create; optional list filter/update | None | DNS record content, 1–4,096 characters. |
ttl | integer | Optional DNS create/update | 1 on create | 1 for automatic or 60–86,400 seconds. |
proxied | boolean | Optional DNS list/create/update | None | Cloudflare proxy selection for compatible records. |
comment | string | Optional DNS create/update | None | Bounded record comment, maximum 500 characters. |
record | object or JSON string | Optional DNS create/update | None | Allowlisted provider fields only: type, name, content, ttl, proxied, priority, comment, tags, and data; 256 KiB cap. |
zoneStatus | string | Optional zone list | None | initializing, pending, active, or moved. |
accountId | string | Optional zone list | None | Exact Cloudflare account ID filter. |
match | string | Optional lists | all | all or any. |
page | integer | Optional list continuation | 1 | Starting page from 1 through 1,000,000. |
limit | integer | Optional lists | 100 | Maximum returned resources, 1–10,000. |
returnAll | boolean | Optional lists | false | Follow pages to exhaustion or the 10,000-item cap. |
confirmDelete | boolean | delete_dns_record | false | Must be true before permanent DNS deletion. |
purgeFiles | array/JSON string | One purge selector | None | One through 30 HTTPS URLs. |
purgeTags | array/JSON string | One purge selector | None | One through 30 cache tags. |
purgeHosts | array/JSON string | One purge selector | None | One through 30 valid hostnames. |
purgePrefixes | array/JSON string | One purge selector | None | One through 30 bounded prefixes. |
purgeEverything | boolean | One purge selector | false | Full-zone cache purge. |
confirmPurgeEverything | boolean | Full purge only | false | Must be true with purgeEverything. |
Typed inputs override matching allowlisted record fields. Create always requires validated type, name, and content. Update requires at least one allowlisted field and cannot pass headers, authentication, arbitrary URLs, or unsupported provider properties.
Outputs
| Name | Type | When present | Description |
|---|---|---|---|
status | string | Always | success or error. |
operation | string | Always | Normalized operation name. |
attempts | integer | Always | Total provider attempts across pages. |
httpStatus | integer | Provider responded | Last Cloudflare HTTP status. |
data | object | Single-resource/mutation success | Cloudflare result object or scalar. |
id, name, providerStatus | string | Provider returns field | Safe convenience fields. |
items / count | array / integer | List success | Bounded provider resources and emitted count. |
hasMore / nextPage | boolean / integer | List success | Provider continuation state. |
requestId | string | Provider supplies one | Cloudflare Ray ID or provider trace reference. |
error | object | Failure | Safe {code, message, httpStatus?, retryable} details. |
Tokens and authorization headers never enter outputs. Provider messages pass through ValkyrAI's shared workflow sensitive-data policy.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Cloudflare API v4 |
| Authentication | Scoped API token sent as Authorization: Bearer … |
accountName | Human-readable automation identity |
accountId | Optional Cloudflare account reference for operators; not used as a credential |
apiKey | Preferred encrypted SecureField containing the token |
password | Encrypted fallback only; prefer apiKey |
status | Must be READY |
Recommended least-privilege token permissions depend on selected operations:
- token verification: the token itself must be active;
- zone discovery: Zone / Zone / Read;
- DNS reads: Zone / DNS / Read;
- DNS writes: Zone / DNS / Edit;
- cache purge: Zone / Cache Purge / Purge;
- zone setting writes: Zone / Zone Settings / Edit.
Do not use a Global API key. Token creation, rotation, revocation, and OAuth refresh belong to the platform IntegrationAccount lifecycle, never workflow inputs.
Configuration
{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:cloudflare-production-dns"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_dns_records\",\"zoneId\":\"023e105f4ecef8ad9ca31a8372d0c353\",\"type\":\"CNAME\",\"limit\":100}"
}
}
The integration-account value is symbolic. Persisted workflows use the generated relationship and never a plaintext token.
Operations
| Operation | Cloudflare behavior | Side effect |
|---|---|---|
verify_token | Reads the current scoped token status. | Read-only; safe retries. |
list_zones | Lists zones with bounded account, name, status, and match filters. | Read-only; safe retries. |
get_zone | Reads one zone. | Read-only; safe retries. |
list_dns_records | Lists records with bounded name, type, content, proxy, and match filters. | Read-only; safe retries. |
get_dns_record | Reads one DNS record. | Read-only; safe retries. |
create_dns_record | Creates one allowlisted record. | New DNS state; single attempt. |
update_dns_record | Partially updates allowlisted record fields. | DNS mutation; single attempt. |
delete_dns_record | Permanently removes a record after confirmDelete=true. | Destructive; single attempt. |
purge_cache | Purges exactly one selector: files, tags, hosts, prefixes, or the entire zone. | Cache invalidation; single attempt. |
get_zone_setting | Reads one allowlisted zone setting. | Read-only; safe retries. |
update_zone_setting | Updates one allowlisted zone setting. | Configuration mutation; single attempt. |
Errors and Failure Modes
| Code | Typical cause | Retryable | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Missing/invalid account, ID, DNS name/type/content, setting, selector, confirmation, JSON, or bound. | No | Correct input; no unsafe request was sent. |
UNSUPPORTED_OPERATION | Unknown operation. | No | Select a documented operation. |
INTEGRATION_ACCOUNT_REQUIRED | No bound account. | No | Bind a Cloudflare IntegrationAccount. |
INTEGRATION_ACCOUNT_NOT_READY | Account is not READY. | No | Repair or reconnect the account. |
CLOUDFLARE_API_ERROR | HTTP succeeded but Cloudflare returned success: false. | No by default | Inspect the safe provider code/message and correct scope or payload. |
CLOUDFLARE_HTTP_400 | Provider rejected a filter or payload. | No | Correct the bounded request. |
CLOUDFLARE_HTTP_401 / 403 | Token invalid, inactive, or missing minimum scope. | No | Rotate or re-scope the token. |
CLOUDFLARE_HTTP_404 | Zone, record, or setting is absent or invisible. | No | Re-run discovery with the same account. |
CLOUDFLARE_HTTP_429 / 5xx | Rate limit or transient provider failure. | Yes for GET | Honor provider timing; reconcile writes before repeating. |
NETWORK_ERROR | Timeout, DNS, TLS, or connectivity failure. | Yes for GET | Verify connectivity and inspect Cloudflare state before repeating a write. |
RESPONSE_TOO_LARGE | Response exceeded 5 MiB. | No | Narrow filters or lower the limit. |
INVALID_PROVIDER_RESPONSE | success, result, list shape, or pagination is inconsistent. | No | Use requestId and verify API compatibility. |
Example
Create a proxied CNAME after a deployment workflow verifies the origin health:
{
"operation": "create_dns_record",
"zoneId": "023e105f4ecef8ad9ca31a8372d0c353",
"type": "CNAME",
"name": "api.example.com",
"content": "origin.example.net",
"ttl": 1,
"proxied": true,
"comment": "Managed by ValkyrAI deployment workflow"
}
Expected result:
{
"status": "success",
"operation": "create_dns_record",
"attempts": 1,
"httpStatus": 200,
"id": "372e67954025e0ba6aaa6d586b9e0b59",
"name": "api.example.com",
"data": {
"id": "372e67954025e0ba6aaa6d586b9e0b59",
"type": "CNAME",
"name": "api.example.com",
"content": "origin.example.net",
"proxied": true
}
}
Notes
- Pagination: zone and DNS lists use
page,per_page, andresult_info.total_pages. Pages request at most 100 resources and total output never exceeds 10,000. An empty page beforetotal_pagesfails closed. - Rate limits: GET operations retry HTTP 408, 429, 500, 502, 503, and 504 according to
RetryPolicy, honoring numericRetry-After. Creates, updates, deletes, setting changes, and purges never retry automatically. - API limits: provider responses are capped at 5 MiB, structured DNS bodies at 256 KiB, setting bodies at 16 KiB, purge selectors at 30 values, and text fields at their documented module bounds. Cloudflare plan and account limits still apply.
- Idempotency: reads are retry-safe. DNS creates, partial updates, deletes, setting changes, and cache purges are single-attempt. Re-read the zone, record, setting, or cache state before repeating a request whose response was lost.
- Destructive behavior: DNS deletion requires
confirmDelete=true. A full cache purge requires bothpurgeEverything=trueandconfirmPurgeEverything=true.purge_cacheaccepts exactly one selector to prevent unintended broadening. - Security: credentials remain in IntegrationAccount SecureFields. The fixed Cloudflare API origin, encoded path segments, allowlisted payloads/settings, bounded responses, and redacted errors prevent arbitrary routing or token reflection.
- External verification: request construction, pagination, validation, retry safety, redaction, payload mapping, destructive guards, and metadata discovery are deterministic local tests. Live Cloudflare scopes, plan entitlements, DNS propagation, proxy behavior, and cache invalidation require separately authorized provider credentials and are not exercised in repository tests.
- Deferred operations: zone create/delete, account administration, Workers, R2, Pages, Access, WAF rulesets, load balancing, tunnels, SSL certificate upload, analytics, webhooks/triggers, legacy Global API key auth, and arbitrary raw requests.
- Functional references: n8n Cloudflare node source, Cloudflare zone API, Cloudflare DNS records API, and Cloudflare cache purge API.