Configure access, traffic, and delivery

Choose the smallest control that matches the problem, apply it to one test route first, and verify the result before broadening its scope.

Choose a control

Goal UI area Docker-label family
Allow or block clients Access → Access control policies clearplane.proxy.access-control
Require route credentials Access → Authentication policies clearplane.proxy.authentication
Limit request rates Abuse → Rate limit policies clearplane.proxy.rate-limit
Ban repeated abuse Abuse → Auto-ban policies clearplane.proxy.auto-ban
Control cross-origin browser access Access → CORS policies clearplane.proxy.cors
Change request or response headers Rules → Request headers policies / Response headers policies clearplane.proxy.request-headers / clearplane.proxy.response-headers
Compress eligible responses Performance → Compression policies clearplane.proxy.compression
Cache eligible responses Performance → Cache policies clearplane.proxy.cache

UI

Create a named policy in the relevant UI area, choose Global or Route scope deliberately, and assign Route policies to the intended proxy route. Assigning a policy sets the route's state for that family to On, so it replaces the Global policies. The route dialog's Policies section shows every family's state; set a family to Off to opt the route out of a Global policy. Start with one route when a control can reject, rewrite, or cache traffic.

The Name is free text shown in lists. The System name is generated from it while creating the policy and can be edited; copy that value into *.policy labels. Renaming a saved policy preserves its System name.

The UI is the source of truth for UI-created policies. Use Logs and Analytics to verify the policy's effect.

Docker labels

For a discovered service, set the family's root label to on, then either select existing named Route policies by System name with its *.policy label or omit policy and use inline labels. Access control, authentication, auto-ban, cache, compression, CORS, rate limit, request headers, response headers and WAF all use this shape. Inline policies belong only to that discovered service and cannot be edited as shared UI policies.

Without the root label, the route inherits the family's Global policies, and any other label of that family rejects the container. Set the root label to Off to opt the route out, or to Inherit to return to the Global policies. Under Inherit and Off, the family's other labels are kept but ignored, so you can switch a policy off for testing without removing them. Do not combine a named-policy label with that family's inline labels. The Docker label reference shows every family.

Repeatable credentials, JWT keys and claims, and header transforms use <semantic-collection>.<index>.<field>. Indices may have gaps and are processed in numeric order, but each entry must be complete. Use the proxy directives for exact combinations, defaults, and accepted values.

Basic authentication

Omit authentication.policy to create an inline Basic policy. Each credential is one complete indexed entry:

services:
  app:
    labels:
      clearplane.proxy.authentication: "On"
      clearplane.proxy.authentication.type: "Basic"
      clearplane.proxy.authentication.key-location: "Edge"
      clearplane.proxy.authentication.basic.realm: "Restricted"
      clearplane.proxy.authentication.basic.credentials.1.username: "alice"
      clearplane.proxy.authentication.basic.credentials.1.password: "replace-with-a-password"

JWT bearer authentication

JWT signing keys and required claims use the same indexed-entry contract:

services:
  api:
    labels:
      clearplane.proxy.authentication: "On"
      clearplane.proxy.authentication.type: "JwtBearer"
      clearplane.proxy.authentication.jwt.issuer: "https://identity.example.com"
      clearplane.proxy.authentication.jwt.audiences: "clearplane-api account-api"
      clearplane.proxy.authentication.jwt.signing-keys.1.kind: "Symmetric"
      clearplane.proxy.authentication.jwt.signing-keys.1.material: "a-secret-signing-key-at-least-32-characters"
      clearplane.proxy.authentication.jwt.required-claims.1.claim: "scope"
      clearplane.proxy.authentication.jwt.required-claims.1.value: "clearplane.read"

Docker labels are visible through container inspection and Compose source. Basic passwords and JWT signing-key material are secret metadata. If they cannot be stored safely there, create a named authentication policy in the UI or API and select it with clearplane.proxy.authentication.policy, together with clearplane.proxy.authentication: "On".

Restricted service baseline

Use this starting point for a service that should accept traffic only from one client address and temporarily ban repeated bad behavior:

services:
  app:
    image: example/app:latest
    labels:
      clearplane.proxy.enabled: "true"
      clearplane.proxy.host: "app.example.com"
      clearplane.proxy.port: "8080"
      clearplane.proxy.access-control: "On"
      clearplane.proxy.access-control.default-action: "Block"
      clearplane.proxy.access-control.allow-addresses: "123.123.123.123"
      clearplane.proxy.auto-ban: "On"
      clearplane.proxy.auto-ban.rate-limit-violation.enabled: "false"
      clearplane.proxy.auto-ban.error-response.enabled: "true"
      clearplane.proxy.auto-ban.error-response.threshold: "30"
      clearplane.proxy.auto-ban.error-response.window-seconds: "60"
      clearplane.proxy.auto-ban.ban-duration-seconds: "600"

Only 123.123.123.123 can reach the application. If that client produces 30 proxied 4xx responses within 60 seconds, Clearplane bans it across every route for 10 minutes; access-control rejections, rate-limit rejections, and ban responses do not count toward the threshold. Edge's own 401 does count when a client presents credentials that fail an authentication policy.

Cache policies and shared pools

Create cache policies in Performance → Cache policies. A policy holds the eligibility, storage mode, lifetimes, cache-key settings and a pool size. A new policy caches static files by extension, ignores request cookies unless they are listed as bypass cookies, and answers If-None-Match from the cache; Docker labels → Caching describes each rule. Every route that uses the policy shares that pool, and eviction removes the least recently used entries across all of them. Entries stay separate per route, and purges still apply to one route.

Path rules in the policy editor give parts of an application their own caching, for example /_framework/* for a year, /api/* never and / as HTML. The first matching rule applies; each rule either caches the path, with an optional lifetime and browser lifetime, or bypasses it. Docker labels → Caching describes the pattern syntax and the equivalent path-rules label.

The list shows each policy's storage mode and Pool usage, the space its routes currently use against the pool size. Assigning more routes to a policy does not use more of the global per-tier cache limit; each enabled policy counts once. Creating or enlarging a policy that would exceed the limit is rejected.

Browse cached responses

Open Performance → Cache and choose Browse beside a route to inspect its cache in a full-width dialog. If a route is already selected, the overview shows only that route.

The dialog contains the bin summary, searchable and sortable entries, freshness and storage filters, and pagination. Open an entry for response metadata, sanitized headers and the request headers it Varies on; cached response bodies are not exposed. Purge resource removes every cached variant of that URI only from the browsed route.

Understand cache activity

On Performance → Cache, each completed request on a cache-enabled route counts once:

  • Hits are fresh responses served from cache, including disk fallback, responses compressed from a cached identity representation, and entries the upstream confirmed unchanged (REVALIDATED).
  • Misses need an upstream response because no reusable entry is available or revalidation is required.
  • Stale responses are cached responses served during the configured stale-while-revalidate or stale-if-error window; they count separately from hits and misses.
  • Bypasses are requests or responses excluded by cache safety rules, response-size limits, or response inspection. For example, bypass cookies, private responses, and upstream responses in an encoding Clearplane did not request bypass caching.
  • Dynamic requests are not eligible under the route's policy, such as HTML pages under static-file eligibility.

Hit ratio is the share of eligible requests (hits, stale responses, misses and bypasses) answered from cache, and Served from cache totals the response bytes Edge sent from cache instead of fetching them. Request counters live in Edge memory and reset when Edge restarts. Purging entries preserves activity counters. The route table lists active cache-enabled routes; global totals can also include activity from routes that have since been disabled or removed. Disk files counts persistent entries, so memory-only caching can use memory while showing zero disk files.

Evictions count entries removed for policy pool or global capacity limits, separately for each storage tier. Storage errors count failed persistent-cache operations and corrupt entries. Normal expiration, removed routes, and entries skipped for response-size limits are not errors. Route-specific failures appear in that route's row even when it has no stored entries; shared index or directory failures appear only in the global total. Edge application logs include the operation, route when known, and exception for storage failures.

To investigate a high miss rate, filter Observability → Logs by cache result and cache reason, or open a request log entry for the affected route and check its Cache (HIT, MISS, STALE, REVALIDATED, BYPASS or DYNAMIC) and Cache reason fields; hits, revalidations and dynamic requests have no reason. Miss reasons distinguish NotFound, Expired, RequestNoCache, and ResponseNoCache; bypass reasons identify exclusions such as Cookie, Authorization, ResponsePrivate, VaryCredentialHeader, VariantLimit, ContentTypeMismatch, OverrideHeader, Range, ConditionalRequest, CacheTagLimit, EncodedUpstreamResponse, or ResponseTooLarge. Check the route's lifetime, upstream cache directives, key settings, and eviction activity alongside these reasons. Different included query-string values or headers create separate entries.

Purge cached responses

Choose Purge cache on Performance → Cache to remove entries from every connected Edge and both storage tiers. Purge one exact URI, a URI prefix, a proxy route, everything, or Cache tags. A tag purge removes every entry whose upstream response listed one of the tags in Cache-Tag or Surrogate-Key, so a deploy can clear the pages that show one product without purging the site. The same purges are available through POST /api/cache/purge and clearplane cache purge. The cache browser shows each entry's tags.

Cache isolation

With the path included in the cache key, encoded paths that reach different upstream resources remain separate cache entries. For example, /p%2561y and /pay do not share a response. Exact-URI and URI-prefix purges preserve that distinction.

Verify

Test an allowed request and the condition the policy should change. Confirm the response, then check Logs or Analytics for the same route before expanding the policy's scope.