# How data privacy works

> Three privacy classes, enforced by the database itself: private per user, shared with members, or public to read.

Once your app has users, the most important question is: who can see which data? Vaulter is built so the safe answer is the default, and the rules are enforced by the database itself, not by code the agent might get wrong.

## Three privacy classes

Every table in your app is declared as one of three classes, and the platform generates the enforcement:

- **Private per user.** Each signed-in user reads and writes only their own rows. If someone creates a booking, saves a note, or uploads a file, that record belongs to them, and nobody else's account can see it. This is the class the agent uses for personal data.
- **Shared.** Every signed-in user of your app can read and write all rows. Right for genuinely collaborative data, like a team board everyone edits.
- **Public.** Anyone can read the rows, but only signed-in users of your app can write them. Right for content everyone browses, like a product catalog or an events list.

The agent declares the class when it creates a table, and you can see the resulting policy on any table with the **View Policies** button in the Database panel. The rules live in the database itself, so they hold no matter what the app's code does.

## Membership is the boundary

Behind all three classes sits one idea: your app knows who its members are. When someone signs in to your app for the first time, they become a member of that app, and every privacy rule checks membership plus, for private data, ownership of the row. Data in one app is never visible to users of another app.

## Signing in and reading data

Reading personal or shared data requires being signed in. That is what makes per-user privacy possible: the app has to know who you are before it can show you only your rows. Signed-out visitors can use your app's public pages, and can read tables you have marked public, but they cannot touch member data.

## Built-in profiles

Every app gets a `profiles` table automatically, holding each user's email, display name, and avatar. It is private per user by default, and it is how your app greets people by name after they sign in.

## Getting it right before you publish

Before you launch an app with real users, confirm the privacy behavior:

- Sign in as one test user, create some data.
- Sign in as a different test user, and check you cannot see the first user's data.

If anything is shared that should be private, or private that should be shared, tell the agent precisely who should see what, and it will change the table's class.

Two separate decisions, often confused: **who can open the app** ([public vs private](/docs/auth/public-vs-private)) and **who can see which data** (this page). Setting one does not change the other.

## Frequently asked

#### Which class should I use for user-generated content?

Private per user, almost always, and it is what the agent picks for personal data by default. Reach for shared or public only when everyone seeing the rows is the point.

#### Can I change a table's class after launch?

Yes. Tell the agent who should see what, and it changes the enforcement. The rows themselves stay put; only the visibility rules change.

#### As the owner, can I see everyone's data?

Yes, through the Database panel in the build workspace, which is your administrative view. The privacy classes govern what users of the app can see through the app.

#### What do signed-out visitors see?

Public pages, and rows in tables marked public. Personal and shared data always requires sign-in, which is what makes per-user privacy possible.
