Third-party origins are a security model problem for PWAs, not just a technical constraint
Your PWA's security boundaries determine what you can build, where you can install, and how users trust you.
Why security models matter for installable web apps
A PWA isn't just a website that works offline—it's a security boundary. When users install a web app, browsers grant it elevated capabilities: service workers, persistent storage, background sync, push notifications, sometimes even file system access. These capabilities are scoped by origin, and that scope determines what third-party integrations are safe, risky, or impossible.
Understanding this model prevents architecture mistakes that block installation or compromise user trust.
The PWA security boundary
Every PWA is constrained by its origin:
- Origin = protocol + hostname + port (
https://example.com:443) - Service workers only control requests within their scope (origin + path)
- Storage APIs (
localStorage,IndexedDB, caches) are origin-isolated - Installable status requires HTTPS + registered service worker
- Platform capabilities are granted per-origin, not per-project
This isolation is a feature, not a bug. It means your installed PWA can't accidentally hijack other sites' resources, and other sites can't hijack your PWA's.
Third-party integration patterns and their risks
Pattern 1: Iframe embedding
<iframe src="https://thirdparty.com/widget"></iframe>- Security: Same-origin policy applies. The iframe has its own origin.
- PWA impact: Service worker does NOT control iframe requests. Iframe caching requires the third party's own service worker.
- Installability: Iframes don't affect installability, but iframe resources won't take advantage of your PWA's offline capabilities.
Pattern 2: Cross-origin API calls
fetch('https://api.thirdparty.com/data', {
credentials: 'include'
})- Security: CORS applies. Third party must explicitly allow your origin.
- PWA impact: Your service worker can intercept and cache these requests if CORS permits.
- Installability: Doesn't directly affect installability, but CORS failures break app functionality.
Pattern 3: Third-party cookies (an increasingly risky pattern)
// Authentication cookies set by thirdparty.com
document.cookie = 'session=xyz; domain=thirdparty.com';- Security: Third-party cookies are being blocked by default in modern browsers (ITP, ETP).
- PWA impact: Auth workflows that rely on third-party cookies will fail for your installed users.
- Installability: Not an installability issue per se, but post-install auth failures destroy user trust.
Pattern 4: Subdomain architecture
https://app.example.com/ (PWA scope)
https://api.example.com/ (backend)
https://cdn.example.com/ (assets)- Security: Subdomains are different origins. Service worker scope must explicitly include them.
- PWA impact: Installable requires service worker registration at root. Subdomain resources need careful scope configuration.
- Installability: Multi-origin architectures require scope planning. Service worker misconfiguration blocks installation.
Practical security checklist for PWAs
Before declaring your app install-ready, verify:
- [ ] All critical assets (icons, images, fonts) hosted under your origin or reliable CDNs
- [ ] Third-party APIs use CORS, not cookie-based auth
- [ ] Service worker scope covers all routes users might navigate to
- [ ] No iframe-dependent features that require your service worker's caching strategy
- [ ] Authentication uses first-party cookies or token-based auth (JWT), not third-party cookies
- [ ] CSP headers allow your origin and block unnecessary third-party scripts
When third-party origins are necessary (and how to handle them)
Use case: Embedded third-party widgets (maps, payments, video)
Strategy: Iframe + third-party service worker
If the third party offers their own PWA-ready widget, their service worker handles offline caching within the iframe. Your service worker cannot help here.
Example: Embedding a map widget<iframe src="https://maps-provider.com/widget?callback=yourapp"></iframe>Risk: Widget might not load offline. Display fallback UI.
Use case: Cross-origin APIs
Strategy: CORS + request interception
Configure your service worker to cache API responses:// service-worker.js
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('https://api.example.com/')) {
event.respondWith(
caches.open('api-cache').then(cache =>
cache.match(event.request).then(response =>
response || fetch(event.request).then(networkResponse => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
})
)
)
);
}
});Use case: Multi-tenant or multi-brand apps
Strategy: Subdomains + scoped service workers
Each tenant gets its own subdomain (tenant1.app.com, tenant2.app.com) with explicit service worker scope. This isolates storage and caching per-tenant.Security_audit_framework
| Threat | How it manifests in PWAs | Mitigation | |--------|------------------------|------------| | Cross-site scripting (XSS) | Third-party scripts injected into your PWA origin | CSP headers, Content-Security-Policy-Report-Only, script integrity checks | | Cross-site request forgery (CSRF) | Authenticated requests to third-party APIs without CORS verification | CSRF tokens, SameSite cookie attributes, Origin header checks | | Data leakage via iframes | Third-party iframes reading your PWA's DOM | Iframe sandbox attributes, X-Frame-Options headers | | Storage partitioning | Third-party storage cleared unexpectedly due to browser tracking protections | Use first-party storage, avoid third-party cookies for persistence |
What this means for developers
- Architecture first: Design your origin structure before writing features. Subdomains vs. single-origin affects service worker configuration.
- Security as a feature: Explicit communications about your security model build user trust. "Your data stays in your browser. We never see it" is a trust signal.
- Plan for post-PC-3RD-COOKIE: Third-party cookies are effectively dead for PWAs. Migrate to token-based auth or first-party cookie auth now.
How this affects installability and platform capabilities
| Platform capability | Security requirement | What violates it | |---------------------|---------------------|------------------| | Service worker registration | HTTPS + same-origin script | HTTP origins, mixed content | | Persistent storage | Origin-isolated storage APIs | Third-party cookies for persistence | | Background sync | Service worker scope control | Subdomain resource access not in scope | | Push notifications | VAPID keys + origin association | Sharing VAPID keys across origins | | File System access | HTTPS + explicit user gesture | Origin mismatches in file dialogs |
Decision framework: Third-party vs. first-party architecture
| Criterion | Keep third-party | Migrate to first-party | |-----------|----------------|------------------------| | Authentication complexity | | ✓ (for critical flows) | | Offline caching needed | ✓ | ✓ (your service worker) | | User perception of security | | ✓ (first-party appears more trusted) | | Development speed | ✓ | | | Long-term maintenance | | ✓ (third-party contracts, deprecations) |
Migration recommendation: For authentication and core data APIs, build or host first-party endpoints. For non-critical widgets and analytics, third-party集成 with sandboxed iframes is acceptable.
Sources
- Service Worker API - Same-origin policy
- CORS - HTTP access control
- Content Security Policy
- Chrome Site Isolation
- Safari ITP and Third-party Cookies
Next steps
Audit your PWA's third-party dependencies:
- List all cross-origin iframes and API calls
- Identify which ones are security-critical (auth, user data)
- Plan migration paths for third-party cookie dependencies
- Test offline behavior for all critical user flows
Your PWA's security model is its contract with users and platforms. Violating that contract blocks installations and destroys trust.