cdn-rate-limiting — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cdn-rate-limiting (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
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).mcp__cpln__create_domain (CNAME DNS mode), mcp__cpln__set_domain_tls with the secret as the custom server certificate, mcp__cpln__add_domain_route to the workload. The apex domain must be verified before configuring a subdomain.mcp__cpln__list_deployments); alternate domain name = your subdomain; attach the ACM cert.*.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) 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 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: 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 ratelimitThe 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 with spot: true. Because enforcement is fail-closed, the ratelimit stack is tier-1 infrastructure for every tagged workload — for production raise its minScale to 2+, set spot: false, 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; 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 invent a remote_address descriptor — it does nothing.
cpln/rateLimitDescriptors: authorization,path produces one compound key (an ordered tuple), not two independent limits. The config must nest in the same order as the tag's comma order:
domain: cpln
descriptors:
- key: authorization # first tag entry
descriptors:
- key: path # second tag entry — nested, not a sibling
rate_limit:
unit: minute
requests_per_unit: 60This buckets per token-and-path pair (any values). Add value: under a key to pin one route or token (e.g. key: path, value: /api/search). Two genuinely independent limits are not expressible through the tags — the filter emits a single action tuple.
Anonymous-bypass warning: Envoy skips the rate-limit check entirely when a descriptor header is missing from the request (skip_if_absent defaults to false and the filter doesn't set it). With authorization in the list, requests without an Authorization header are never checked — including the sample 10/minute config above. Limit by path or host (always present) when anonymous traffic matters, or throttle it at the CDN.
failure_mode_deny: true and a 1s check timeout — if the ratelimit service is down, unreachable, or the address is wrong, inbound requests are denied, not passed through. Verify the ratelimit workload is Ready (mcp__cpln__list_deployments) before tagging the target, and treat a typo in cpln/rateLimitAddress as an outage.authority produces an empty action list — the filter runs but limits nothing.Traffic passes, in order: the CDN (absorbs and caches), then the firewall (inboundAllowCIDR = CDN IPs only, so nobody bypasses the CDN), then rate limiting (catches abuse that passes the CDN), then the workload.
Authorization header gets 429. After any rules edit, force-redeployment the ratelimit workload first.curl -I https://SUBDOMAIN shows the CDN's header (cf-cache-status on Cloudflare, x-cache on CloudFront).curl the canonical endpoint directly — after the firewall lock-down it must no longer answer from outside the CDN ranges.| Symptom | Likely cause |
|---|---|
| Every request denied | Ratelimit service down/unready, or cpln/rateLimitAddress wrong — enforcement is fail-closed |
| Requests never limited | cpln/rateLimitDescriptors unset (default matches nothing); domain mismatch between tag and config; rules edited without force-redeployment; misspelled tag (tags are unvalidated) |
| Cloudflare 526 / TLS errors | Domain TLS not using the origin-cert secret, or SSL mode not Full (strict) |
| Redirect loop behind Cloudflare | SSL mode is Flexible — switch to Full (strict) |
| Origin still reachable directly | inboundAllowCIDR not restricted to the CDN ranges |
cpln apply --file rate-limiting.yaml (bundled manifest), cpln workload force-redeployment (config reload)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.