Skip to content

Security and data handling

How Topicary stores, protects, and serves your documentation.

Hosting

Topicary runs on Vercel's global edge network. All traffic is served over HTTPS with automatic TLS (Transport Layer Security) certificate provisioning and renewal. Vercel provides built-in DDoS (distributed denial of service) protection and automatic scaling.

Database

Content is stored in Supabase-managed PostgreSQL. Databases are encrypted at rest using AES-256. Supabase provides automated daily backups with point-in-time recovery.

Content is stored as TipTap/ProseMirror JSON, a structured document format that preserves formatting, hierarchy, and metadata without relying on raw HTML.

Access control

Every database table uses PostgreSQL Row-Level Security (RLS). Users can only read and write data for projects they belong to. There are no shared tables or global read access to project data. Even direct database queries are scoped to the authenticated user's project membership.

Three roles control what project members can do:

Role

Permissions

Admin

Full access including project settings, member management, billing, and all content operations

Author

Create, edit, and publish content; manage topics, maps, and components

Reviewer

Read-only access through review sessions (no Topicary account required)

Authentication

User accounts use Supabase Auth with email and password. Sessions are refreshed on every request through server-side middleware. Dashboard routes are protected, so unauthenticated requests redirect to the login page. Password reset is available from the login page through an emailed reset link.

Enterprise accounts can additionally sign in through Set up SSO (SAML 2.0).

Published-site sessions

Published sites that use password protection issue their own session, separate from your dashboard login. These sessions are HMAC-SHA256 signed and expire after 24 hours. Changing a site's password immediately invalidates existing reader sessions.

Published sites

Published documentation sites are publicly accessible by design, so anyone with the URL can read them. Do not publish sensitive internal documentation unless you intend it to be publicly available.

Published content is served using a read-only database connection dedicated to serving published content. This client bypasses RLS because published sites are intended for anonymous readers, not project members.

Review access

Reviewers access content through a unique token link, with no Topicary account required. Each review session generates its own token. Tokens grant read-only access to the topics included in that review session.

Content sanitization

All content rendered on published sites is sanitized before serving:

Category

Allowed

Blocked

Event handlers

None

onclick, onerror, and all on* attributes are stripped

URI protocols

http://, https://, mailto:, tel:, relative paths

javascript: URIs

Data URIs

data:image/* for raster images (PNG, JPEG, GIF, WebP)

data:image/svg+xml (SVG can contain scripts)

Custom CSS

Standard CSS properties

@import rules, url() functions that load external resources

Example of how sanitization transforms content:

<!-- Before sanitization (authored content) -->
<a href="javascript:alert('xss')">Click here</a>
<img src="photo.jpg" onerror="alert('xss')" />
<div style="background: url('https://evil.com/track')">Content</div>

<!-- After sanitization (published output) -->
<a>Click here</a>
<img src="photo.jpg" />
<div>Content</div>

API key security

REST API authentication are never stored in plaintext. Each key is `tk_`-prefixed. When a key is generated, Topicary returns the full key to the user once and stores only a SHA-256 hash. Subsequent authentication checks hash the incoming Bearer token and compare it against the stored hash. This means:

  • A database breach does not expose usable API keys.

  • Lost keys cannot be recovered. They must be revoked and regenerated.

  • Each key is scoped to a single project and has an optional expiration date.

Webhook security

Configure webhooks deliveries are signed using HMAC-SHA256. Each webhook subscription has its own signing secret. Topicary computes the HMAC of the request body using the secret and includes it in the `X-Topicary-Signature` header. Recipients should verify this signature using a timing-safe comparison to prevent forged requests.

Webhook signing secrets can be rotated at any time from Settings > Webhooks. After rotation, the old secret is immediately invalid.

SSO / SAML security

Set up SSO (SAML 2.0) responses are verified using the identity provider's X.509 certificate. Topicary validates:

  • The XML signature on the SAML assertion matches the configured certificate.

  • The NotBefore and NotOnOrAfter conditions are within the current time window.

  • The Audience restriction matches the Topicary entity ID.

SAML assertions are processed server-side only, so no assertion data is exposed to the browser.

Encryption

GitHub sync tokens (used for the Sync with GitHub feature) are encrypted at rest using AES-256-GCM before storage. Integration credentials (Zendesk, Salesforce, Phrase TMS) are stored in the integration_configs table with the same encryption approach.

Data storage and versioning

Topics are auto-versioned on every save. When content changes, a snapshot is stored in a separate versions table. Identical consecutive saves are deduplicated.

Map versions duplicate the map structure (item order and nesting) while sharing the same underlying topics.

Deleting and exporting your data

You can delete a whole project from Settings > Danger zone by typing the project name to confirm. This permanently removes the project and its content.

Content export is per map or per topic. Publish a map to a web or PDF target, or use the export options to download content as Markdown (and, on the Enterprise tier, DITA, Word, OKF, or XLIFF).

There is no self-serve button to delete your entire account or download all account data at once. To close your account or request a full data export, contact support and the Topicary team will process the request.

Product analytics

Topicary collects anonymized product usage analytics by default to improve the app. Capture is anonymized and does not set advertising cookies, so no cookie-consent banner is shown. This is separate from the reader analytics collected on your published sites, which cover reader search, page feedback, and AI queries.

Security summary

Layer

Protection

Transport

HTTPS with automatic TLS (Vercel)

Infrastructure

DDoS protection, automatic scaling (Vercel)

Database

AES-256 encryption at rest, daily backups with PITR (Supabase)

Access control

PostgreSQL RLS on every table

Authentication

Supabase Auth, server-side session refresh; SAML 2.0 SSO (Business)

API keys

SHA-256 hashed at rest, project-scoped, optional expiration

Webhooks

HMAC-SHA256 signed deliveries, per-subscription secrets

Secrets

AES-256-GCM encryption for GitHub tokens and integration credentials

Content output

HTML sanitization (event handlers, URI protocols, data URIs, CSS)


See also

Was this page helpful?