# HTTP policy and host limits

Configure headers, CSP, origins, and publishing without confusing them with runtime permissions.

See versions, changes and requirements in [Framework 4.0 and CLI 1.2](/docs/guides/releases/).


<span id="dos-controles-con-responsabilidades-distintas"></span>

<span class="section-anchor" id="section-1"></span>

## Two controls with different responsibilities

`security` in `wu.config.json` defines the HTTP policy served by WU and exported by the build for other hosts. Each app's `grants` form part of the authority the host gives the runtime. A CSP header does not replace the capability contract, and a grant alone does not authorize the browser to load an origin blocked by CSP.

<span id="configuración"></span>

<span class="section-anchor" id="section-2"></span>

## Configuration

```json
{
  "security": {
    "enabled": true,
    "csp": "",
    "frame_options": "DENY",
    "referrer_policy": "strict-origin-when-cross-origin",
    "nosniff": true,
    "app_origins": ["https://apps.example.com"],
    "connect_origins": ["https://api.example.com"],
    "wasm": false
  }
}
```

The example domains are placeholders. Your policy should describe the origins your application actually uses.

| Field | Effect |
| --- | --- |
| `enabled` | Enable or disable the header set |
| `csp` | Generated or literal policy, `report-only`, or `off` |
| `frame_options` | `X-Frame-Options`; default `DENY` |
| `referrer_policy` | Referrer policy |
| `permissions_policy` | Browser capabilities through Permissions-Policy |
| `hsts` | Strict-Transport-Security; useful when serving over TLS |
| `nosniff` | `X-Content-Type-Options: nosniff` |
| `corsOrigin` or `cors` | CORS origin; `cors` also accepts an object with `origin` |
| `app_origins` | Bundle origins: scripts and connections |
| `connect_origins` | API origins: connections |
| `wasm` | Allow WASM compilation in generated CSP |

The parser also supports camelCase spellings for several fields, such as `appOrigins`, `connectOrigins`, `frameOptions`, and `wasmUnsafeEval`. CORS has an important exception: `cors_origin` is the structure's internal name, but JSON accepts `corsOrigin` or `cors`, not that snake_case spelling.

<span id="convenciones-de-valores"></span>

<span class="section-anchor" id="section-3"></span>

## Value conventions

For text header fields, an empty string lets WU decide, and `off` suppresses that header. `csp: "report-only"` generates an equivalent policy in the reporting header; the browser reports violations without blocking them under that policy. A literal CSP string is used as provided.

Generation analyzes inline scripts in the final document and calculates hashes. Run it after inserting any catalog or import map. An HTML handler such as `onclick` is treated differently from a hashed script; diagnostics report incompatibilities. Keeping events in modules and styles in stylesheets avoids relying on HTML exceptions.

In 1.2.0, CSP hashes are computed per page and normalize CRLF line endings. `security.upgradeInsecureRequests` controls upgrading to HTTPS. The build preserves the shell’s `_headers`, applies immutable caching to hashed files and validates values against header injection. Check the policy actually sent by hosting with `wu doctor --url`.

<span class="section-anchor" id="section-4"></span>

## CORS

`Access-Control-Allow-Origin` is not emitted by default. Serving microapps from the same origin does not require enabling `*`. When the topology requires another origin, configure its exact value and also review CSP, credentials, and the destination policy.

The `cors` option of a proxy rule belongs to that rule. It is not identical to `security.corsOrigin`, which governs production server responses.

<span id="archivos-publicables"></span>

<span class="section-anchor" id="section-5"></span>

## Publishable files

Path security decodes escapes before checking segments and rejects traversal, control characters, backslashes, and absolute paths. The file filter blocks dotfiles and extensions or names considered sensitive. `.well-known` is a deliberate exception because it contains public protocol documents.

The build and `doctor` inspect publishable areas, but credentials still belong in the backend or its environment. If an application needs a private token, do not include it in source files or `public/`, even if a particular name is not on the blocklist.

The development server applies its own Host, CORS, HMR and file-access policy, including sourcemaps, modules and query imports. Configure tunnels through `dev.allowedHosts`; only `VITE_*` and `WU_*` from `.env` reach the browser. See [development](/docs/cli/development/) to migrate these behaviors.

<span class="section-anchor" id="section-6"></span>

## Sentinel

The sentinel instance is disabled in `wu dev` and instantiated with its defaults in `wu serve`. Code exists for classifying requests and publishing ACP protocol routes. These modules do not establish universal protection against automation or replace product access control.

CLI `1.2.0` accepts `manifest: "define"` on each app and `security.frameOrigins` for remote iframes. Frame origins only enter `frame-src`; they do not enable host scripts or connections. The catalog navigation filter does not block fetch access. See [remote apps](/docs/framework/remote-apps/) and [build](/docs/cli/build/).

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-7"></span>

## Implementation references

- `wu-cli/src/config/config.zig`
- `wu-cli/src/runtime/security.zig`
- `wu-cli/src/runtime/project_fs.zig`
- `wu-cli/src/runtime/allowed_hosts.zig`
- `wu-cli/src/runtime/dev/env.zig`
- `wu-cli/tests/dev-security.test.cjs`
- `wu-cli/tests/doctor-policy.test.cjs`