INTEGRITY Cloudflare Docs

Custom metadata

You may wish to configure per-hostname (customer) settings beyond the scale of Rules or Rate Limiting.

To do this, you will first need to reach out to your account team to enable access to Custom Metadata. After configuring custom metadata, you can use it in the following ways:


Examples

Please speak with your Solutions Engineer to discuss additional logic and requirements.

Submitting custom metadata

You may add custom metadata to Cloudflare via the Custom Hostnames API. This data can be added via a PATCH request to the specific hostname ID to set metadata for that hostname, for example:

Required API token permissions

At least one of the following token permissions is required:
Edit Custom Hostname
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$CUSTOM_HOSTNAME_ID" \
	--request PATCH \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"ssl": {
				"method": "http",
				"type": "dv"
		},
		"custom_metadata": {
				"customer_id": "12345",
				"redirect_to_https": true,
				"security_tag": "low"
		}
	}'

Changes to metadata will propagate across Cloudflare's edge within 30 seconds.


Accessing custom metadata from a Cloudflare Worker

The metadata object will be accessible on each request using the request.cf.hostMetadata property. You can then read the data, and customize any behavior on it using the Worker.

In the example below we will use the user_id in the Worker that was submitted using the API call above "custom_metadata":{"customer_id":"12345","redirect_to_https": true,"security_tag":"low"}, and set a request header to send the customer_id to the origin:

export default {
	/**
	 * Fetch and add a X-Customer-Id header to the origin based on hostname
	 * @param {Request} request
	 */
	async fetch(request, env, ctx) {
		const customer_id = request.cf.hostMetadata.customer_id;
		const newHeaders = new Headers(request.headers);
		newHeaders.append("X-Customer-Id", customer_id);

		const init = {
			headers: newHeaders,
			method: request.method,
		};
		return fetch(request.url, init);
	},
};
export default {
	/**
	 * Fetch and add a X-Customer-Id header to the origin based on hostname
	 * @param {Request} request
	 */
	async fetch(request, env, ctx): Promise<Response> {
		const customer_id = request.cf.hostMetadata.customer_id;
		const newHeaders = new Headers(request.headers);
		newHeaders.append("X-Customer-Id", customer_id);

		const init = {
			headers: newHeaders,
			method: request.method,
		};
		return fetch(request.url, init);
	},
} satisfies ExportedHandler<Env>;

Accessing custom metadata in a rule expression

Use the cf.hostname.metadata field to access the metadata object in rule expressions. To obtain the different values from the JSON object, use the lookup_json_string function.

The following rule expression defines that there will be a rule match if the security_tag value in custom metadata contains the value low:

lookup_json_string(cf.hostname.metadata, "security_tag") eq "low"

Best practices

General guidance is to follow Google's JSON Style guide where appropriate.


Limitations

There are some limitations to the metadata that can be provided to Cloudflare:

Terraform support

Terraform only allows maps of a single type, so Cloudflare's Terraform support for custom metadata for custom hostnames is limited to string keys and values.