> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usechar.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure CORS and CSP

> Set up Content Security Policy and CORS headers for the Char agent

The Char agent connects to external services and loads resources. If your application uses Content Security Policy (CSP) headers, you'll need to allowlist Char's domains.

## Content Security Policy

### Minimum Required Policy

Add these directives to your CSP header:

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  connect-src 'self' https://*.usechar.ai wss://*.usechar.ai;
  script-src 'self' https://unpkg.com;
  style-src 'self' 'unsafe-inline';
```

<Warning>
  **`'self'` does not cover WebSocket connections.** You must explicitly list `wss://*.usechar.ai` in `connect-src`. This is a [common pitfall](https://github.com/w3c/webappsec-csp/issues/7) — the `'self'` keyword matches only the same scheme, host, and port.
</Warning>

### Directive Breakdown

| Directive     | Values                 | Purpose                          |
| ------------- | ---------------------- | -------------------------------- |
| `connect-src` | `https://*.usechar.ai` | HTTPS API requests               |
| `connect-src` | `wss://*.usechar.ai`   | WebSocket connection to Tool Hub |
| `script-src`  | `https://unpkg.com`    | Agent script from CDN            |
| `style-src`   | `'unsafe-inline'`      | Agent component styles           |

### About `'unsafe-inline'` for Styles

The Char agent uses web components with shadow DOM, which inject styles dynamically. This currently requires `'unsafe-inline'` in `style-src`.

<Note>
  While `'unsafe-inline'` weakens CSP protection against style-based attacks, the primary security value of CSP comes from restricting `script-src`. Style injection attacks are significantly less severe than script injection. See [OWASP CSP Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html) for context.
</Note>

**Alternative with nonces** (if your framework supports it):

```http theme={null}
Content-Security-Policy:
  style-src 'self' 'nonce-{random}';
```

However, web components that create styles in shadow DOM may not respect nonces. If you need strict CSP without `'unsafe-inline'`, contact us about self-hosting options.

### Self-Hosted Agent

If you bundle the agent with your application instead of loading from CDN:

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  connect-src 'self' https://*.usechar.ai wss://*.usechar.ai;
  style-src 'self' 'unsafe-inline';
```

This removes the need for `unpkg.com` in `script-src`.

### Strict CSP Starting Point

For applications starting with a strict policy, here's a complete example:

```http theme={null}
Content-Security-Policy:
  default-src 'none';
  script-src 'self' https://unpkg.com;
  style-src 'self' 'unsafe-inline';
  connect-src 'self' https://*.usechar.ai wss://*.usechar.ai;
  img-src 'self' data:;
  font-src 'self';
  base-uri 'self';
  form-action 'self';
```

Starting with `default-src 'none'` and explicitly allowing only what's needed is the [recommended approach](https://content-security-policy.com/).

## CORS Configuration

The Char API includes appropriate CORS headers for browser requests. Your server doesn't need to proxy Char API calls.

### Reverse Proxy Considerations

If you're running a reverse proxy or API gateway, ensure it doesn't strip CORS headers from Char API responses:

**Nginx:**

```nginx theme={null}
location / {
    # Preserve CORS headers from upstream
    proxy_pass_header Access-Control-Allow-Origin;
    proxy_pass_header Access-Control-Allow-Headers;
    proxy_pass_header Access-Control-Allow-Methods;
    proxy_pass_header Access-Control-Allow-Credentials;
}
```

**Apache:**

```apache theme={null}
# Don't modify upstream CORS headers
Header always unset Access-Control-Allow-Origin "expr=%{REQUEST_URI} =~ m#^/api/#"
```

**Cloudflare / Vercel / Netlify:**

These platforms preserve CORS headers by default. No configuration needed.

### CORS vs CSP

These are different mechanisms:

| Mechanism | Controls                          | Direction        |
| --------- | --------------------------------- | ---------------- |
| **CORS**  | Which origins can read responses  | Server → Browser |
| **CSP**   | Which resources the page can load | Page → Browser   |

CSP's `connect-src` does not bypass CORS. Both must allow the connection.

## Troubleshooting

### "Refused to connect to wss\://"

**Cause:** WebSocket URL not in `connect-src`.

**Fix:** Add `wss://*.usechar.ai` to `connect-src`. Note that `'self'` does not cover WebSocket schemes.

### "Refused to load the script"

**Cause:** Script source not allowed by `script-src`.

**Fix:** Add `https://unpkg.com` to `script-src`, or self-host the agent.

### "Refused to apply inline style"

**Cause:** `style-src` doesn't allow inline styles.

**Fix:** Add `'unsafe-inline'` to `style-src`. This is currently required for the agent's web components.

### Agent loads but API calls fail

**Cause:** Reverse proxy stripping CORS headers.

**Fix:** Configure your proxy to pass through `Access-Control-*` headers. Check the Network tab — responses should include `Access-Control-Allow-Origin`.

### Mixed content errors

**Cause:** Page loaded over HTTPS but trying to connect via HTTP.

**Fix:** Ensure all Char URLs use `https://` and `wss://` (not `http://` or `ws://`).

## Verifying Your Configuration

Open browser developer tools and check:

1. **Console** — No CSP violation errors (red text mentioning "Content Security Policy")
2. **Network** → Filter by "WS" — WebSocket connection shows status 101
3. **Network** → Filter by domain — Requests to `usechar.ai` return 200

## Report-Only Mode

Test your CSP without breaking functionality:

```http theme={null}
Content-Security-Policy-Report-Only:
  default-src 'self';
  connect-src 'self' https://*.usechar.ai wss://*.usechar.ai;
  report-uri /csp-reports;
```

This logs violations without blocking them. Review reports, then switch to enforcing mode.

## References

* [MDN: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
* [MDN: connect-src directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/connect-src)
* [OWASP: CSP Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
* [CSP Quick Reference](https://content-security-policy.com/)
