Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ cfctl guide edge.certificate order --zone example.com --host app.example.com --h
cfctl hostname verify --file state/hostname/example.yaml
```

Before choosing a write path, scan [docs/capabilities.md](docs/capabilities.md).
It is generated from the catalogs and shows the read/plan/apply/verify contract,
including preview requirements, destructive confirmations, lane policy,
selectors, and desired-state sync support.

Before credentials exist, `cfctl doctor` reports `bootstrap_required` and points
at `cfctl bootstrap permissions`; `cfctl doctor --strict` still fails until a
healthy token lane exists.
Expand Down Expand Up @@ -208,7 +213,7 @@ zone, such as `CF_TOKEN_LANE=global CFCTL_PUBLIC_CONTRACT_ZONE=example.com
operator policy for these credentials is in
[docs/permission-doctrine.md](docs/permission-doctrine.md).

See [docs/runbooks/cfctl.md](docs/runbooks/cfctl.md) and [docs/capabilities.md](docs/capabilities.md) for the full reference.
See [docs/runbooks/cfctl.md](docs/runbooks/cfctl.md) and [docs/capabilities.md](docs/capabilities.md) for the full reference. `docs/capabilities.md` is generated from the catalogs and is the fastest way to see which surfaces are read-only, which operations are preview-gated, which destructive operations require confirmation, and which surfaces support desired-state sync.

## Layout

Expand Down Expand Up @@ -315,7 +320,7 @@ targeted retry does not shrink accepted domains to only the retry subset.
- [CFCTL_PROMPT.md](CFCTL_PROMPT.md) — strict embedding prompt for tool integrators
- [docs/agent-landing.md](docs/agent-landing.md)
- [docs/auth.md](docs/auth.md)
- [docs/capabilities.md](docs/capabilities.md) — generated from catalogs
- [docs/capabilities.md](docs/capabilities.md) — generated from catalogs; includes the read/plan/apply/verify operation matrix
- [docs/config-standards.md](docs/config-standards.md)
- [docs/cloudflare-doc-bank.md](docs/cloudflare-doc-bank.md)
- [docs/runtime-policy.md](docs/runtime-policy.md)
Expand Down
3 changes: 2 additions & 1 deletion docs/agent-landing.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Start by naming the job class:
- External command auth bridge:
run `cfctl env run --lane dev -- <command> [args...]` when another repo owns deploy semantics but `cfctl` owns Cloudflare credential hydration. Never pass secrets as command args because argv is recorded as evidence.
- Mutation:
read state, load standards, classify, guide, preview with `--plan`, apply with `--ack-plan <operation-id>`, then verify.
read state, scan the generated matrix in [docs/capabilities.md](capabilities.md), load standards, classify, guide, preview with `--plan`, apply with `--ack-plan <operation-id>`, then verify.
- Runtime development:
change `cfctl`, catalogs, docs, and contract checks together; do not document a public capability before it exists in the catalog and command surface.
- Degraded trust:
Expand All @@ -36,6 +36,7 @@ Do not turn a source-config audit into a live Cloudflare claim. If the question
```bash
cfctl doctor
cfctl surfaces
cfctl explain surfaces
cfctl docs
cfctl docs watch
cfctl standards audit
Expand Down
126 changes: 98 additions & 28 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,104 @@ _Generated from `catalog/surfaces.json` and `catalog/runtime.json`. Edit the cat

This table is the operable runtime surface. The standards layer and docs bank intentionally cover more Cloudflare territory than `cfctl` can currently mutate or verify directly.

| Surface | Read | Apply | Desired State | Standards | Docs Topics | Module |
| --- | --- | --- | --- | --- | --- | --- |
| `access.app` | yes | yes | yes | `access.app` | `zero-trust-api, api-auth` | `access_app` |
| `access.policy` | yes | yes | yes | `access.policy` | `zero-trust-api, api-auth` | `access_policy` |
| `api_gateway.discovery` | yes | no | no | `-` | `api-gateway, api-auth` | `-` |
| `api_gateway.operation` | yes | no | no | `-` | `api-gateway, api-auth` | `-` |
| `api_gateway.schema` | yes | no | no | `-` | `api-gateway, api-auth` | `-` |
| `audit.log` | yes | no | no | `-` | `audit-logs, api-auth` | `-` |
| `d1.database` | yes | no | no | `-` | `-` | `-` |
| `dns.record` | yes | yes | yes | `dns.record` | `api-auth` | `dns_record` |
| `edge.certificate` | yes | yes | no | `edge.certificate` | `advanced-certificates, api-auth` | `edge_certificate` |
| `email.routing_rule` | yes | yes | no | `-` | `email-routing, api-auth` | `-` |
| `logpush.job` | yes | yes | no | `-` | `-` | `-` |
| `pages.project` | yes | no | no | `-` | `-` | `-` |
| `queue` | yes | no | no | `-` | `-` | `-` |
| `r2.bucket` | yes | no | no | `-` | `-` | `-` |
| `tunnel` | yes | yes | yes | `tunnel` | `api-auth` | `tunnel` |
| `turnstile.widget` | yes | yes | no | `-` | `-` | `-` |
| `vulnerability_scanner.credential_set` | yes | no | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `vulnerability_scanner.scan` | yes | no | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `vulnerability_scanner.target_environment` | yes | no | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `waiting_room` | yes | yes | no | `-` | `-` | `-` |
| `worker.route` | yes | yes | no | `worker.route` | `workers-routes, api-auth` | `worker_route` |
| `worker.script` | yes | yes | no | `-` | `-` | `worker_script` |
| `worker.secret` | yes | yes | no | `-` | `-` | `worker_secret` |
| `workflow` | yes | no | no | `-` | `-` | `-` |
| `zone` | yes | no | no | `-` | `-` | `-` |
| `zone.ruleset` | yes | yes | no | `-` | `ruleset-engine, api-auth` | `-` |
| Surface | Read | Can | Apply | Verify | Desired State | Standards | Docs Topics | Module |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `access.app` | yes | yes | yes | yes | yes | `access.app` | `zero-trust-api, api-auth` | `access_app` |
| `access.policy` | yes | yes | yes | yes | yes | `access.policy` | `zero-trust-api, api-auth` | `access_policy` |
| `api_gateway.discovery` | yes | yes | no | yes | no | `-` | `api-gateway, api-auth` | `-` |
| `api_gateway.operation` | yes | yes | no | yes | no | `-` | `api-gateway, api-auth` | `-` |
| `api_gateway.schema` | yes | yes | no | yes | no | `-` | `api-gateway, api-auth` | `-` |
| `audit.log` | yes | yes | no | yes | no | `-` | `audit-logs, api-auth` | `-` |
| `d1.database` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `dns.record` | yes | yes | yes | yes | yes | `dns.record` | `api-auth` | `dns_record` |
| `edge.certificate` | yes | yes | yes | yes | no | `edge.certificate` | `advanced-certificates, api-auth` | `edge_certificate` |
| `email.routing_rule` | yes | yes | yes | yes | no | `-` | `email-routing, api-auth` | `-` |
| `logpush.job` | yes | yes | yes | yes | no | `-` | `-` | `-` |
| `pages.project` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `queue` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `r2.bucket` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `tunnel` | yes | yes | yes | yes | yes | `tunnel` | `api-auth` | `tunnel` |
| `turnstile.widget` | yes | yes | yes | yes | no | `-` | `-` | `-` |
| `vulnerability_scanner.credential_set` | yes | yes | no | yes | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `vulnerability_scanner.scan` | yes | yes | no | yes | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `vulnerability_scanner.target_environment` | yes | yes | no | yes | no | `-` | `api-shield-vulnerability-scanner, api-auth` | `-` |
| `waiting_room` | yes | yes | yes | yes | no | `-` | `-` | `-` |
| `worker.route` | yes | yes | yes | yes | no | `worker.route` | `workers-routes, api-auth` | `worker_route` |
| `worker.script` | yes | yes | yes | yes | no | `-` | `-` | `worker_script` |
| `worker.secret` | yes | yes | yes | yes | no | `-` | `-` | `worker_secret` |
| `workflow` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `zone` | yes | yes | no | yes | no | `-` | `-` | `-` |
| `zone.ruleset` | yes | yes | yes | yes | no | `-` | `ruleset-engine, api-auth` | `-` |

## Operation Contract Matrix

This matrix is derived from the same catalogs used by `cfctl explain`, `cfctl classify`, `cfctl guide`, and the static verifier. It is the preflight view for deciding whether a surface is read-only, preview-gated, destructive, lane-sensitive, or desired-state-backed.

| Surface | Operation | Risk | Preview | Lock | Verify After Apply | Confirmation | Allowed Lanes | Selectors |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `access.app` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `access.app` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: id |
| `access.app` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: id |
| `access.app` | `sync` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | state match: id, name, domain |
| `access.policy` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: app_id |
| `access.policy` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: app_id, policy_id |
| `access.policy` | `make-reusable` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: app_id, policy_id |
| `access.policy` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: app_id, policy_id |
| `access.policy` | `sync` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | state match: app_id, policy_id, name |
| `dns.record` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, name, type |
| `dns.record` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: zone; one of: id / name, type |
| `dns.record` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone; one of: id / name, type |
| `dns.record` | `upsert` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, name, type |
| `dns.record` | `sync` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | state match: zone, id, name, type |
| `edge.certificate` | `order` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone |
| `email.routing_rule` | `upsert` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, name, service |
| `logpush.job` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `logpush.job` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: id |
| `logpush.job` | `ownership` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `logpush.job` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: id |
| `logpush.job` | `validate-destination` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `logpush.job` | `validate-origin` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `logpush.job` | `validate-ownership` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `tunnel` | `cleanup-connections` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: id |
| `tunnel` | `configure` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: id |
| `tunnel` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `tunnel` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: id |
| `tunnel` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: id |
| `tunnel` | `sync` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | state match: id, name |
| `turnstile.widget` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | - |
| `turnstile.widget` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: sitekey |
| `turnstile.widget` | `rotate-secret` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: sitekey |
| `turnstile.widget` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: sitekey |
| `waiting_room` | `create` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone |
| `waiting_room` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: zone, id |
| `waiting_room` | `patch` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, id |
| `waiting_room` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, id |
| `worker.route` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: zone; one of: id / pattern |
| `worker.script` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: name |
| `worker.script` | `upsert` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: name, metadata, module |
| `worker.secret` | `delete` | `destructive` | yes | `lease` | yes | `delete` | `dev`, `global` | required: script, name |
| `worker.secret` | `upsert` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: script, name |
| `zone.ruleset` | `update` | `write` | yes | `apply` | yes | `-` | `dev`, `global` | required: zone, id |

## Read-Only Surfaces

These surfaces are first-class read surfaces but do not expose `apply` or desired-state `sync` today. Mutation should not be inferred from an inventory script alone.

| Surface | Public Actions | List Selectors | Inventory Backend |
| --- | --- | --- | --- |
| `api_gateway.discovery` | `list`, `get`, `verify`, `can` | required: zone | `scripts/cf_inventory_api_gateway.sh` |
| `api_gateway.operation` | `list`, `get`, `verify`, `can` | required: zone | `scripts/cf_inventory_api_gateway.sh` |
| `api_gateway.schema` | `list`, `get`, `verify`, `can` | required: zone | `scripts/cf_inventory_api_gateway.sh` |
| `audit.log` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_audit_logs.sh` |
| `d1.database` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_d1.sh` |
| `pages.project` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_pages.sh` |
| `queue` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_queues.sh` |
| `r2.bucket` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_r2.sh` |
| `vulnerability_scanner.credential_set` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_vulnerability_scanner.sh` |
| `vulnerability_scanner.scan` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_vulnerability_scanner.sh` |
| `vulnerability_scanner.target_environment` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_vulnerability_scanner.sh` |
| `workflow` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_workflows.sh` |
| `zone` | `list`, `get`, `verify`, `can` | - | `scripts/cf_inventory_zones.sh` |

Composite lifecycle commands:
- `cfctl hostname verify --file state/hostname/<name>.yaml`
Expand Down
6 changes: 6 additions & 0 deletions docs/runbooks/cfctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ It is built for agent and operator use:
- `explain` for the machine-readable contract of a surface
- `diff` for selective desired-state comparison

[docs/capabilities.md](../capabilities.md) is the generated repo-wide contract
matrix. Use it before writing to see read-only surfaces, preview requirements,
destructive confirmations, allowed lanes, selector requirements, verification
expectations, and desired-state sync support in one place.

## Core Examples

```bash
Expand Down Expand Up @@ -99,6 +104,7 @@ CF_TOKEN_LANE=global cfctl apply edge.certificate order --zone example.com --hos
- commands emit a stable JSON result envelope
- every result includes active auth lane and auth scheme
- `standards` returns the canonical configuration standards catalog or one surface-specific standard set
- `docs/capabilities.md` is generated from `catalog/surfaces.json` and `catalog/runtime.json`; edit the catalogs when the public contract changes
- `docs` returns the curated official Cloudflare docs bank, either as a compact overview or one tracked topic
- `docs` includes freshness metadata so the bank does not masquerade as auto-refreshed truth
- `standards audit` scans the active Wrangler footprint under a root and reports standards coverage plus per-file findings
Expand Down
5 changes: 5 additions & 0 deletions docs/runbooks/live-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ cfctl snapshot tunnel
CF_TOKEN_LANE=global cfctl diff dns.record --zone example.com
```

For the repo-wide read/write boundary, use
[../capabilities.md](../capabilities.md). It is generated from the catalogs and
separates read-only inventory surfaces from preview-gated apply and
desired-state sync surfaces.

## Runtime-First Reads

Use `cfctl` when you want a stable public interface:
Expand Down
6 changes: 6 additions & 0 deletions docs/runbooks/tool-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ It gives agents and operators:
- structured runtime results
- consistent verification semantics

Use [../capabilities.md](../capabilities.md) when the first question is which
surface owns a task, whether that surface is read-only, whether an operation is
preview-gated or destructive, and which selectors are required. The matrix is
generated from `catalog/surfaces.json` and `catalog/runtime.json`, not hand-kept
operator prose.

## Use Direct API Wrappers For

- account-wide inventory
Expand Down
Loading
Loading