Security & reliability
Last updated: October 7, 2026
The short version
Your content lives in your own GitHub repository; our database holds only the account and workflow data needed to run the service (listed precisely in the privacy policy). PullPress asks GitHub for the narrowest permissions that still let editors work, and is designed so that even a full PullPress outage never locks you out of your content or takes your website down.
Your content stays in your repository
Every page, post and image your team edits is committed to your own GitHub repository through the GitHub App you install. Drafts are branches; published changes are merged commits with full history. Our database stores account and workflow data — accounts, review states, change-request titles, comments and ideas, entry titles with their search embeddings, and a cache of entry titles and dates that speeds up listings — but your pages and posts themselves live in Git.
That architecture is your strongest guarantee: your content is versioned by Git, hosted by GitHub, and fully portable. Stop using PullPress tomorrow and you keep everything, with history.
Sign-in and access control
Editors sign in with single-use, short-lived magic links sent to their email — there are no passwords to leak, reuse or brute-force, and link requests are rate-limited per client and per address. A new invitee's invitation carries a personal sign-in link instead: single use, valid for 7 days, stored only as a hash, bound to that one account and dead as soon as they have signed in; opening it only shows a page, so mail scanners can't use it up. Someone who already has an account is never signed in from an invitation — they accept it themselves. The same email carries a six-digit code for signing in on another device: valid for 10 minutes, single use, stored only as a hash and void after five wrong tries. Sessions last 30 days from the last use. Writers never need a GitHub account.
Access is layered: workspace roles (owner, admin, member), site roles (editor, approver, viewer) and optional per-collection restrictions, so a writer only sees what they are meant to touch. Site access always requires membership of the workspace that owns the site, so removing someone from a workspace ends their access everywhere in it, and only owners can grant or take away ownership. Every data access goes through a single workspace-isolation chokepoint on the server, so one workspace can never read another's sites or installations.
AI agents connect through the Model Context Protocol using OAuth 2.1 with PKCE and short-lived, rotating tokens — a refresh token that is reused after it was replaced revokes the whole connection (one network retry within 30 seconds is tolerated) — or personal API tokens that expire after 30 days, 90 days or a year (your choice) and are stored only as hashes. Every connection carries scopes (read, write, approve and schedule) shown on the consent screen next to the exact address the app redirects to, unknown apps are flagged as unverified, and every new connection is emailed to the account owner. Deleting an account or registering a device for push notifications is never possible with an assistant's token. An agent never exceeds the role of the person it acts for: without the approve-and-schedule scope it can only draft and submit for review, and only an agent acting for an approver or admin who granted that scope can approve or schedule changes.
Minimal GitHub permissions
The PullPress GitHub App requests only what the editor needs: read/write on repository contents and pull requests, read-only metadata, and optional read-only checks. It deliberately has no access to Actions workflows, so even a compromised account could not modify your CI/CD pipeline through PullPress. At the organization level it reads only membership (read-only), and only to check — with the connecting person's own GitHub authorization — whether they own the organization before they may move an installation away from another workspace.
GitHub access uses short-lived, per-request installation tokens. Before an installation is tied to a workspace, GitHub itself confirms — through the connecting person's own GitHub authorization — that they have access to it, so no one can attach someone else's repositories by guessing an installation number. Private keys and secrets stay in server-side environment variables and are never sent to the browser. Commits are attributed to the editor who made them, so your Git history stays honest. That check uses PKCE, the one-time GitHub authorization is revoked right after, and a workspace admin is reminded to re-confirm it every 180 days, so someone who left your GitHub organization doesn't keep publishing through PullPress unnoticed.
Platform security
All traffic is encrypted in transit (HTTPS). Rate limits protect sign-in, saving, reviewing and invitations against abuse. When PullPress fetches a URL on your behalf (link checks, your live site's sitemap, notification webhooks) it only talks to public internet addresses on standard ports, so it can't be pointed at internal networks. Bring-your-own AI keys are encrypted at rest. Billing is handled by Stripe — we store a subscription reference, never card details.
Found a vulnerability? Report it to security@pullpress.app (also listed in /.well-known/security.txt) and we will respond as quickly as we can. Please give us reasonable time to fix an issue before disclosing it publicly.
Reliability and uptime
Our internal, non-binding target is 99.9% monthly availability for the hosted service — it is not a contractual SLA, and the terms of service offer no service credits. We publish a public status page at /status — current status, 90-day uptime history and incidents, computed from our own health checks — plus a live health endpoint (/api/health) that independent uptime monitors can watch.
More important than any number is the failure model: PullPress sits beside your website, not underneath it. Your site is built and hosted from your repository by your own pipeline — if PullPress is ever down, your live website keeps serving, your content remains in GitHub, and nothing is lost; editing simply pauses until we are back.
Backups and retention
Content: protected by Git itself — full version history in your repository, stored on GitHub's infrastructure. Deleted or changed by mistake? Any previous version can be restored from history, in the app, without git commands.
Account and workflow data: stored in a managed Postgres database (Supabase) with daily backups; backups roll over within at most 30 days. Account data is kept while your account exists and is removed when you delete your account (self-service, on your profile) or workspace; your content stays in your repository, under your control.
Where your data lives
Your content lives wherever your GitHub repository lives, under your GitHub agreement. Our database holds the account and workflow data described above, in a managed Postgres database in the EU (Supabase), with the app hosted on Netlify; analytics run only with consent, on PostHog's EU cloud.
Our Data Processing Agreement (/dpa) applies to every workspace automatically, and the current list of sub-processors with their locations is at /subprocessors.
If your organisation has specific data-residency or vendor-review requirements (questionnaires, processing details), contact us at security@pullpress.app — answering them is part of the job, not an enterprise upsell.