Security ยท checked against the code on 2026-09-24
Security
What Shipglot stores, how it protects it, and what it does not do yet. Every statement here describes what the code does.
Hosted translation is not open yet. The open-source QA gate runs on your machine or in your CI, needs no account, and sends nothing anywhere.
The QA gate and browser tools
shipglot check,lock,statusandinitread files locally and make no network requests. There is no telemetry.- The browser tools run the same parser, checks and writer inside your browser tab. Files are not uploaded.
- This website sets no cookies and loads no third-party scripts, stylesheets or fonts. The fonts are served from this site.
What leaves your machine, and when
Only three commands contact the hosted service, and only with a SHIPGLOT_TOKEN:
shipglot translatesends the keys that need a translation with their context (source text, neighbouring keys, up to three lines of code that use the key), your glossary and style guide, and translation memory unless you pass--no-memory.--dry-runlists what would be sent and sends nothing. The privacy policy lists every field.shipglot syncsends key names and a SHA-256 hash of each source text, not the text, to count keys for billing.shipglot pushuploads the translation files your config matches to the reviewer editor.
What the hosted service stores
- Your GitHub user id, login, name and email; your memberships and roles.
- Source key names and hashes, translation jobs, their results and a per-string decision log.
- Strings pushed to the editor, with comments and suggestions.
- Subscription, invoice and credit records from Stripe. Card numbers go to Stripe and never reach Shipglot.
- An audit log, hashes of API tokens and sessions, and webhook endpoints.
AI model providers
Strings are translated and checked by models from OpenAI, Anthropic and Google (Gemini API). Which model handles which language is set by a routing file produced by Shipglot's model test battery, with a fallback on a different provider for every role. Requests to OpenAI are sent with response storage turned off (store: false). Shipglot does not train models on your content. The full list is on Data processing and sub-processors.
Encryption and cookies
- Sign-in works only over HTTPS: every cookie the service sets is Secure. Cloudflare terminates TLS for visitors and connects to the server over TLS; the server refuses requests that do not come through Cloudflare.
- The session cookie is
__Host-sg_session: signed, HttpOnly, Secure, SameSite=Lax, and valid for 30 days. Sessions are stored as SHA-256 hashes, so a copy of the database holds no usable session. - Changes made with the session cookie are refused from another origin, and any body they send must be JSON; editor changes also need a CSRF token.
- The editor sends a Content-Security-Policy that allows scripts, styles, fonts and connections only from its own origin, and refuses to be framed.
- The database is not encrypted by the application, and the server disk it lives on is not encrypted at rest.
Tokens and secrets
- API tokens start with
sg_and carry 32 random bytes. Shipglot stores only a SHA-256 hash and compares in constant time, so a token is shown once, when it is created. Tokens have scopes (projects:read,projects:write,keys:sync,translate,screenshots:write) and can be limited to one project and revoked at any time. - The GitHub App private key, the Stripe keys and the webhook secrets of GitHub and Stripe are read from the server's environment or files, not from the database.
- Each outgoing webhook endpoint's signing secret is stored as is, because every delivery must be signed with it.
- The API allows 60 requests a minute per token or signed-in user.
Sign-in, SSO and roles
- Sign-in with GitHub asks only for
read:useranduser:email. - SAML single sign-on is on every band, including the free one. An account can require it for every member except owners, who can always sign in with GitHub, for example to fix a broken identity provider certificate. API tokens created before keep working when SSO is required; review and revoke them when you turn it on. IdP-initiated sign-in is off unless an owner turns it on.
- Not supported yet: SAML single logout, SCIM provisioning, encrypted assertions and more than one identity provider per account. Removing someone at the identity provider stops new sign-ins; remove their membership in Shipglot to end access at once.
- Four roles: owner, admin, reviewer and viewer.
Audit log
Changes to tokens, webhooks, SSO settings, projects, editor actions and billing events are recorded with who did it (user, token or system), what changed, the time and the IP address. Owners and admins read the log through the API (GET /v1/audit). There is no export in the editor yet.
Webhooks
- Outgoing webhooks carry a
Shipglot-Signatureheader: a timestamp and an HMAC-SHA256 of the timestamp and body. Check the signature and reject timestamps more than five minutes old. - Deliveries refuse private, loopback and link-local addresses, resolve DNS again at send time, and do not follow redirects.
- Incoming GitHub and Stripe webhooks are rejected unless their HMAC-SHA256 signatures verify. Stripe events are processed once each.
GitHub App permissions
The App asks for five permissions:
contents: writeto read translation files and commit translations to a branch.pull_requests: writeto open the pull request and post a summary comment.checks: writeto report the "Shipglot" check run, with annotations, on pull requests.metadata: read, which every GitHub App needs.workflows: write, used only to add.github/workflows/shipglot.ymlin the onboarding pull request. The App works without it: the onboarding pull request then adds onlyshipglot.config.jsonand shows the workflow for you to add.
It commits only to its own branches (shipglot/onboarding and shipglot/review/<branch>); your branches change only through pull requests you merge. It only acts on repositories that install it.
Payments
Billing is prepaid through Stripe Checkout and the Stripe billing portal. Nothing is invoiced in arrears, so there is no stored card that can be charged for usage you did not see coming: upgrades are charged when they happen, and translation beyond the included amount needs credits bought in advance.
Over-the-air delivery
Published over-the-air bundles are public by design, so apps can fetch them without a secret. Anyone with a project's public id can read what you publish. Bundles are immutable and carry a SHA-256 checksum.
Retention and deletion
- Expired sessions and sign-in requests are deleted. GitHub delivery ids are kept 30 days, background jobs that failed for good 30 days, and rate-limit counters one day.
- Outgoing webhook deliveries, with their payloads, are kept until you delete their endpoint.
- The audit log, which records IP addresses, has no set retention yet.
- Owners and admins can delete a project in Settings, under Projects. That deletes its strings, comments, suggestions, translation jobs, project API tokens, screenshots and published over-the-air bundles at once; monthly usage records stay for billing. Deleting an account is not self-service yet. Email hello@shipglot.com and we delete it and confirm when it is done. Webhook endpoints and SSO settings can be deleted through the API now. API tokens can be revoked through the API at any time; a revoked token stops working at once, and its record and hash are kept.
What we do not have
Shipglot has no SOC 2 or ISO 27001 certification and has not had an external penetration test. There is no status page yet, because there is no hosted service running for customers.
Report a vulnerability
Email hello@shipglot.com with the steps to reproduce. We will confirm we received it, keep you informed, and credit you if you want. Please do not test against other people's accounts or data.