Skip to content
Wixy

Security

What one client breaks stays with that client

Separate build, separate process, separate token, separate artifact. And the code the AI writes never runs inside the platform: it compiles in a container with no network and is served from a process that can only reach what’s already public on your site. Here it is, piece by piece: how it holds up, and what happens when something fails.

The layers

Six things that live in the code, not in a promise

Each one has a test, and the test is trying to break it: read another client’s data, compile code that calls another server, mark an order as paid with a forged notification. Whatever doesn’t survive the attempt doesn’t ship.

  • Isolation in three layers

    Every table carries the client as a foreign key, access control filters every read and every write, and Row-Level Security filters again inside the database itself. If a query slips past the first two, the third returns zero rows, not someone else’s.

  • Builds in a container with no network

    The code the AI writes compiles in a throwaway container: no network, no credentials, a read-only root and a hard time limit. If a change loops forever, it gets cut off after a few minutes and takes nobody down with it. And nobody installs dependencies because a prompt asked for them.

  • The renderer only reads what’s published: See how publishing works

    The process serving your site carries a token that only reaches your client’s published content, runs without a single variable holding a secret, doesn’t write to disk and has a time limit per request. If the code did something odd, the furthest it gets is what’s already public on your site.

  • Payment credentials, encrypted: See the online store

    Your gateway keys are stored encrypted with AES-256-GCM, shown once — after that only the last four characters remain as a hint — and they never leave the core: not to the browser, not to the process that draws your store. A notification with a bad signature marks nothing as paid, and it gets logged.

  • An audit trail of everything, that nobody edits

    Who published, who rolled back, who moved credits, who exported submissions, who signed in to your account. It’s written from the server, and through the API it can’t be created, edited or deleted, not even by us. Publishing and payment records are kept for at least twelve months.

  • Backups, and two versions that are never deleted

    The database and the file store are backed up, and every client’s theme is dumped separately. The published version of your site and the one before it are never archived, whatever your plan’s retention says: being able to go back isn’t a paid extra.

Isolation

Three layers, and the last one lives inside the database

Isolation between clients isn’t left to the application code, because a slip there isn’t a style problem: it’s a data leak. So there are three locks, one behind the other, and the first one to fail isn’t the last. Every table carries the client as a foreign key, access control filters every read and every write, and Postgres filters again on its own.

  • Deny by default

    Without the active client set on the session, the database returns no rows at all. A slip on our side gives an empty list, never somebody else’s data.

  • The inner tables too

    A page’s content is its blocks, and those live in their own tables. Those carry a policy as well: without it, a direct query would read them all even with the page itself locked down.

  • And it won’t start if one is missing

    On boot, the platform checks that every isolated table has its policy. If one is missing, it doesn’t start. An oversight never reaches production waiting for somebody to notice.

How publishing and rolling back work
$ mc abrir clinica-san-jose
12 files in apps/sitios/src/temas/clinica-san-jose
$ mc guardar clinica-san-jose -m "Header with appointments"
✓ v22 saved (origin: team)
$ mc construir clinica-san-jose
✓ v22 built in 41 s
$ mc publicar clinica-san-jose
✓ v22 published · to go back: mc revertir
$

What the AI leaves alone

Three gates, and all three are code

An allowlist of folders a prompt can touch, a blocklist above any setting, and a per-file flag the team sets and clears. The most restrictive one wins, and it’s checked twice: when the version is saved and again before it compiles. The prompt is an instruction; the gate is code.

The AI can change

  • bloques/ · layouts/ How each piece and each page looks. If you don’t like the result, you discard it from the preview and it never reaches your site.
  • componentes/ The theme’s helper pieces and the look of every form field. Only the look: what gets asked and where it goes, no.
  • estilos.css · tema.json Colors, typefaces and spacing. The manifest is declarative JSON: nothing that runs at build time.
  • paginas/ The templates for a post, a category or a product, except the ones the team has locked for you.

The AI never touches

  • comercio/ Cart, checkout, account and payment. Whatever charges money lives in the core, and no prompt reaches this folder.
  • sistema/ The SEO <head>, data loading and the props contract. A redesign can’t take them away.
  • Secrets and keys The process serving your site doesn’t hold a single secret in its environment. The AI can’t read what isn’t there.
  • Another client Not their files, not their content, not their balance. What gets sent to the model comes from your client alone.

A component that tries to read the disk, read environment variables or call another server doesn’t build, and the message says what to change. If a proposal touches something forbidden, that part isn’t applied, you’re told in plain language what was done and what wasn’t, and no credits are charged: if the model tried something it shouldn’t, we’re the ones who need to do better.

The head belongs to the system

What costs you business when it breaks is drawn by the system, not the theme

Title, canonical URL, Open Graph and structured data come out of sistema/, beyond any prompt’s reach. And a form submission goes to the core, not to the site: it’s validated there against the schema, whatever the design says. Those are the two things that, when a redesign breaks them, nobody notices until the customers stop arriving.

  • An AI redesign can’t break your SEO: it never reaches the <head>
  • Anything set to noindex stays out of the sitemap, by definition and not by configuration
  • A form that doesn’t draw a required field doesn’t validate: it’s the same error as removing it
  • A submission is only accepted from a domain that’s yours, and anything not declared in the schema is dropped

See the SEO module

sistema/Cabeza.astro → <head> set by the system · the AI can’t reach this
<title>Zapatillas Runner · Tienda San José</title><link rel="canonical" href="https://clinicasanjose.pe/tienda/zapatillas-runner"><meta property="og:image" content="…/zapatillas-runner-og.jpg"><script type="application/ld+json">{"@type":"Product","offers":{"price":"189.00","priceCurrency":"PEN"}}</script>

If something goes wrong

What happens when something broken gets published

You don’t have to be the one who notices, and you don’t have to write to us on a Sunday night.

  1. The router counts it

    If the version just published doesn’t start, or fails several times in its first few minutes, it gets flagged. A page that arrives half-written counts too: it’s the most common failure in a theme and it doesn’t throw a visible error.

    5 failures in 5 minutes

  2. It rolls back on its own

    The pointer goes back to the version that was published before. Since its package already exists, it takes as long as one query: nothing is rebuilt.

    no human involved

  3. It’s written into your history

    A version is created documenting the rollback, so “keep editing” doesn’t start from the broken one. The failed version keeps the reason in its log, so it can be looked at.

    origin: system

  4. And it alerts us

    The alert goes out once, not on a loop. We read the build log and tell you in plain language what happened: what needs changing, not what failed.

    frontend.reversion-automatica

And if the change fails before it ever gets there, it doesn’t publish at all: a failed build leaves that version flagged with its error log and doesn’t touch the one that’s live. A change of yours never takes your site down.

In numbers

What stands between your site and the one next door

layers of isolation between clients
3 layers of isolation between clients foreign key · access control · Row-Level Security
credentials in the process that serves your site
0 credentials in the process that serves your site no database, no gateway, no AI provider
policy checks: when the version is saved and before it compiles
2 policy checks: when the version is saved and before it compiles the same rule, written in one place in the code
throwaway container per build, with no network and no credentials
1 throwaway container per build, with no network and no credentials created, compiled, destroyed

Questions

What people ask before they trust us

Can the AI see another client’s data?

No. What gets sent to the model comes from your client: your theme files, the type contract and a sample of your content marked as data. Theme files are never shared between clients even when their contents match, and the three layers of isolation, foreign key, access control and Row-Level Security, apply to a query coming from the AI exactly as they do to one coming from the panel.

Who can sign in to my account?

Your users, with the roles you give them. And our team, only to support you: they sign in as your owner user for one hour, with a permanent banner on screen and an audit entry on the way in and on the way out. While inside, they can’t create API keys or change passwords. A change we make that way is logged under our name, never yours.

What if the generated code tries to do something odd?

It doesn’t build. Before compiling, a validator rejects what a theme never needs: reading the disk or the environment variables, calling another server, running code through eval, embedding unsanitized HTML, or loading images and scripts from elsewhere. And if something gets around the validator, behind it are the container with no network or credentials and the renderer that only reads its own folder and only reaches your client’s published content. None of the three layers is assumed to be enough on its own.

Where is my customers’ card data?

With your payment gateway (Culqi, Mercado Pago or Stripe), not with Wixy: payment happens on their page or on the core’s, never in the theme, and we don’t store card numbers. What we store are your gateway credentials, encrypted, and the notifications the gateway sends to the core. An order is marked paid only with what the gateway has confirmed with its signature; the same notification twice charges once, and an amount that doesn’t match the order marks nothing and gets audited.

And my form submissions?

They go to the core, never to the process that draws your site, and they’re only accepted from a domain that’s yours. The validation that counts is the server’s, against the form’s schema: anything not declared is dropped. Attachments go to a private folder, outside the media library, and are downloaded with a signed link that expires in ten minutes. The visitor’s IP is stored only if the form says so, and exporting or deleting submissions is logged in the audit trail.

What if the preview of my unpublished site leaks into Google?

It can’t. A preview lives on a separate domain, never on yours, goes out with the header that tells search engines not to index it, and needs a short-lived signed link to open. It shows published content by default: seeing drafts takes a different signed link, requested separately. And on your production domain there’s no way to ask for any version other than the published one.

What happens if another client’s site goes down or publishes something broken?

Nothing happens to yours. Each client has their own build, their own process and their own artifact; a renderer that hangs gets killed and replaced, and that affects that client alone, never the others and never the panel. And if you’re the one who publishes something broken, the router catches it within the first few minutes, rolls back to the previous version on its own and writes it into your history.

Try to break it. It goes back to how it was in seconds.

A free site at yourname.wixy.app, with the same three layers, the same sandbox and the same audit trail as a paid plan.