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

# Practical Implications

> What the CSP means for how you build and bundle your game

# Practical Implications

The Content Security Policy enforced on Greenhouse Games has direct implications for how you structure and develop your game. This page breaks down what's allowed, what's blocked, and how to work within the constraints.

## All Assets Must Be Bundled Locally

The CSP restricts resource loading to `'self'` (same-origin) for most directives. This means:

* **Scripts, stylesheets, fonts, and images** must be included in your ZIP bundle — they cannot be loaded from external CDNs or third-party servers.
* References to Google Fonts, Font Awesome CDN, Bootstrap CDN, or any external host will be blocked at runtime.
* Include all dependencies directly in your bundle's file structure.

```html theme={null}
<!-- ❌ Blocked — external CDN -->
<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/phaser@3/dist/phaser.min.js"></script>

<!-- ✅ Allowed — local files -->
<link href="./fonts/inter.css" rel="stylesheet">
<script src="./lib/phaser.min.js"></script>
```

## Inline Scripts and Styles Are Permitted

The `script-src` directive includes `'unsafe-inline'` and `'unsafe-eval'`, and `style-src` includes `'unsafe-inline'`. This means:

* Inline `<script>` tags work normally.
* Inline `<style>` tags and `style` attributes work normally.
* `eval()` and `new Function()` are permitted by CSP (though `eval` and `Function` constructor are flagged by the separate security scan — see [Blocked APIs](/security/blocked-apis)).
* Dynamic style injection via JavaScript (e.g., `element.style.color = 'red'`) works as expected.

<Note>
  Even though CSP permits `eval()`, the platform's security scan still flags it as a blocked API. The CSP allows it to avoid breaking legitimate game engines that use code generation patterns, but direct use of `eval` will result in a security finding.
</Note>

## Blob URLs Are Permitted

The CSP allows `blob:` URLs in several directives (`script-src`, `connect-src`, `img-src`, `frame-src`, `worker-src`). This means:

* You can dynamically create scripts, images, and workers from Blob objects.
* `URL.createObjectURL()` works for generating runtime content.
* This is useful for game engines that compile or generate code/assets at runtime.

```javascript theme={null}
// ✅ Allowed — creating a worker from a blob
const code = 'self.onmessage = (e) => self.postMessage(e.data * 2)';
const blob = new Blob([code], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));
```

## Network Requests Are Restricted to Same-Origin

The `connect-src 'self' blob:` directive means:

* `fetch()`, `XMLHttpRequest`, and `WebSocket` can only connect to same-origin endpoints.
* Any request to an external domain will be blocked by the browser.
* This includes analytics services, telemetry endpoints, multiplayer servers, and ad networks.

```javascript theme={null}
// ❌ Blocked — external API call
await fetch('https://api.example.com/scores');

// ❌ Blocked — WebSocket to external server
const ws = new WebSocket('wss://multiplayer.example.com');

// ✅ Allowed — same-origin request
await fetch('/api/data.json');
```

<Warning>
  If your game makes external network requests, it will appear to work during local development without the CSP applied. Always [test with the CSP locally](/csp/local-testing) before submitting.
</Warning>

## Web Workers Must Be Same-Origin or Blob URLs

The `worker-src 'self' blob:` directive means:

* Workers loaded from local files in your bundle work normally.
* Workers created from blob URLs (dynamically generated) work normally.
* Workers loaded from external URLs are blocked.

```javascript theme={null}
// ✅ Allowed — same-origin worker file
const worker = new Worker('./workers/physics.js');

// ✅ Allowed — blob URL worker
const blob = new Blob([workerCode], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));

// ❌ Blocked — external worker
const worker = new Worker('https://cdn.example.com/worker.js');
```

## localStorage, sessionStorage, and Cookies Are Blocked

While not directly controlled by CSP, the platform's JavaScript API restrictions block access to:

* `localStorage` — blocked by security scan
* `sessionStorage` — blocked by security scan
* `document.cookie` — blocked by security scan

Games that use these APIs will receive a CRITICAL security finding and be automatically rejected. If your game needs to persist state, consider in-memory storage that resets between sessions.

See [Blocked APIs](/security/blocked-apis) for the full list of restricted JavaScript APIs.

## Summary Table

| Capability                   | Status    | Notes                                             |
| ---------------------------- | --------- | ------------------------------------------------- |
| Local scripts & assets       | ✅ Allowed | Must be in your bundle                            |
| External CDN resources       | ❌ Blocked | No external script/style/font/image loading       |
| Inline scripts               | ✅ Allowed | `<script>` tags in HTML work                      |
| Inline styles                | ✅ Allowed | `<style>` tags and `style` attributes work        |
| Blob URLs                    | ✅ Allowed | For scripts, workers, images, frames, connections |
| Same-origin fetch/XHR        | ✅ Allowed | Relative URLs work                                |
| External fetch/XHR/WebSocket | ❌ Blocked | No cross-origin network requests                  |
| Same-origin Web Workers      | ✅ Allowed | Load from local files                             |
| Blob URL Web Workers         | ✅ Allowed | Dynamically generated workers                     |
| External Web Workers         | ❌ Blocked | Cannot load workers from other domains            |
| localStorage                 | ❌ Blocked | Flagged by security scan                          |
| sessionStorage               | ❌ Blocked | Flagged by security scan                          |
| document.cookie              | ❌ Blocked | Flagged by security scan                          |
