Security at Specsight
How we handle your code, your data, and your access. We aim to be specific and honest — including about what is and is not in place at this stage of the product.
Your source code is never stored
Repositories are cloned to a temporary environment, analysed, and deleted in the same job. Only the extracted specification persists.
Read-only GitHub access
Specsight uses a fine-grained GitHub App with read-only permissions. It cannot write to, merge into, or modify your repositories.
Row-level security on every org table
Multi-tenancy is enforced at the Postgres layer, not just in application code. Cross-organisation data access is not possible.
European operator, GDPR compliant
Specsight is operated from Poland. We follow GDPR, and a Data Processing Agreement is available on request.
GitLab connections use an access token you create; Specsight stores it encrypted and never writes to your code.
How we handle your source code
This is the most common question we get, so we are explicit about every step.
During analysis. When you trigger a full scan, a background job clones your repository with a shallow Git clone (--depth 1 --single-branch) to a temporary directory created with the operating system’s mkdtemp primitive. For GitHub, the clone uses a short-lived GitHub App installation token, not a long-lived credential. For GitLab, it uses the access token you provided, decrypted for that job only.
What is excluded. Before the scan agent reads anything, the clone is stripped of everything that is not source code. .env files of every kind (.env.local, .env.production, and so on), media, binaries, archives, data files, and lockfiles are removed, so they are never analysed or sent to Claude.
After analysis. The temporary directory is deleted in a finally block — so even if the analysis fails partway through, the code is removed. The cleanup runs whether the scan succeeded, failed, or was cancelled.
What persists. Only the extracted specification: features, scenarios, annotations, connections, and metadata about the scan itself (token usage, duration, status). The raw source code, file contents, and commit messages are not stored anywhere in Specsight.
During merge syncs. When you merge to your watched branch, Specsight receives a webhook and analyses only the diff for the changed files. The diff is sent to Specsight for analysis and is not persisted after the sync completes.
GitHub App permissions
For GitHub, Specsight integrates via a fine-grained GitHub App — not a personal access token, not an OAuth app with broad scopes.
- Read-only access to repository contents. Specsight can read files, branches, commits, and diffs. It cannot write, push, merge, open pull requests, or modify your repositories in any way.
- Webhook events. The app subscribes to three events:
push(to trigger merge syncs),installation(app install/uninstall), andinstallation_repositories(repo added to or removed from the installation). - Webhook signature verification. Every incoming GitHub webhook is verified using HMAC-SHA256 with a timing-safe comparison against a secret known only to Specsight and GitHub. Unsigned or mismatched deliveries are rejected.
- Replay protection. Each delivery is enqueued on the background-job system with an idempotency key derived from its delivery ID, so a replayed delivery cannot run twice.
- Installation-scoped tokens. When Specsight needs to clone your repository, it generates a short-lived installation token at the moment of the scan. That GitHub token is never stored.
GitLab access tokens
For GitLab there is no app to install: you create an access token and Specsight stores it. This is exactly what that means.
- What you provide. An access token plus your instance URL: gitlab.com or a self-managed host, https only. The recommended token is a fine-grained personal access token that grants only what Specsight uses: User: Read, Personal Access Token: Read and Project: Read on the User tab, and Project: Read, Repository: Read, Branch: Read, Code: Read, Code: Download, Webhook: Create, Webhook: Read and Webhook: Delete on the Group and project tab. On GitLab older than 19.2, or with a group access token, a legacy token with the
apiscope. - What is stored. Per organisation: the instance URL, the numeric id and username of the token’s owner (and whether it is a bot account), the token itself encrypted in Supabase Vault, a per-connection webhook secret, and the token’s expiry date when GitLab reports one.
- How the token is used. It is decrypted only to call the GitLab API: to list the repositories it can see and read the ones you watch, to create and remove Specsight’s own webhooks on those repositories, to clone a repository for analysis, and once a day to confirm the token still works. It is sent only to the https host you entered. A self-managed instance is operated by you, not by Specsight.
- Network reach. Specsight reads code from the cloud (Vercel and Trigger.dev), which has no fixed outbound IP addresses. A self-managed instance must be reachable over https from the public internet; Specsight cannot currently be allow-listed by IP or reach an instance behind a VPN.
- Least privilege where GitLab offers it. A fine-grained token created with those permissions can only read your user profile and the token’s own details, list and read repositories, branches and code, and create, list and delete webhooks. Before storing a token Specsight checks that every one of those permissions is present and refuses a token missing any of them or carrying more. A legacy
api-scope token can write. Either way, Specsight never writes to your code. - Webhook verification. GitLab deliveries are verified by comparing the per-connection secret in the
X-Gitlab-Tokenheader with a constant-time comparison, not by an HMAC signature. Deliveries with a missing or mismatched token are rejected. Replay protection works as for GitHub: each delivery is enqueued with an idempotency key. - Expiry and rejection. Admins and Developers are emailed 30 days, 7 days, and 1 day before the token expires, and when GitLab rejects it. A rejected token is not purged automatically: replace it or disconnect GitLab.
- Revocation and destruction. The stored token is destroyed when you disconnect GitLab, replace the token, or delete your organisation. Revoking the token in GitLab stops all access immediately. Disconnecting also asks GitLab to remove the webhooks Specsight created; if the token has already expired or been revoked, GitLab refuses and those webhooks stay on your repositories until you delete them in GitLab. They carry no credential, and any delivery to Specsight is rejected once the connection is gone. If we have reason to believe a stored token may have been exposed, we email your Admins and Developers so you can revoke it at the source.
AI processing
All code analysis and text generation is handled by Anthropic’s Claude.
Specsight uses the Claude Agent SDK for codebase analysis (full scans and merge syncs) and the Claude API for text generation tasks like feature descriptions, change reports, merge triage, and answering your questions in Ask Specsight. Both run against Anthropic’s hosted API.
Per Anthropic’s privacy policy, inputs are not used to train their models. Anthropic retains API inputs for up to 30 days for abuse and safety review only, then deletes them. We do not currently have a Zero Data Retention agreement with Anthropic — if your security review requires one, contact us and we can raise it with them. Anthropic’s broader security posture is documented at trust.anthropic.com.
Whose Anthropic account analyses your code. By default, code is analysed using Specsight’s own Anthropic account. Organisations still on our former BYOK plan use their own Anthropic API key until they move to Standard, so their code goes to their own Anthropic account. The encrypted storage of those keys is described in Encryption.
Ask Specsight. When you ask a question in Ask Specsight, your question, the conversation so far, and the relevant parts of your spec (in a project’s Ask) or your account and billing state (in the Specsight Help drawer, for Admins) are sent to the Claude API to compose the answer — under the same Anthropic data policy above, and using your organisation’s own Anthropic key when it is on BYOK. Unlike code analysis, Ask conversations are kept: your questions and Specsight’s answers are stored so you can reopen, pin, or export a thread, and you can delete a thread at any time.
Every AI call logs input and output token counts, cost, and duration to an internal ai_usage_log table for billing and quotas. That usage log holds token counts and metadata only — never your prompts or AI outputs. Ask Specsight conversations are stored separately, as described above.
Data storage and access control
Organisation data is stored in Supabase Postgres. Every table is protected by Row-Level Security.
Row-Level Security (RLS). Every table holding org-scoped data has RLS policies enforced at the Postgres layer. A user authenticated to one organisation cannot read or modify data belonging to another — even if a bug in application code tried to request it. Multi-tenancy is enforced in the database, not only in the application.
What is stored. Features, scenarios, annotations, changelogs, feature connections, feature summaries, projects, organisations, members, profiles, API key hashes, encrypted BYOK keys, encrypted GitLab access tokens, and Ask Specsight conversations (the questions you ask and the answers Specsight returns).
What is not stored. Raw source code, repository file contents, full commit history, plaintext API keys, or plaintext access tokens.
Edit history. Every change to a scenario or feature — whether by Specsight or a teammate — is recorded in a changelog table (scenario_changelog, feature_changelog) with the change type, the source (AI vs human), the timestamp, and the author for human edits. Members can see this history in the activity feed.
Encryption
All data in transit is encrypted, and sensitive secrets have an additional layer of protection at rest.
- In transit. All connections use TLS/HTTPS. This includes API requests, webhook deliveries, database connections, and any calls to third-party services.
- At rest (database). The Supabase-managed Postgres database encrypts stored data using Supabase’s platform defaults.
- BYOK API keys (Bring Your Own Key). Organisations still on our former BYOK plan store their Anthropic key in Supabase Vault, a dedicated secrets manager, not a regular database column. It is only decrypted at the moment of use, is never logged, and is deleted when the organisation moves to Standard. The underlying RPC functions that read BYOK keys are
SECURITY DEFINERand restricted to the database service role. - GitLab access tokens. Stored the same way as BYOK keys: encrypted in Supabase Vault, decrypted only at the moment of use, never logged, and read through service-role-only database functions. Destroyed when you disconnect GitLab, replace the token, or delete your organisation.
- Webhook signatures. GitHub webhooks are verified using HMAC-SHA256 with a timing-safe comparison, not a simple string equality check. GitLab webhooks carry a per-connection secret token instead of a signature; Specsight checks it with the same constant-time comparison.
Authentication
Specsight uses Supabase Auth for all authentication.
- Supported methods. Email and password, Google OAuth, and magic link (used for invitation acceptance).
- Password storage. Password hashing is handled by Supabase Auth using industry-standard algorithms. Specsight never sees or stores plaintext passwords.
- Sessions. JWT-based sessions are delivered as Secure, SameSite=Lax cookies managed by Supabase Auth. The session cookie is readable by the application in the browser (required for live in-app updates); Specsight's own cookies (active organisation, invitation state) are HttpOnly.
- Multi-factor authentication. MFA is not currently enabled in production. TOTP support and SSO (SAML/OIDC) are on the roadmap — if your procurement process requires either, let us know.
MCP API keys
API keys for the Specsight MCP server are designed so a database breach would not expose usable credentials.
- Hash-only storage. The full API key is shown to you exactly once, at creation. Only a SHA-256 hash is stored in the database. If the database were ever exposed, existing keys would not be usable.
- Prefix for identification. All keys start with
sk_sp_. The first 8 characters are stored separately so you can identify which key is which in the UI without the hash being exposed. - Org-scoped. Each key is scoped to a single organisation. Members can see and revoke their own keys; admins can see and revoke any key in the organisation.
- Soft revocation. Revoked keys are marked with a timestamp rather than deleted, so the audit trail is preserved.
Subprocessors
The third-party services Specsight relies on to operate. Each one is listed below with its purpose and the data it may handle.
| Service | Location | Purpose & data |
|---|---|---|
| SupabaseSupabase Inc. | UK (London) | Database, authentication, realtime, Vault (secrets), storageOrganisation and user data, scenarios, annotations, encrypted BYOK keys and GitLab access tokens |
| AnthropicAnthropic PBC | USA | AI code analysis (Claude Agent SDK), text generation, and Ask Specsight answers (Claude API)Source code during analysis (transient), generated specifications, Ask Specsight questions and answers |
| GitHubGitHub, Inc. (Microsoft) | USA | Repository access via GitHub App, webhook deliveryRepository metadata, code changes, release identifiers, short-lived installation tokens |
| GitLabGitLab Inc. | USA | Repository access and webhook delivery for organisations that connect gitlab.com. A self-managed instance is operated by you and is not a subprocessorRepository metadata, code changes, release identifiers, the access token you created (sent with each request) |
| VercelVercel Inc. | UK (London) | Application hosting, serverless compute, analyticsHTTP metadata, error logs, web vitals |
| PostHogPostHog Inc. | EU (Frankfurt) | Cookieless website analytics on public pages, signup and onboarding, and product-usage events for signed-in membersPage views, scroll depth, click positions, browser details, with the IP address hashed into a daily visitor ID, then discarded. Product actions with the random IDs of the account and organisation, never names, emails or content |
| Trigger.devTrigger.dev Ltd. | USA (AWS us-east-1) | Background job orchestration for scans and merge syncsJob payloads (scan parameters, results), task metadata |
| StripeStripe, Inc. | USA | Payment processing and subscription managementStripe customer ID, subscription ID, plan type |
| ResendResend Inc. | USA | Transactional email delivery (invitations, notifications)Email addresses, invitation content, notification content |
| LoopsLoops Right Inc. | USA | Marketing and lifecycle email, mailing-list subscriptions, hosted unsubscribeEmail address, full name, signup source, mailing-list membership state; for lifecycle emails, organisation name, the free trial’s main use and activity counts, project name, one Highlight’s wording, and a cancellation reason |
Data held in the UK is covered by the EU’s adequacy decision for the UK. Transfers to the USA rely on the EU–US Data Privacy Framework or Standard Contractual Clauses as appropriate. See the privacy policy for the full legal basis.
Operations and personnel
Specsight is operated by one person today. We say so plainly because it shapes the answers below.
- Production access. Ola Piętka, the founder, is the sole operator with access to production infrastructure (Supabase, Vercel, Trigger.dev, Stripe, Resend). New team members will not get production access without a documented review.
- Backups. Daily backups are handled by Supabase as part of the managed Postgres service. We have not yet rehearsed a full restore from backup — this is on the roadmap.
- Security headers. All responses set HSTS (2-year, preload),
X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin, and a locked-downPermissions-Policy. A formal Content Security Policy is not yet deployed and is on the roadmap. - Rate limiting. Public-facing endpoints (contact forms, OAuth, the MCP server) have per-IP rate limits. The implementation is in-memory per serverless instance — defence in depth rather than a hard guarantee.
- Vulnerability management. Dependencies are pinned in
package-lock.jsonand updated on a regular cadence. We watchnpm auditand GitHub’s built-in vulnerability alerts on the repository. Critical vulnerabilities are patched promptly after disclosure.
Compliance and your data rights
Specsight is operated from Poland by Ola Piętka, a registered sole proprietorship. Personal data is handled under GDPR.
- GDPR. Specsight follows the General Data Protection Regulation. The privacy policy details lawful bases for processing, data retention, and your rights as a data subject.
- Data subject rights. You can request access to, correction of, or deletion of your personal data. Account deletion is processed immediately on request — your user account, organisation data, scenarios, and connected projects are removed from the active database via cascading foreign-key constraints. Backups held by Supabase rotate out within 7 days.
- Data residency. The Supabase Postgres database — where organisation data, scenarios, and annotations are stored — is hosted in the UK (London,
eu-west-2). Application requests and serverless functions run on Vercel in the same region (lhr1, London). Background jobs run on Trigger.dev’s managed cloud in AWSus-east-1(N. Virginia, USA). - International transfers. Data held in the UK is covered by the EU’s adequacy decision for the UK. Where data is processed in the USA — including by background jobs on Trigger.dev and AI calls to Anthropic — transfers rely on the EU–US Data Privacy Framework or Standard Contractual Clauses.
- Data Processing Agreement (DPA). A DPA is available on request. Email us at the address in the next section.
- Breach notification. In the event of a personal data breach, Specsight will notify the Polish supervisory authority (UODO) within 72 hours of becoming aware, and affected users directly if the risk is high.
What we do not claim
Specsight is an early-stage product. We think being specific about what is and is not in place matters more than marketing language.
We have not yet pursued external compliance certifications such as SOC 2 or ISO 27001. Security reviews and penetration testing are on the roadmap but have not been commissioned at the time of writing. If your procurement process requires any of these, let us know — we can discuss where we are and what is realistic to commit to.
The practices on this page are what the product does today. As the product matures and we add subprocessors or capabilities, this page will be updated and the privacy policy will be versioned accordingly.
Reporting a security issue
If you believe you have found a security vulnerability in Specsight, we want to hear about it.
Email ola@specsight.app with SECURITY in the subject line. Include a clear description of the issue, steps to reproduce if possible, any related URLs or proof of concept, and your assessment of the impact.
We take reports seriously and respond as quickly as we can. We ask that you give us a reasonable window to investigate before public disclosure, and that you avoid accessing data that is not your own while testing.
Frequently asked questions
No. Specsight reads your code, it does not keep it. For an analysis the repository is copied to a temporary environment, read, and deleted in the same job. What stays afterwards is only what Specsight wrote: features, scenarios and connections. On every release only the changed code is read, and that is not stored either.
All code analysis and text generation is performed by Anthropic's Claude. Per Anthropic's API privacy policy, inputs sent to their API are not used to train their models. Specsight uses the Claude Agent SDK for full analysis and the Claude API for text generation like feature descriptions, digests, and release notes.
Read-only, and nothing else. Specsight connects through a GitHub App with fine-grained permissions to read repository contents, file trees, commits and code changes. It cannot write to your repositories, merge anything, or change them in any way. It subscribes to push and installation events so it knows when a release has landed.
Through an access token you create in GitLab and paste into Specsight with your instance URL, so gitlab.com and self-managed GitLab both work. Specsight stores it encrypted and never writes to your code. The permissions the token needs and what happens when it expires are in connect GitLab and on the security page.
Every org-scoped table in Specsight's database has Row-Level Security (RLS) policies enforced at the Postgres layer via Supabase. A user authenticated to one organisation cannot read or modify data belonging to another. Multi-tenancy is enforced in the database, not just in the application code.
When you generate an MCP API key, only a SHA-256 hash is stored in the database, never the full key. If the database were ever exposed, existing keys would not be usable. Keys are prefixed with sk_sp_ for identification and are scoped to a single organisation. Revocation is soft-only so the audit trail is preserved.
Account deletion is processed immediately. Your account is removed from the active database via cascading foreign-key constraints, and Supabase backups rotate it out within 7 days. Deleting an organisation cascades to every project, feature, scenario and changelog entry inside it. If other members remain, the organisation persists and only your account leaves. Billing records are retained for the period required by Polish tax law, 5 years from the end of the tax year. Full detail on the security page.
Yes. A DPA is available on request. Email ola@specsight.app and we will send you one.
Email ola@specsight.app with "SECURITY" in the subject line. Please describe the issue clearly, include steps to reproduce if possible, and give us a reasonable window to respond before any public disclosure. We take reports seriously and respond as quickly as we can.