Security & data protection
PageWard hosts HTML that other people wrote — often generated by an AI. Treating that file as untrusted is the core design assumption. This page explains how it's contained, who can reach it, and where the data lives.
Last updated: 22 July 2026 · Written for IT and security reviewers
PageWard is in a closed pilot. Everything described as Today is built and running. Items marked Planned are not yet implemented — they're listed so you can see the trajectory, not so you can rely on them. We'd rather lose a deal than pass a security review on a feature that doesn't exist.
1. The core problem: untrusted HTML
An uploaded page can contain arbitrary JavaScript. If that script could read your PageWard session or reach another customer's page, the product would be indefensible. Containment is enforced at four independent layers.
Sandboxing protects PageWard and other customers. It does not stop an uploaded page from sending data outward to a server its author controls — an opaque origin restricts what a page can read, not where it can send. Pages may also load scripts and styles from public CDNs.
So treat an uploaded page exactly as you would treat any script someone hands you: the person who wrote it is trusted with what a viewer puts into it. We don't scan uploads for malicious behaviour, and we'd rather say so than let you assume otherwise.
Isolated origin Today
Every page renders inside a sandboxed <iframe> with allow-scripts allow-forms allow-modals allow-popups allow-downloads and deliberately without allow-same-origin. That gives the frame an opaque origin: its scripts cannot read PageWard's cookies or session, cannot touch another page, and cannot access browser storage. Popups inherit the sandbox — allow-popups-to-escape-sandbox is not granted, so there is no escape hatch. A matching Content-Security-Policy sandbox header is sent on the response itself, so the protection does not depend on the embedding page alone.
Never served from a public URL Today
Files live in a private object store — not a public bucket, not a CDN path. PageWard delivers them only through an authenticated application route that checks the caller against the page's allowlist on every single request. An unauthenticated or unauthorised caller receives 401/404, never the content.
One honest boundary: this controls who may obtain a page, not what they do afterwards. Someone you have already authorised can pass the content on, exactly as they could with a file you emailed them. The bucket itself also enforces an HTML-only content type and a 10 MB cap, and responses are sent with no-store and Referrer-Policy: no-referrer, so page URLs don't leak to sites a page calls out to.
Access enforced in the database Today
Ownership and allowlist checks are enforced by PostgreSQL Row-Level Security, not by application code alone. Every query runs as the signed-in user, and parallel policies govern the stored files themselves. RLS policies are still code and can still contain mistakes — but a bug in the web layer cannot grant access the database refuses.
Two controls sit above that layer, in the application rather than the database: pausing a page, and the view log. Pausing hides a page in the product; it is not yet a database-level restriction, so it should be treated as a convenience rather than a security boundary. Deleting a page — which does enforce at the database and removes the file — is the reliable way to cut off access.
No privileged key in the application Today
The app holds no service-role or admin database key. There is no credential in the running application that could be used to read across users, which means a compromise of the web tier does not become a compromise of everyone's data.
2. Who can see a page
| Control | How it works | Status |
|---|---|---|
| Private by default | No page is ever public or guessable. Access is deny-by-default. | Today |
| Per-person allowlist | The owner names each email address that may open the page. Everyone else gets a no-access screen — never the content. | Today |
| Authenticated sign-in | Passwordless email link, or an optional password. No anonymous viewing. | Today |
| Instant revocation | Removing someone from the allowlist, or deleting a page, takes effect immediately at the database layer — delete removes the stored file, not just the link. Pausing is an application-level control (see above). Deletion clears live storage; we do not yet publish a purge timeline for encrypted backups. | Today |
| View log | Which authorised address opened the page, and when — visible to the owner. It is a usage record, not a tamper-evident audit trail: dashboard preview loads are excluded, and it is not hardened against a determined viewer avoiding it. | Today |
| SSO / SAML / OIDC | Sign-in against your own identity provider. | Planned |
| Org-wide & role-based sharing | Share to everyone in the organisation, or to directory groups and roles. | Planned |
| Exportable audit log | Full action history with CSV export. | Planned |
| Expiring links | Time-limited access for external stakeholders. A manual pause/unpause control exists today. | Planned |
| SCIM provisioning · DLP | Directory sync and data-egress controls. | Planned |
3. Where your data lives
Uploaded files, the database, and the application compute all run in the European Union — Frankfurt, Germany. Storage and processing were deliberately placed together in-region rather than defaulting to a global edge.
One honest caveat: a thin edge layer that refreshes the session cookie may execute outside the EU. In validating the session it receives the signed-in user's email address, so a personal identifier — not merely an opaque token — is processed there. It never reads uploaded page content and issues no database queries. We treat this as a transfer and cover it accordingly; tightening it is on the roadmap. We'd rather document it than let you discover it.
Encryption
All traffic is encrypted in transit over HTTPS. Data is encrypted at rest by our infrastructure providers.
4. Subprocessors
| Provider | Purpose | Region |
|---|---|---|
| Supabase | Database, authentication, file storage | EU — Frankfurt |
| Vercel | Application hosting and compute | EU — Frankfurt (edge cookie refresh may be global) |
| Email delivery | Sign-in link delivery | See Privacy Policy |
Any new subprocessor will be listed here before it is used. A payment processor will be added when PageWard begins accepting payment.
5. Known limitations
Things a reviewer should know, stated plainly:
- Single self-contained file only. Sidecar assets fetched by relative path will not resolve. Scripts and styles loaded from public CDNs work.
- Browser storage is unavailable inside a page, because the opaque origin blocks it. The app detects pages that reference it and warns the owner at upload.
- Outbound requests from a page to services that don't permit cross-origin access will fail — a consequence of the isolation, not a bug.
- No automated deprovisioning yet. Removing someone is a manual action until SCIM ships.
- Uploaded content is your responsibility. If a page contains personal data, you remain its controller; we process it on your behalf.
6. Who operates PageWard
PageWard is currently built and operated by one individual in Austria, with no company entity yet — see the Impressum. Everything on this page is what one person has actually built. We use "we" below out of habit; there is no team behind it.
That has consequences worth knowing before you evaluate us:
- The operator has administrative access to the database and storage and can technically read uploaded content. That access is not itself logged today. There are no other personnel.
- Business continuity is not yet solved. If the operator were unavailable, there is currently no second person able to restore access or export your data. A documented fallback is on the list before anyone pays us.
- There is no 24/7 monitoring, no on-call rotation, and no guaranteed response time.
If any of that is disqualifying for your organisation, it should be — and it's better learned here than three months in.
7. Compliance
PageWard is built to support GDPR obligations: EU data residency, deletion on request, and access limited to named individuals.
A Data Processing Agreement is not yet drafted. If you need one in place before using PageWard — and as a controller you are entitled to require it — say so and it will be prioritised. Claiming to have one on the shelf would be untrue.
We do not currently hold ISO 27001 or SOC 2 certification, and no external penetration test has been performed — PageWard is an early-stage product and claiming otherwise would be false. If a formal certification is a procurement requirement for you, tell us; it's a roadmap question we'd like to hear about from real buyers.
Breach notification: if personal data you control is affected by a security incident, we will notify you without undue delay and provide the information we hold, so you can meet your own obligations under Articles 33 and 34 GDPR.
8. Reporting abuse or illegal content
PageWard hosts files uploaded by its users. If a page hosted here is unlawful, deceptive, or abusive — including phishing or malware — report it to abuse@pageward.dev with the page link and what's wrong with it. We will acknowledge the report, investigate, and can suspend or remove a page and its uploader's access.
Note that pages are private and require sign-in, which means external scanning tools cannot inspect them. That is a deliberate confidentiality property, and it also means we depend on reports rather than automated detection.
9. Reporting a vulnerability
If you believe you've found a security issue, please email security@pageward.dev with enough detail to reproduce it. We aim to acknowledge within five working days, and we'll keep you updated as we investigate. Please don't publicly disclose before we've had a reasonable chance to fix it.
Testing against your own account and your own uploaded pages is welcome, and good-faith research within that scope will not be met with legal action. Please don't test against other users' data, attempt denial of service, or use automated scanners that generate significant load.
Questions this page doesn't answer? Write to hello@pageward.dev — security questions from real reviewers are genuinely useful to us.