# Impreza Shield L7 protection

Source: https://docs.imprezahost.com/security/shield.html

Impreza Shield adds a layer-7 protection stack in front of a deployment, rendered
by the managed proxy that already serves your routes. It is configured per
deployment, it starts in audit mode, and it never stores a visitor identity.
Existing servers require an explicit agent update to a version that announces
`shield-v1`; older agents keep working unchanged and simply do not receive
Shield directives.

## What it is — and what it is not

Shield combines three mechanisms at the proxy:

| Mechanism | Behavior |
| --- | --- |
| WAF (Coraza + embedded OWASP CRS) | Inspects requests against the OWASP Core Rule Set. In audit mode it only observes; in enforce mode it blocks matching requests. |
| Proof-of-work gate | Visitors solve a short SHA-256 challenge in the browser before reaching the site — a self-contained page, no third-party CAPTCHA, no external assets. |
| Rate limit + temporary ban | Per-client request limits in proxy memory with short temporary bans for sustained abuse. |

**Shield is L7 only.** It mitigates abusive HTTP traffic: scanners, credential
stuffing, floods of expensive requests. It does **not** mitigate volumetric
DDoS (saturation of your uplink) and is not advertised as such. Tor onion
routes are protected too; on plain-HTTP onion origins the gate cookie is
issued without the `Secure` attribute so browsers accept it. Shield does not
filter the non-HTTP ports an application publishes, such as a database or a
game server; limit who reaches those with
[inbound access](/security/inbound-access.html).

## Profiles

| Profile | Included | WAF | Gate and limits |
| --- | --- | --- | --- |
| `off` | — | none | none |
| `standard` | yes | CRS, **audit only** — never blocks | none |
| `hardened` | add-on, no extra cost today | CRS, audit until you activate blocking | PoW + rate limit |
| `max` | add-on, no extra cost today | CRS at paranoia level 2, audit until activated | harder PoW + tighter limits |

New deployments on agents that announce `shield-v1` are born `standard`. The
`standard` profile is observation-only by design: it can never block a
legitimate visitor. Existing deployments are not migrated — enable a profile
explicitly when you want it.

## Audit first, blocking after review

When you choose `hardened` or `max`, the WAF still starts in **audit** mode.
Blocking (`shield_mode=enforce`) is only accepted after you confirm you
reviewed the audit behavior for false positives on your site — the API call
requires `confirm_enforce: true`. You can return to audit at any time.
The `standard` profile never enforces.

This ordering exists because a WAF rule set that blocks first can take a
legitimate form or API call with it. Review first, then enforce.

## Privacy model

- No visitor IP is stored, logged or exported by the Shield stack. Client
  keys for rate limiting are HMAC-hashed with a per-process random key.
- The WAF audit log stays off: its native format would embed the visitor IP.
- Proof-of-work state lives in proxy memory for minutes; a proxy restart
  clears it and visitors simply redo a cheap challenge.
- Telemetry is aggregate counters per deployment (requests, challenges,
  rate-limited hits). Never an address, path or user agent.

## Request metrics

On servers with the updated proxy, every routed deployment also reports
per-minute proxy counters: request volume by status class, latency
percentiles (p50/p95/p99), transferred bytes and Shield outcomes. They
appear as `proxy_metrics` on the deployment and never carry visitor
identity. Minute detail is kept for 48 hours; longer proxy history is not
available yet.

## Manage a profile

The portal's **Shield card** lives in App settings of each custom application
and is the same contract as the API surface — the card bridges to it, so every
rule below holds identically on both:

- The card shows the current profile and mode, plus the last 24 hours of
  Shield counters (challenges, passed, rate-limited — counts only, never an
  IP, a path or a user agent). Read them before you enforce: they are the
  audit review.
- **Profile** (`off|standard|hardened|max`): `standard` audits and never
  blocks; `hardened` and `max` are included at no extra cost while adoption
  is measured (we will announce before that ever changes).
- **Mode**: `audit` (log only) by default and always available back;
  `enforce` exists only on `hardened`/`max` and asks for the explicit
  audit-review confirmation in the card. `standard` can never enforce.
- A server whose agent does not announce `shield-v1` shows the minimum agent
  version and offers no control until the agent is updated (My Apps → server
  card).
- Deploy with `shield_profile` (`off|standard|hardened|max`) in the create
  request.
- Change at runtime with `POST /v1/platform/deployments/{id}/shield` —
  body `shield_profile`, optional `shield_mode` (`audit|enforce`), and
  `confirm_enforce: true` when activating blocking on `hardened`/`max`.
- MCP: `impreza_set_shield` mirrors the same contract. `impreza_deploy_custom`
  does not declare `shield_profile` yet, so strict MCP clients cannot send it:
  create the deployment, then set the profile with `impreza_set_shield`.

The change re-renders the proxy fragment. An updated proxy image or configuration can recreate the proxy container while preserving its certificates and data. Route changes can interrupt connections; this is not a guarantee of zero downtime.


## Detailed rule review

Agent **0.6.27 or later** adds `shield-v2` and `shield-v2-controls`. Existing servers require an explicit Agent update and must report those capabilities. The portal, REST API and hosted MCP expose the controls. A released local MCP package may have a different surface; inspect its available tools before relying on a field.

Read `impreza_get_shield` or the app's Advanced Shield card before changing a policy. The review includes aggregate WAF outcomes and top matching detection rules, with static descriptions. It carries no request payloads or visitor identity. A match does not prove malicious traffic. Only supported detection rules can be excluded, at most twenty per app, optionally restricted by a path prefix. Changing exclusions returns enforcement to audit and clears the previous enforcement confirmation; review legitimate app behavior before confirming again.

Policy writes require `base_revision`. A concurrent edit returns a revision conflict: refresh and review the current policy before retrying. Omitted controls keep their settings; null request limits restore profile defaults. Saving a policy queues a route change: read its result and verify the actual route.

## Tune challenges and limits

The `controls` object on a Shield update supports:

| Field | Contract |
| --- | --- |
| `pow_paths` | At most ten request-path prefixes, up to 256 characters each. An empty list gates every path on `hardened` or `max`. `/api` also matches `/apiary`; prefer `/api/` for a subtree. |
| `rate_limit_rpm` | 30–6,000 requests per minute, or null for profile defaults. |
| `pow_difficulty` | Challenge difficulty 2–4, or null for profile defaults. |
| `trusted_sources` | At most ten canonical network CIDRs: IPv4 /16–/32 or IPv6 /48–/128. Real clearnet transport peers only; forwarded headers and onion routes do not qualify. Trusted peers bypass proof-of-work and rate limits, never the WAF. Configuration stays private and is excluded from audit logs. |
| `under_attack` | Enable for 1–24 hours, or disable early. Applies proof-of-work everywhere with difficulty at least 4. Base settings return locally at the absolute deadline, even without the control plane. It never enables WAF enforcement automatically. |

WAF audit mode does not turn off a profile's proof-of-work or request limits. Browser challenges need JavaScript and can prevent a non-browser API or webhook client from working. Test the relevant clients and paths before enforcing a new policy. The IP allowlist does not authenticate users or bypass Tor client authorization.

The new per-window protection counts remain aggregate telemetry; no visitor identity is exported. Shield protects HTTP at layer 7, including supported onion routes. It does not prevent uplink saturation or change logging in your application or an external service.

For a guided workflow, read [protect an app with Impreza Shield](https://impreza.host/guides/protect-an-app-with-impreza-shield/).
