Skip to content
assetlib

Assetlib security

Security, plainly.

What protects your workspaces, your artwork, and the apps that display it, as built today. Each control on this page was checked against the console’s code or its providers’ settings on the date below. Assetlib is a developer preview: there is no production SLA, no independent audit, and no SOC 2 report.

Last updated October 10, 2026. Covers the console at console.assetlib.dev and its delivery routes, the Assetlib SDKs, and this website. What each surface collects is in the privacy notice.

The database keeps each workspace apart.

Workspaces share one PostgreSQL database, and the database itself enforces the boundary. Every table that holds workspace data has row-level security turned on and forced. The console connects through two restricted roles, one for workspace data and one for sign-in; neither is a superuser or can bypass row-level security. A query that does not carry a signed-in member’s workspace sees no workspace rows.

  • Roles are checked on every operation. A member is an owner, publisher, editor, or viewer, and the database checks the current role each time. Viewers read; owners, publishers, and editors prepare drafts; only owners and publishers publish. Only owners manage members, app tokens, and webhooks. Removing a member or lowering a role applies from their next request.
  • Owners have an activity log. Publications, promotions, restores, approvals, and changes to members, tokens, and integrations are recorded with who made them. Only owners can read the log, and its entries cannot be edited or deleted.
  • App tokens are narrow. A token for CI or the Figma plugin belongs to one app and carries only the scopes it was given. No token can publish or archive.

Automated tests run these boundaries against PostgreSQL with the restricted roles: cross-workspace reads and writes, role checks, and forced row-level security on every workspace table.

Apps check every release before they use it.

The console signs each release manifest with an Ed25519 private key. Your app’s public SDK configuration pins the matching public keys, and before using anything in a release the SDKs check:

  • the signature, against a pinned key;
  • that the release names your workspace, app, and environment;
  • that its release number is higher than any the app has already accepted, so an older release cannot be replayed;
  • each image’s byte length and SHA-256 hash, before it is cached or shown, and again when it is read from the cache.

The SDKs fetch artwork only from your app’s own delivery paths on the console’s address, send no cookies or credentials, and refuse redirects. When a check fails or the network is unavailable, the app shows a verified cached image or the image bundled with it. A release delivers artwork only, images and Lottie JSON, never code.

Published artwork is public by design: anyone with a delivery URL can fetch a published release’s manifest and images. Unpublished artwork needs a workspace sign-in or one of the app’s draft tokens, and original uploads need workspace membership. The privacy notice says exactly what becomes public.

Secrets are encrypted or kept only as hashes.

  • Release signing keys and the signing secrets of webhooks you create are encrypted with AES-256-GCM, each bound to its own database row, under a key that is held in the hosting environment, not in the database.
  • App tokens are stored as a SHA-256 hash and a short prefix. The full token is returned only when it is created.
  • The GitHub token issued at sign-in is stored encrypted and used only to complete sign-in.
  • Rate-limit counters hold a keyed hash of each IP address, not the address.
  • Public SDK configurations hold identifiers, a delivery URL, and public keys. Apps never need a private key or an editing credential.

Sign-in goes through GitHub.

The hosted console has no passwords. You sign in with GitHub over OAuth, handled by the Better Auth library. Assetlib asks only for the read:user and user:email scopes, requires a verified email address, and does not link a second sign-in to an account.

  • A session lasts eight hours and is not extended. Its cookie is Secure, HttpOnly, and SameSite=Lax. You can see and end your sessions under Settings › Sessions.
  • A change made with a session must come from the console’s own pages; requests from other origins are refused.
  • Console pages are served only over HTTPS, with HTTP Strict Transport Security, and cannot be framed by other sites.
  • Assetlib does not check whether your GitHub account uses two-factor authentication. Turn it on in GitHub, since it guards your Assetlib sign-in.

Where it runs, and who processes the data.

Console and delivery
Vercel, with server functions in its Washington, D.C. region (iad1, US East). Published manifests and images can also be cached by Vercel’s network and by browsers.
Database
Neon managed PostgreSQL, in AWS US East 1 (Northern Virginia).
Artwork files
Cloudflare R2, stored in Eastern North America. The bucket has no public address: its r2.dev URL is off and no custom domain is connected, so files reach apps only through the console’s delivery routes.
This website
Vercel. It has no accounts, forms, or analytics.

Subprocessors

Three providers process data on Assetlib’s behalf, the same three the privacy notice names:

  • Vercel hosts the console, its delivery routes, and this website.
  • Neon provides the database for accounts, sessions, and workspaces.
  • Cloudflare stores uploaded images and animations in R2.

GitHub provides sign-in under your own GitHub account’s terms.

Backups, as they stand today.

  • Database: Neon keeps point-in-time history, one day at present, so the database can be restored to any moment within it. A restore to a separate copy was rehearsed on October 9, 2026 and checked against production. A copy is also taken inside Neon before each change to the database schema.
  • Artwork files: each file is named by its SHA-256 hash. R2 keeps no earlier versions of a file, so the files are copied out of R2 periodically, and each copy is checked against those hashes.

Deleting data removes it from the live service. Backup copies can keep it until they are deleted, as the privacy notice explains.

Rate limits bound the load.

The console and its delivery routes limit requests per IP address: 180 a minute in general, with lower limits on sign-in, uploads, usage reports, invitations, and new workspaces. Over a limit, a request gets status 429, and an integrated app keeps showing verified cached or bundled artwork. The numbers, the response, and what each SDK does are in the guide. These limits bound the preview’s load and cost; they are not a guarantee against denial of service.

What is planned, and what is not claimed.

  • Planned: two-factor sign-in in Assetlib itself, and uptime monitoring with a public status page.
  • Not claimed: SOC 2 or any other certification, an independent security audit or penetration test, a production SLA, or a bug bounty.

Report a vulnerability privately.

If you find a vulnerability in any part of Assetlib, including the console, an SDK, a plugin, or this website, report it through GitHub’s private vulnerability reporting on the AssetLib/sdk-js repository. The report reaches the maintainers privately, whichever part is affected. Do not open a public issue with exploit details, and leave secrets and personal data out of the report.

Test only against your own workspace. The terms rule out load or security testing of the hosted console without our written agreement, probing other workspaces, and getting around rate limits.

There is no bug bounty and no guaranteed response time.