access-control
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies,…
CDN caching and request rate limiting for Control Plane workloads. Use when the user asks about CDN, Cloudflare, CloudFront, edge caching, rate limiting, request throttling, per-key or per-route limits, or DDoS protection.
Claude Code
$ npx -y skills add controlplane-com/ai-plugin --skill cdn-rate-limiting --agent claude-code
Codex
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a codex -y
Cursor
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a cursor -y
Gemini CLI
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a gemini-cli -y
GitHub Copilot
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a github-copilot -y
OpenCode
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a opencode -y
Windsurf
$ npx skills add controlplane-com/ai-plugin --skill cdn-rate-limiting -a windsurf -y
name: cdn-rate-limiting description: "CDN caching and request rate limiting for Control Plane workloads. Use when the user asks about CDN, Cloudflare, CloudFront, edge caching, rate limiting, request throttling, per-key or per-route limits, or DDoS protection."
Two edge concerns, both built from existing primitives — there is no CDN or rate-limit resource kind. A **CDN** is bring-your-own (Cloudflare / CloudFront) pointed at the workload's canonical endpoint; **rate limiting** is an Envoy ratelimit service you deploy, enabled per workload by `cpln/rateLimit*` **tags**. Assumes the `workload` primer (firewall deny-by-default, canonical URL rules, create-then-verify).
The pattern: the CDN proxies your domain and uses the workload's **canonical endpoint** as origin — read it from `status.canonicalEndpoint` or `mcp__cpln__list_deployments`, never construct it. A **workload endpoint** gives precise geo-routing and per-workload failover; a **GVC endpoint** serves one CDN route for many domains or wildcard subdomains, but keeps sending traffic to every location even when that location's workload is down.
1. **DNS at Cloudflare:** proxied CNAME (orange cloud on) from your subdomain to the canonical endpoint; SSL/TLS mode **Full (strict)**. 2. **Origin certificate** (SSL/TLS, then Origin Server; RSA 2048) becomes a Control Plane **TLS secret** — `create_secret` type `tls` with `values: "user"` (the user types the cert and key in the Console), **TLS chain left empty** (the origin cert is self-signed). 3. **Domain at Control Plane:** `mcp__cpln__create_domain` (CNAME DNS mode), then one `mcp__cpln__update_domain` call: `addPorts` sets the secret as the listener's custom **server certificate** (`tls.serverCertificate.secretLink`) and `addRoutes` routes it to the workload. **The apex domain must be verified before configuring a subdomain.**
1. **ACM public certificate in `us-east-1`** (CloudFront requires that region), DNS validation, covering your subdomain or wildcard. 2. **Distribution:** origin = the workload's canonical endpoint (BYOK: the per-location endpoint from `mcp__cpln__list_deployments`); alternate domain name = your subdomain; attach the ACM cert. 3. **DNS:** CNAME your subdomain to the distribution's `*.cloudfront.net` name.
With a CDN in front, restrict the workload firewall so only CDN traffic reaches it: set `inboundAllowCIDR` to the provider's published ranges ([CloudFront IP ranges](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html)) via `mcp__cpln__update_workload`, and keep the list current. BYOK locations must also admit the ranges in the cluster's ingress security group — the CloudFront list is large, so raise the VPC quota for rules per security group to at least **530**. Details: **firewall-networking**.
Tags on the target workload inject an [Envoy rate-limit filter](https://github.com/envoyproxy/ratelimit) into its **inbound sidecar**: each request makes a gRPC check (1s timeout) against a ratelimit service you deploy (Envoy ratelimit + Redis); over-limit requests get **HTTP 429**.
The stack is one multi-resource manifest from the [rate limiting guide](https://docs.controlplane.com/guides/rate-limiting): the **ratelimit** workload (`envoyproxy/ratelimit`), a **redis** workload, the **ratelimit-config** opaque secret (the rules), and the identity + policy for secret access. The user downloads and reviews it from the guide before it is applied. Create the GVC with `mcp__cpln__create_gvc`; no MCP tool applies a multi-resource manifest, so the apply uses the CLI:
cpln apply --file rate-limiting.yaml --org ORG --gvc ratelimit
The manifest assumes the GVC is named `ratelimit` (edit it if yours differs) and pins an older `envoyproxy/ratelimit` image tag; substitute a newer tag if desired.
**As shipped, the manifest is a trial setup, not a production one:** both workloads run `minScale: 1`. Because enforcement is fail-closed, the ratelimit stack is tier-1 infrastructure for every tagged workload: for production raise its `minScale` to 2+ and run the GVC in the same locations as the workloads it protects (every request pays the check's round trip). A Redis restart only resets counters; a ratelimit outage denies traffic.
Have the user edit the `ratelimit-config` opaque secret, [Envoy ratelimit format](https://github.com/envoyproxy/ratelimit#configuration); `unit`: `second` / `minute` / `hour` / `day`:
domain: cpln
descriptors:
- key: authorization
rate_limit:
unit: minute
requests_per_unit: 10After editing, reload the config: `cpln workload force-redeployment ratelimit --gvc ratelimit`.
Set with `mcp__cpln__update_workload` (or at creation):
| Tag | Required | Default | Meaning | |---|:-:|---|---| | `cpln/rateLimitAddress` | **Yes** | — | Canonical endpoint **hostname** of the ratelimit workload (no scheme prefix) — nothing happens without it | | `cpln/rateLimitDescriptors` | **Effectively yes** | `authority` | Comma-separated: `authorization`, `host`, `path` — the default matches none of them, so **no limiting is applied until you set this** | | `cpln/rateLimitScheme` | No | `https` | `https` dials the service over TLS with SNI | | `cpln/rateLimitPort` | No | `443` | Port of the ratelimit service | | `cpln/rateLimitDomain` | No | `cpln` | Must match `domain` in the config secret |
| Descriptor | Buckets per | HTTP header | |---|---|---| | `authorization` | API key / token | `Authorization` | | `host` | domain | `Host` | | `path` | endpoint | `:path` |
**There is no per-IP descriptor** — these three are the only ones wired. For per-client-IP throttling use the CDN layer (e.g. Cloudflare rate-limiting rules); keep this stack for per-token and per-route limits. Don't
Run containerized workloads across AWS, GCP, Azure, OCI, and your own hardware under one API.
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies,…
Audit trail and compliance on Control Plane. Use when the user asks about audit logs, who changed what, change tracking, audit…
Workload autoscaling and Capacity AI on Control Plane. Use when the user asks about scaling up/down, min/max replicas,…
Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI…
Writes, builds, and deploys an app the user asks for in the chat, with no repository and no image yet. Use when the user asks to…
Custom domains for Control Plane workloads. Use when the user asks to put a domain or subdomain in front of a workload, pick…
Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…
Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…
Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…