For security reviewers
The answers IT and procurement teams ask for on identity, tenant isolation, audience control, data residency, deletion and retention.
This page is written for the person doing a vendor security review, not for end users. It answers the questions that come up in nearly every assessment, and it is deliberately explicit about what is not in place yet.
Beta posture, stated plainly
ShareMyPage is in public beta. It does not hold its own SOC 2 certification; its subprocessors do. Where something is designed but not shipped, this page says so rather than describing it as available. If you find a claim here that the product does not support, that is a bug and we want to hear about it.
Identity and authentication
Sign-in is delegated entirely to Clerk. ShareMyPage stores no passwords for user accounts and implements no credential handling of its own. The application renders Clerk's hosted sign-in component, so the set of enabled methods is configuration on the Clerk instance rather than something compiled into the app.
Ask us for the current live configuration: which providers are enabled, whether email one-time codes are on, and whether MFA is enforced. We will confirm it against the running instance. We would rather do that than have this page drift out of date.
MFA is inherited from your identity provider. If your users authenticate through Google or Microsoft, your MFA policy applies unchanged.
SSO and SAML (Okta, Entra, Google Workspace)
Not enabled by default, and not self-serve. SAML is available through a paid add-on on our identity provider, configured per customer domain during onboarding. It requires DNS TXT domain verification on your side.
Two limitations worth knowing before you plan around it:
- SSO cannot currently be enforced. Configuring a SAML connection for
yourcompany.commakes SSO available to those users. It does not prevent the same users from signing in through another enabled method. A per-workspace "require SSO" flag is designed but not built. If exclusive SSO is a hard requirement for you, treat it as a gap, not a setting. - SCIM deprovisioning is likewise available but not configured by default.
Tenant isolation
This is the question we get asked most precisely, so here is the mechanism rather than a summary.
Every tenant-scoped row carries a non-null workspace_id: pages, decks,
folders, members, invites, tokens, comments, assets. Every query runs through a
shared access layer that filters on it. There is no code path that fetches one
of these objects without also scoping to a workspace.
The active workspace is never supplied by the client. Our identity provider handles identity only; the workspace is resolved server-side from the members table using the authenticated user. A user in workspace A requesting a workspace-B object fails the same-workspace check and is denied. There is no request parameter that can widen this.
API tokens have the workspace baked in. A token resolves to exactly one user and one workspace. There is no workspace argument anywhere in the API surface, so a token is structurally incapable of addressing another tenant. This is an absence of capability, not a runtime check that could be bypassed.
The one intentional exception is deliberately shared content. Publicly shared pages and decks are served by unguessable random ID and gated by the object's own visibility setting rather than by membership, with version serving pinned to the parent object so a link for one page cannot serve another.
Isolation is enforced in the application layer
Tenant isolation today is enforced in application code, not by Postgres row-level security. RLS would be a second structural layer beneath it; we have scoped and cost-assessed it and would build it on request where a requirement calls for it. If your assessment requires database-enforced isolation specifically, this is the honest answer: we do not have it today.
Controlling who can see what
Every page and presentation has a visibility level, chosen per object:
| Level | Who can open it |
|---|---|
| Just me | The owner, plus anyone explicitly invited. |
Everyone at <company> | Members of the workspace, and signed-in users whose provider-verified email domain matches the workspace domain (view only). |
| Anyone with the link | No sign-in required. |
| Anyone with the link + password | Link plus a password. Passwords are argon2-hashed and rate-limited. |
Per-person email invites work on top of any level, keyed to the provider-verified address. Invites grant viewing or editing; they never grant management rights such as changing visibility, deleting, or re-sharing.
Access is decided server-side on every read. Nothing about it is trusted from the client, and private, invited and password-protected pages do not appear in workspace browse or search for anyone but their owner.
A workspace can restrict public sharing
A workspace administrator can turn on Restrict public sharing in workspace settings. While it is on, no member can set a page or presentation to "Anyone with the link" or to a password-protected link. The restriction is enforced server-side at the data layer, on the create and the visibility-change path, not merely hidden in the UI, so it holds the same across the app, the authenticated API and the MCP tools. Private, workspace and invite-only sharing are unaffected.
The setting is off by default, and it is preventive going forward rather than retroactive: turning it on blocks new public and password links but does not silently rewrite the visibility of pages already shared that way. So that the exposure is stated rather than implied, the settings screen shows a live count of how many pages and presentations in the workspace are currently reachable by link, so an administrator can see and clear the existing exposure before relying on the policy.
Visibility changes are also written to an append-only audit log as a detective control alongside this preventive one. That log is available on request rather than through a self-serve UI export.
Domain auto-join
A workspace can claim an email domain. The first workspace created from a
@yourcompany.com address claims that domain; later users with a
provider-verified address on it join that same workspace automatically as
members. Public email providers (Gmail, Outlook, iCloud, Proton and others) are
blocked from claiming a domain, so a workspace created from a personal address
can never auto-admit an entire consumer provider.
Two things to note in an assessment: the block list is a maintained list rather than a derived property, and auto-join trusts that your identity provider verified the address. It does not independently verify domain ownership.
Where data lives
- Page content, database and serverless compute all run in the EU
(Frankfurt,
eu-central-1/fra1). - Page HTML is stored as private objects on managed, SOC 2-certified cloud storage. The objects require a server-held credential to read, so raw bytes are not publicly fetchable even if a URL leaks, and keys are random.
- US subprocessors are used only for authentication and payments, covered by the EU Standard Contractual Clauses.
- Encrypted in transit and at rest.
A current subprocessor list is published at
/docs/subprocessors, a DPA at /dpa, and the privacy
policy at /privacy.
Network and infrastructure
Assessments often ask about network segmentation (VLANs, firewalls, a customer VPC). That question assumes self-managed infrastructure, and ShareMyPage has none. It runs entirely on managed serverless platforms: application code as Vercel Functions, the database as managed Neon Postgres, content as managed object storage. There are no servers, load balancers or network segments we operate or that you would segment. Network-level controls at that layer are the platforms' responsibility, and they are SOC 2-certified for it.
What this means honestly: there is no traditional network segmentation to show you, because there is no traditional network. Isolation is enforced one layer up, at the application and data layer, described under "Tenant isolation" above. Database components are not exposed to the public internet beyond their managed, credential-gated endpoints, and there is no customer-facing network surface to firewall. If your assessment requires evidence of network segmentation specifically, the accurate answer is that the architecture replaces it with application-layer isolation rather than implementing it, and that database-enforced isolation (RLS) is a second layer we would add on request.
Content leaves the EU in exactly one case: the AI features. Creating or editing a deck with AI, changing a slide layout, suggesting a theme, and importing a PowerPoint in re-author mode send that slide or deck's content to Anthropic in the United States, routed through the Vercel AI Gateway and covered by the Standard Contractual Clauses. Hosting, sharing and viewing a page involve no model call. The detail is in AI and your content, including the fact that AI instruction text is retained in our product analytics.
Can staff access customer content? Technically yes. Content is decrypted server-side in order to serve it, so this is not a zero-knowledge system. Access is limited to documented support and legal needs and is logged. Customer-managed encryption keys, which would remove that access, are designed but not shipped.
Deletion and retention
Deleting a page is a hard delete. There is no soft-delete, no trash, and no restore. The database row is removed, all associated rows (versions, comments, invites, form responses, view records) are removed by cascade, and the stored HTML bytes for every version are deleted from object storage.
Deleting a presentation is also a hard delete. The database rows (slides, versions, invites) and the slide content stored inline in them are removed, and the composed deck HTML, uploaded deck images and any logo uploaded for that presentation are deleted from object storage.
A logo field can also hold a URL we do not host, because it may be set to any public address rather than uploaded. We delete only the objects we stored for the item being deleted, and never an address on another host or one another item still points at.
Objects written before July 2026, when presentation deletion began reclaiming bytes, may still exist in storage. They are not reachable through the application and carry no access path. Ask us and we will clear them directly.
Version history follows the page: deleting a page purges its versions and their bytes. On the free plan only the most recent versions are retained; paid plans retain unlimited versions.
Anonymous pages, created without an account, carry a fixed expiry and are purged automatically by a daily job if never claimed.
Viewer identity on view records is kept for twelve months. A page or presentation view stores who viewed it so the owner can see it. After twelve months a daily job clears the viewer's name and email address and replaces the key that links their views with a one-way hash of itself. The view counts are unaffected. Note this is pseudonymisation, not anonymisation: the hash is derived from an account identifier, so anyone already holding the account list could recompute it. It removes the identifier from the analytics table, which is what limits the exposure if that table alone leaks.
A viewer who is not signed in is recorded by a keyed hash of their IP address, never the address itself. The hash is what makes two visits by the same person count as one viewer. The key is fixed rather than rotating, because rotating it would silently inflate unique-viewer counts every time it changed. This is pseudonymisation on the same terms as above: anyone holding both the key and a candidate address can confirm a match. Records written before August 2026 may still hold the address in plain text until they are rewritten or reach the twelve-month purge.
A view record also stores three coarse signals about the visit: the site the visitor arrived from, their country, and whether they were on a phone, tablet or desktop. All three are derived on our servers from the request itself. Nothing is stored on or read from the visitor's device for this, which is why the product still sets no cookies and shows no consent banner.
What we deliberately do not keep, because each would narrow a small audience to a named individual: the visitor's city, the full address of the referring page (which can carry the title of a private document), and the raw browser user-agent string.
How much of this an owner sees depends on whether they already know who the viewer is.
For a visitor who is not signed in, the answer is nothing. Their row in the viewer list reads "Anonymous viewer" and carries no source, no device and no country, permanently. On a page with a handful of readers, a referring site plus a device on that row would be an identification rather than a detail, and that is the case the rule exists for.
For a viewer who is signed in, and whose name and email address the owner can already see, their row also shows the site they first arrived from and the kind of device they last read it on. This tells an owner something about a share they made to a person they can already name; it does not tell them who somebody is.
Country is never shown per person, for anyone. The site someone arrived from describes the share. A country describes the person's whereabouts, and that is a different kind of fact to hand an owner about a named individual, so it stays in the totals.
Those totals, broken down by source, country and device, appear only once an item has at least five distinct viewers. Below that threshold the breakdown is not computed at all.
These three signals are not cleared by the twelve-month identity purge. They are not identifying on their own, they are the only reason the aggregate exists, and clearing them would silently rewrite an owner's historical view of their own page.
Workspace and account deletion are handled manually
There is no self-serve path to delete an entire workspace or an account today. Deletion requests are handled by us directly on request. If your assessment requires a documented, self-serve deletion mechanism, this is a gap.
Note also that deleting rows in the live database does not immediately expunge them from the managed database provider's point-in-time recovery window. That is a property of any managed Postgres with PITR; we can confirm the current window on request.
Continuity, lock-in and the bus factor
Assessments of a small vendor ask this one directly, so here it is directly. ShareMyPage is operated by one person. That is a concentration risk and no paragraph makes it not one. What we can do is make sure that risk never costs you your content.
Nothing is stored in a proprietary format. A page is HTML, or Markdown with the source retained. A deck is HTML. There is no database-shaped export you would need our software to read.
Every page and deck can be exported at any time, without asking us:
| Object | Formats |
|---|---|
| Page | HTML, Markdown, PDF, JPG |
| Presentation |
Export is available in the app's Download menu and over the authenticated API,
and the MCP tools (list_pages, get_page) let you pull an entire workspace
programmatically. What does not exist yet is a one-click "export this whole
workspace" button; that is a gap, listed below.
The database is backed up daily and recoverable for 30 days. Neon takes an automated backup at midnight, keeps it for 30 days, and offers continuous point-in-time recovery on top, so the database can be restored to any moment in a rolling 30-day window. One honest limit: a database restore recovers the rows, while page bytes live in separate object storage that has no point-in-time recovery, so the two can drift apart on a restore. We have written down the restore procedure and that limitation, and we have now run two restore drills, both logged in our backup-and-recovery notes. The first restored a point-in-time branch cleanly with the data intact. The second restored a full logical dump into a clean database and checked it table by table rather than by sampling: every table, every row and every index, constraint and key matched, with no orphaned records. We then checked every single pointer from the database into object storage, not a sample, and all of them resolved.
We also now keep our own copy of the object storage, so a file deleted there still exists somewhere, which is the failure the platform itself does not cover. Two honest limits on that. It is a copy, not a point in time, so it restores what the last run captured rather than any chosen moment. And it is run by hand rather than on a schedule, so how current it is depends on when it was last run. Both are listed as gaps below. Neither drill was a full application-level failover, and we would rather tell you exactly that than let "we have backups" stand in for a recovery you have never tested.
If the service were ever to wind down, our commitment is 90 days' notice to every account holder by email, with the service and its export paths staying up for that whole period. We would rather write that down than have you assume it.
There is no source-code escrow arrangement and no third party contractually able to keep the service running. If your assessment requires escrow, that is a gap, and for an enterprise agreement it is something we would discuss rather than something we already have.
Logging and monitoring
Uploads, edits, visibility changes, password attempts and token use are written to an append-only audit log. Uploads, comments, password attempts and token use are rate-limited. The log is available on request; there is no self-serve UI export.
Detection is layered, but there is no dedicated intrusion-detection system. What exists: the append-only audit log above; rate limiting on uploads, comments, password attempts, token use and the AI surfaces, which fails closed rather than open; a bot check (Cloudflare Turnstile) on anonymous uploads; and the hosting platform's own edge protections. What does not exist: a dedicated IDS or IPS, and automated alerting or anomaly detection on the audit log. Today that log is a record to inspect after the fact, not a monitor that pages someone. If continuous intrusion detection is a hard requirement for your assessment, treat it as a gap rather than a setting.
API and MCP tokens
Tokens are hashed at rest with SHA-256, shown exactly once at creation, scoped to a single user and workspace, and immediately revocable. Failure reasons are logged internally but never returned to the caller, so the endpoint is not an enumeration oracle.
Two limitations to record: tokens carry no granular scopes. A token grants the full tool surface at that user's permission level, so there is no read-only token. They also carry no expiry, living until explicitly revoked. An administrator also cannot currently enumerate or revoke another member's tokens.
Security testing
We test the access-control model rather than assume it. ShareMyPage includes an internal testing harness that provisions two isolated tenants and a set of role personas (a workspace admin, a plain member, and an external invitee with no workspace), then tries to cross the boundaries that matter: one workspace reaching another's content, a member acting beyond their role, an invitee exceeding what they were shared. Tenant isolation and per-page visibility are exercised against both the web application and the hosted MCP endpoint, since that endpoint is a second door onto the same data.
Access-control checks also live in our automated test suite and run on every change, so a boundary that is closed cannot be quietly reopened.
When a check finds a problem, we fix it and record the fix in our public changelog. We would rather you see that we look for these issues and close them than claim we have never had one.
This is self-assessment, not an independent third-party audit. We welcome external review: if your security team wants to test ShareMyPage against a scoped set of throwaway tenants, we can provision that environment and share our rules of engagement.
Reporting a vulnerability
Email security@sharemypage.app. Include enough detail to reproduce, and tell us if you intend to publish so we can agree a timeline.
- We aim to acknowledge within five working days. ShareMyPage is run by one person, so we would rather give you a target we will actually hit on a bad week than a fast one we miss.
- We will not pursue legal action against researchers acting in good faith: testing only against accounts you control or a scoped environment we provision, no access to other customers' data, no degradation of the service, and no public disclosure before we have had a chance to fix.
- We do not run a paid bounty programme. We will credit you in the changelog if you would like that.
The same address is published at /.well-known/security.txt.
Known gaps, in one place
Collected here so an assessment does not have to hunt for them.
| Area | Status |
|---|---|
| ShareMyPage SOC 2 certification | Not held. Subprocessors are SOC 2 Type II. |
| Postgres row-level security | Not implemented. Isolation is application-layer. |
| Workspace policy blocking public sharing | Implemented. Admin toggle, off by default. |
| Enforced SSO (SSO-only sign-in) | Not implemented. |
| Self-serve audit log export | Available on request. No self-serve UI export. |
| Self-serve workspace / account deletion | Manual on request. |
| Reclamation of objects orphaned before 2026-07 | Manual on request. Current deletions reclaim. |
| Granular or expiring API token scopes | Not implemented. |
| Customer-managed encryption keys | Designed, not shipped. |
| Formal uptime SLA | None in beta. Negotiable for enterprise. |
| One-click whole-workspace export | Not implemented. Per-object export and the API cover it. |
| Workspace policy to disable the AI features | Not implemented. AI is opt-in per action. |
| AI instruction text in product analytics | Retained. Under review. See AI and your content. |
| Plaintext visitor IPs on view records written before August 2026 | Hashed at write time since. Historical rows pending a one-off rewrite; all reach the twelve-month purge regardless. |
| Source-code escrow | None. Discussable for an enterprise agreement. |
| Single-operator concentration risk | Real. Mitigated by open formats and export, not removed. |
| Point-in-time recovery for object storage | None from the platform. We keep our own copy, so deleted files still exist, but it restores the last run rather than a chosen moment. |
| Scheduled object-storage backup | Not automated. Run by hand today, so currency depends on the last run. |
Getting the rest
For a completed questionnaire in CAIQ or SIG-lite shape, a countersigned DPA, or a call with whoever is doing your review, get in touch. We would rather answer a hard question directly than have you infer the answer from a marketing page.
See also
- Security and containment: how untrusted HTML is sandboxed.
- Access and sharing: the visibility model in product terms.
- Workspaces: membership, roles and domains.