# Frontend Security



> GoSmarter's browser security controls - Content Security Policy, secure token storage, and supply chain protections.
> 
> **URL:** https://www.gosmarter.ai/docs/frontend-security/

**Date:** 0001-01-01



## Browser security controls

The GoSmarter web application is a single-page application (SPA) and we apply several layers of browser-level security to protect you whilst you use it.

### Content Security Policy (CSP)

We enforce a Content Security Policy that restricts what the browser can load and execute:

| Directive | Policy | What it means |
|-----------|--------|---------------|
| `default-src` | `https:` | Only HTTPS resources allowed by default |
| `script-src` | `'self'` + Supademo, Frill, Clerk, Cloudflare Turnstile, and Stripe.js | Only our own scripts plus the specific third-party scripts required for authentication (Clerk), bot protection (Cloudflare Turnstile), billing (Stripe.js), product guidance (Supademo), and feedback (Frill) can execute |
| `frame-src` | `'self'` + `blob:` + the same Clerk, Cloudflare Turnstile, Stripe, Frill and Supademo origins | Only our own site, local blob frames, and the named third-party embeds above can render |
| `style-src` | `https: 'unsafe-inline'` | Styles from HTTPS sources (inline styles required by the UI framework) |
| `worker-src` | `'self'` + `blob:` | Service workers restricted to our own origin and local blob workers |
| `object-src` | `blob:` | Embedded content restricted to local blob URLs (used by the PDF viewer); no third-party plugins |
| `img-src` | `https:` + `blob:` + `data:` | Images from HTTPS sources, local blobs, and inline data URIs |
| `font-src` | `'self'` + `data:` + Frill's CDN (`frill-prod-app.b-cdn.net`) | Fonts from our own origin, inlined as data URIs, or served by the Frill feedback widget |
| `frame-ancestors` | `'none'` | The application cannot be embedded in an iframe on another site (clickjacking protection) |

The allowlisted third-party origins are:

- **Clerk** (`*.clerk.accounts.dev`, `*.clerk.com`) for authentication
- **Cloudflare Turnstile** (`challenges.cloudflare.com`) for bot protection during sign-up
- **Stripe** (`js.stripe.com`, `hooks.stripe.com`) for billing and checkout
- **Supademo** (`script.supademo.com`, `app.supademo.com`) for interactive in-app guides
- **Frill** (`widget.frill.co`) for product feedback and communication widgets

No advertising scripts are loaded from the frontend shell.

### Token storage

Authentication is handled by **Clerk**. The session token is stored in an HTTP cookie (`__session`, plus a companion `__client_uat` cookie used to track session state), not in browser localStorage or sessionStorage:

- `SameSite=Lax` is set on Clerk's cookies
- Clerk's client SDK does not log PII to the browser console by default, and exposes no equivalent to a verbose PII-logging toggle

### Source maps

Production builds do **not** include source maps. This prevents exposing application structure and logic through browser developer tools.

### API route protection

The GoSmarter API is served separately from the frontend, behind the **Zuplo API gateway**, which validates Clerk session tokens at the edge before any customer-facing request reaches the backend. A response override redirects a 401 from the frontend shell back to the sign-in page. See [Access Control](../access-control/) for the full authentication and authorisation architecture, including the small set of provider webhook endpoints that sit outside the gateway by design.

### Supply chain security

- **Dependency scanning**: Dependabot monitors all frontend dependencies for known vulnerabilities
- **Dependency review**: Pull requests are automatically checked for high/critical CVEs and copyleft license violations
- **No hardcoded secrets**: No API keys, tokens, or credentials in the frontend source code

### Key points for your security team

- **CSP enforced**: Strict Content Security Policy limiting script execution to self + named vendors
- **Named script/frame allowlist**: Clerk (authentication), Cloudflare Turnstile (bot protection), Stripe (billing), Supademo, and Frill — no others
- **Cookie-based tokens**: Session tokens stored in an HTTP cookie (`SameSite=Lax`) by Clerk's client SDK, not in browser localStorage or sessionStorage
- **No PII logging**: Clerk's client SDK does not log PII to the console by default
- **No source maps in production**: Application internals not exposed
- **Authenticated API routes**: Enforced at the Static Web App platform level
- **Automated dependency scanning**: Dependabot + dependency review on every PR
- **CORS policy**: API cross-origin access is restricted to configured origins
- **HSTS**: HSTS headers are set to enforce HTTPS connections to the frontend

### Request evidence

[Email us](mailto:support@gosmarter.ai), [contact us online](https://gosmarter.ai/contact), or [book a compliance call](https://calendly.com/gosmarter-demo).

