Security & trust
How the widget is isolated, how credentials are stored, how access is controlled, and how public content is moderated.
Widget isolation
The widget UI renders inside a sandboxed iframe served from the Annot8 origin. Two consequences, both deliberate:
- Your site's CSS cannot break the widget, and the widget's styles can never leak into your page.
- The widget cannot read your page's cookies, storage, or session, and your page cannot read the widget's.
There is intentionally no custom-CSS hook, because it would require giving up that boundary.
Domain allow-listing
A project's environments define which hostnames the widget may run on. A page whose hostname matches nothing gets nothing.
A bare * wildcard is rejected — there's no configuration that makes the widget
embeddable from any origin.
Origin-validated widget sessions
Before any public write is accepted, the widget requests a session token.
Annot8 validates the browser-sent Origin header against the project's
environment patterns, and only then issues a short-lived token. Writes without a
valid token are rejected.
This is what makes the project key safe to publish in your HTML: it's an identifier, not a credential. On its own it can't be used from a domain you haven't authorised.
Integration credentials
Third-party credentials — API tokens, webhook URLs — are encrypted with AES-256-GCM before being stored, using an envelope scheme that supports key rotation without downtime.
They're only ever decrypted server-side at delivery time. They are never returned to the browser, never included in a client query, and never rendered back into the settings form.
Access control
- Workspace isolation. Every query is scoped to a workspace you're a member of. Membership is checked server-side on every read and write, not in the UI.
- Role permissions. Owner, admin, and member map to a fixed permission set, enforced on the server. See Team members.
- Guest scope. Guests who comment through a public link have no dashboard access and cannot see other people's submissions.
Content reports
Public surfaces need a reporting path, so the feedback portal has one:
Anyone can report
A visitor reports a post or comment. They receive a receipt link they can revisit at any time to see the current status.
Your team reviews
Reports land in Project → Moderation. States are: received, under review, action taken, no action, and appeal under review.
The reporter can appeal
If they disagree with the outcome, they can appeal from the same receipt link, which reopens the report for review.
Removed content is marked with a reason rather than silently disappearing, so the record of what happened survives.
Data handling
What the widget collects, what it deliberately doesn't, and how screenshots are redacted is covered in What gets captured and Privacy.
Reporting a vulnerability
Email security@annot8.app. Please include enough detail to reproduce, and give us a reasonable window to fix before disclosing.
Documents
| Document | Where |
|---|---|
| Privacy policy | annot8.app/privacy |
| Terms | annot8.app/terms |
| Data processing addendum | annot8.app/dpa |
| Subprocessors | annot8.app/subprocessors |
| Security overview | annot8.app/security |
| Cookies | annot8.app/cookies |