cloudflare

package
v1.801.490 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package cloudflare is your Cloudflare account, managed from Hanzo: zones, Pages, Workers, Workers AI, R2, KV and D1.

It is the per-org Cloudflare asset plane for the unified Hanzo Cloud binary — the first-class /v1/cloudflare/* surface (sibling of /v1/dns and /v1/domain) that drives an org's Zones/Analytics, Pages, Workers, Workers AI, R2, KV, and D1 through the SAME per-org, KMS-sealed API token the org connected via apps/integrations. Connecting the provider stays on the integrations plane (/v1/integrations/cloudflare/{connect,callback}); MANAGING the resources is this first-class plane — "how you connected" and "what you manage" are separated, one concern each. Every call drives Cloudflare with the org's own scoped token, so the platform never reaches Cloudflare with a global env token — one token, one custody boundary, one org.

Workers AI is the one exception to pure passthrough: an /ai/run is INFERENCE, so it meters through the SAME unified usage/billing spine (cloud.AIMeterProvider) and emits to the SAME gen_ai o11y span plane as every other model call — at the thin BYO fee, since the org's own token already paid Cloudflare for the compute. There is no Cloudflare-specific usage or o11y path.

TENANT ISOLATION (the crown jewel). Every handler resolves the caller's org from the VALIDATED principal (principal.Org → the X-Org-Id the identity boundary minted from a verified credential, HIP-0026 / SanitizeIdentity), NEVER from a body or query field. The org is then the ONLY input to token custody: the per-org token is read in-process through the ONE seam integrations.TokenFor, which keys KMS on that org (/orgs/{org}/integrations/cloudflare/api_token). So a request can ONLY ever address its own org's Cloudflare account:

  • no validated principal ⟹ principal.Org fails ⟹ 403 (a forged X-Org-Id with no bearer is refused by the identity boundary, then again here);
  • a non-SuperAdmin bearer has X-Org-Id pinned to its own owner (SanitizeIdentity), so it cannot name another org;
  • cross-org token reach is structurally impossible — the token path is derived from the validated org, not from any caller-controlled field.

The token rides ONLY the Authorization header on the outbound Cloudflare request; it is never logged, echoed in an error, or stored by this subsystem.

FAIL-CLOSED. An org that has not connected Cloudflare, an unmounted integrations plane, or a KMS that is not Ready each yield an error and a 503 — never another org's data and never a silent success.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mount

func Mount(app cloud.Router, deps cloud.Deps) error

Mount wires /v1/cloudflare/* onto app. The subsystem holds no store and runs no goroutine: it reads the per-org token in-process per request and proxies to Cloudflare. The build closure captures deps to construct the "ai"-provider meter (Base.Bill is provider "cloudflare"; Workers AI must bill under "ai").

Types

type D1Query added in v1.801.350

type D1Query struct {
	// SQL is the statement to run. Required.
	SQL string `json:"sql"`
	// Params are the statement's bound values, in the order its placeholders appear.
	Params []any `json:"params,omitempty"`
}

D1Query is the shape this plane's query route takes, DECLARED for the document (openapi.Register, cloudflare.go) rather than bound by the handler. The handler forwards the caller's body to D1 verbatim, so there is no Go struct it could bind that would also state the shape — binding one is exactly the field loss the route refuses. It reads `sql` off the body to require it, and nothing else; this states the two fields D1 itself takes, and the schema is an OPEN object, so a field D1 accepts that is not named here still reaches D1 unchanged.

type PagesBuildConfig

type PagesBuildConfig struct {
	BuildCommand   string `json:"build_command,omitempty"`
	DestinationDir string `json:"destination_dir,omitempty"`
	RootDir        string `json:"root_dir,omitempty"`
}

PagesBuildConfig is the project build config.

type PagesD1Binding

type PagesD1Binding struct {
	ID string `json:"id"`
}

type PagesDeploy added in v1.801.350

type PagesDeploy struct {
	// Branch is the branch to build. Omit it to build the project's production branch.
	Branch string `json:"branch"`
}

PagesDeploy is the deploy request body: the branch to build. It is the whole shape this route reads, so it is also what the document declares for it (openapi.Register, cloudflare.go) — one struct, bound by the handler and reflected by the spec, so the published contract cannot drift from the code.

type PagesDeploymentConfig

type PagesDeploymentConfig struct {
	CompatibilityDate  string                    `json:"compatibility_date,omitempty"`
	CompatibilityFlags []string                  `json:"compatibility_flags,omitempty"`
	EnvVars            map[string]PagesEnvVar    `json:"env_vars,omitempty"`
	KVNamespaces       map[string]PagesKVBinding `json:"kv_namespaces,omitempty"`
	D1Databases        map[string]PagesD1Binding `json:"d1_databases,omitempty"`
	R2Buckets          map[string]PagesR2Binding `json:"r2_buckets,omitempty"`
}

PagesDeploymentConfig is a preview/production deployment config.

type PagesDeploymentConfigs

type PagesDeploymentConfigs struct {
	Preview    *PagesDeploymentConfig `json:"preview,omitempty"`
	Production *PagesDeploymentConfig `json:"production,omitempty"`
}

PagesDeploymentConfigs pairs the preview + production deployment configs.

type PagesEnvVar

type PagesEnvVar struct {
	Value string `json:"value"`
	Type  string `json:"type,omitempty"`
}

PagesEnvVar is one deployment env var (plain_text | secret_text).

type PagesKVBinding

type PagesKVBinding struct {
	NamespaceID string `json:"namespace_id"`
}

PagesKVBinding / PagesD1Binding / PagesR2Binding are the deployment-config resource bindings (ported from PagesDeploymentConfig).

type PagesProjectCreate

type PagesProjectCreate struct {
	Name              string                  `json:"name"`
	ProductionBranch  string                  `json:"production_branch,omitempty"`
	BuildConfig       *PagesBuildConfig       `json:"build_config,omitempty"`
	DeploymentConfigs *PagesDeploymentConfigs `json:"deployment_configs,omitempty"`
}

PagesProjectCreate is the create-project request body (ported from PagesProjectCreateParams). The platform sends {name, production_branch}; the full shape is modeled so a richer caller is forwarded faithfully.

type PagesR2Binding

type PagesR2Binding struct {
	Name string `json:"name"`
}

type PurgeCache

type PurgeCache struct {
	Everything bool     `json:"purge_everything,omitempty"`
	Files      []string `json:"files,omitempty"`
}

PurgeCache is the body of a zone cache purge. Exactly one selector may be set: Everything drops the zone's entire edge cache; Files purges the listed URLs. Cloudflare also accepts tags/hosts/prefixes, which are Enterprise-only and are deliberately not modeled — an unmodeled field would silently no-op on our plan.

type WorkerScriptPut

type WorkerScriptPut struct {
	Script             string          `json:"script"`
	MainModule         string          `json:"mainModule,omitempty"`
	CompatibilityDate  string          `json:"compatibilityDate,omitempty"`
	CompatibilityFlags []string        `json:"compatibilityFlags,omitempty"`
	Bindings           json.RawMessage `json:"bindings,omitempty"`
}

WorkerScriptPut is the upload request for a Workers module script. Script is the ES-module source; MainModule names the entry file (default "worker.js"). CompatibilityDate/Flags and Bindings ride the multipart metadata part. It is the struct the handler binds AND what the document declares for the route (openapi.Register, cloudflare.go), so the published contract follows the code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL