Skip to content
Inkstand
← Reference

Security and data handling

Where the data sits, what leaves it, who can read it, and what the sub-processor list contains. Written to be pasted into an assessment.

Where it sits

One database instance, in Stockholm. The only content that leaves it is content a person pressed a button to send.

Deck generation, brand-guideline reading, AI compliance review and claim research each leave on a press. Carousels, brand kits, uploaded images and governance records never do.

The site itself is a static bundle on a CDN. It holds no customer data, sets no analytics cookie and loads no third-party script.

Your browser talks straight to one managed platform in Stockholm, inside the European Economic Area, with no application server of ours in between. Exactly one path leaves that boundary: the AI features, and only when a person presses one. It ends at a model provider that may sit outside the EEA.

your browser

The editor, the checker, the export

TLS, straight to the platform — no application server of ours in between

european economic area

Stockholm

  • Database
  • Authentication
  • File storage

one region · no second region to move to

the AI features, and only when a person presses one

a model provider

May sit outside the EEA

What is not here

No analytics, error reporting, session recorder or ad network — on the site or in the product. That is why there is no cookie banner.

Sign-in is a one-time link, so no password is stored, reused or available to leak.

Who can read what

Isolation is asserted against a real database, in a rolled-back transaction, assuming the same role and identity claims the API assumes. A button hidden from a viewer is a courtesy; the policy is the control.

Administrator status cannot be granted from inside the product. It is seeded out of band, so privilege escalation is a deliberate act at the database.

A limited seat has no account-wide reach: it sees only the workspaces it holds a named grant on. A viewer reads and cannot comment or sign off — the policies refuse both.

Every table carries its own row-level policy, and every one of those policies asks the same shared membership function whether the caller holds a seat in the account that owns the row. The answer decides the result: rows in your own account are returned, and rows in any other account are returned as nothing at all rather than as an error.

every table carries a policy · among them

  • accounts
  • workspaces
  • projects
  • carousels
  • assets
  • templates
  • release records
  • generation audits
  • review links
  • brand grants

One shared membership function

asked by every policy above · keyed to your seat

returned

Rows in your own account

The seat you hold, and nothing inferred from the screen you asked from.

nothing at all

Rows in any other account

Not an error, and not a partial answer. Empty, on every table above.

Keys, headers and uploads

The browser bundle carries only the public key. The keys that bypass row-level policies, and the model-provider key, exist only in server-side functions.

HSTS preloaded with a two-year max-age and includeSubDomains; nosniff; frame-ancestors denied; strict-origin-when-cross-origin; camera, microphone, geolocation and topics denied.

Uploads are allow-listed image types, 8 MB on images and 3 MB on fonts, into a private bucket, served through signed URLs that expire in an hour.

Brand import fetches a URL you give it, server-side, so it is treated as an attack surface. Non-HTTP schemes, private and link-local addresses, intranet names, unbounded bodies and redirect chains are refused.

What cannot be rewritten

Release records, generation audits and the ledger of overridden findings can be read and inserted, never updated or deleted. An update affects no rows, for anyone — including the account owner, including us.

Five rule kinds are decided in code and call nothing. Four need judgement, and every release record states whether that review ran. A rule the reviewer did not reach is recorded as such and never counted as passed.

Leaving

Content is kept until you delete it. Deleting an account cascades to its workspaces; a workspace to its projects, carousels, assets and generation records. Release records survive by design — their purpose is to evidence what was published.

Artwork exports as PNG and PDF, the compliance report as JSON. Nothing you make is held in a format only we can read.

The short answers

Sub-processors
The managed database and object-storage platform, the CDN, and the model router. Eleven runtime packages; two features were written in-house to keep a name off this list.
Training on your content
No.
Encryption
TLS in transit. Encryption at rest is provided by the managed platform; we operate no disks of our own.
Backups
Run by the managed database platform under our plan. Ask and you get the plan’s actual figures.
Penetration testing
More than 800 automated tests on the compliance and rendering logic, plus the database isolation suite. Both run before anything ships.
Data residency
Stockholm.
Session handling
Held in the browser and refreshed automatically. Removal takes effect in the database the moment membership ends, not at next sign-in.
Invites
32 random bytes, single use, fourteen-day expiry, bound to the invited address.