> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parable.work/llms.txt
> Use this file to discover all available pages before exploring further.

# Provider Policies

> Choose which rows of each Provider table the people in each Workspace role read, everywhere your Workspace reads that table.

# Provider Policies

## Sources

Docs: [Protection Primer](https://docs.parable.work/protection/primer.md),
[Policies](https://docs.parable.work/ponder/parables/pieces/policies.md),
[Query Provider Pools with SQL](https://docs.parable.work/protocols/sql/query-provider-pools.md).

Web App: Workspace administrators open **Protection → Provider Policies**.

A Provider Policy decides which rows of one Provider table the people in each
Workspace role read. It applies to every read of that table in the Workspace:
Pages and Panes in every Parable, SQL in a Parable, SQL tools that connect
with a SQL token, and Ponder when it reads data for someone. A Parable's
Primary reads under it like anyone else. It does not narrow what Ponder
already read into a shared Problem ([Where it applies](#where-it-applies)).

## How a Provider Policy works

A Provider Policy is a list of rules and one fixed row, **Everyone else**.
Each rule names one or more Workspace roles and what they read:

| Reads | What the people the rule names read |
| - | - |
| **All rows** | Every row of the table. |
| **Rows where** | Only the rows that pass every condition of the rule. |
| **Hidden** | No rows. The table reads as empty, so a Page that joins it still loads. |
| **Source permissions** | Only the rows each person can open in the Provider. When the rule has conditions, each row must also pass them. See [Source permissions in a rule](#source-permissions-in-a-rule). |

* **Rules add up.** A person reads the rows of every rule that names one of
  their roles. Someone who holds both Viewer and Data Access, where the
  Viewer rule keeps their own rows and the Data Access rule keeps All rows,
  reads every row. Someone whose roles a Source permissions rule
  and a Rows where rule name reads the rows they can open in the Provider and
  the rows the Rows where rule keeps. Hidden adds no rows to another rule.
* **Everyone else** is what a person reads when no rule names any of their
  roles, including a member with no role at all. It starts at **All rows**,
  so adding a rule for one role changes nothing for anyone else.
* **One rule per role.** A role can appear in only one rule of a table.
* **A deleted role binds nobody.** Its rule keeps it, marked as removed.
* **A role with All data access reads every row.** A rule can name such a
  role, such as Workspace Administrator, but its holders read every row
  through [All data access](#all-data-access) whatever the rule says. Only a
  **View as** preview of one of them applies the rule. The page marks the
  role **All data access** when you pick it, says under the rule that its
  holders read every row, and shows it as **All data access** in **Who reads
  what**.
* **No Policy, no change.** A table with no Provider Policy is read in full by
  everyone whose role can read it.

For example, to let each person see only the calendar events they attend
while the people in the Data Access role see all of them, give the events
table two rows:

| Roles | Reads | Condition |
| - | - | - |
| Data Access | All rows | |
| Everyone else | Rows where | `attendee_email = request_principal()['email']` |

Workspace administrators need no rule. They read every row through
[All data access](#all-data-access), whatever the rules and Everyone else say.

## Where it applies

A Provider Policy applies wherever the table is read in the Workspace:

* every Page and Pane of every Parable, for every participant, the Primary
  included;
* SQL run in a Parable and SQL that names no Parable;
* SQL tools that connect with a SQL token, which read as the token's owner;
* Ponder's data tools, which read as the person who asked. What they return
  stays in the Problem's shared context, so everyone who can see the Problem
  can ask Ponder to repeat it, including someone a Provider Policy narrows.
  Keep tables a Provider Policy narrows out of Problems that people with
  different access share
  ([Everyone in a Problem shares its context](https://docs.parable.work/ponder/primer.md#everyone-in-a-problem-shares-its-context)).

A Parable's own Policies can narrow what a Provider Policy leaves a reader.
They never widen it.

People who hold [All data access](#all-data-access) read past Provider
Policies and source permissions everywhere they read a table themselves:
SQL, Pages and Panes, and the Refreshes they run. The Provider Pool tools for
agents are an exception ([All data access](#all-data-access)).

A scheduled Refresh runs as the Workspace, which no Provider Policy binds, so
it reads every row. See [Stored results and Refreshes](#stored-results-and-refreshes)
for who can open what it stores.

## Write conditions

A condition is a SQL expression over the table's own columns that is true or
false for each row. A rule's conditions must all hold, so they combine with
AND. Conditions use Parable's SQL dialect, Apache DataFusion's: comparisons,
`IN`, `LIKE` and `ILIKE`, regular-expression matches with `~`, `IS DISTINCT
FROM`, casts such as `id::VARCHAR`, and the usual text and number functions.

`request_principal()['email']` is the email of the person reading, so one
condition keeps each person's own rows:

```sql theme={null}
owner_email = request_principal()['email']
```

On a table with an email column, **Only the reader's rows** adds this
condition for that column.

A Source permissions rule can have conditions too. They narrow the rows a
person can open in the Provider, and they combine with AND.

Every condition is checked against the table's columns before a save. A save
is refused, with the condition and the reason, when a condition:

* names a column the table doesn't have;
* isn't true or false, such as `42`;
* calls a function whose answer changes on every call, such as `random()`;
* calls an AI function, such as `ponder()` or `embed()`;
* contains a subquery, an aggregate, an alias or a parameter, or more than
  one statement.

A table's Provider Policy holds at most 50 rules, 100 conditions and 60 KiB
of condition text.

If a Provider later drops a column a condition names, the page marks the
table **Needs attention** and shows the problem under the condition. Until an administrator fixes the condition, the people
whose rules use it can't read the table; everyone else keeps reading it.

Conditions that compare a column with a value, such as `region = 'EMEA'` or
the email condition above, let Parable skip files that can't match.
Wrapping the column in a function, such as `lower(region) = 'emea'`, makes
every read of the table read every file.

## Count rows before you save

**Count rows** counts how many of the table's rows each rule and Everyone
else would read, as the table is now, in one pass over the table. A rule
whose conditions depend on who is reading has no single count and shows
**Depends on who reads**. A Source permissions rule shows it too, because
each person can open different rows in the Provider. A rule that names only
roles with All data access shows every row of the table, because that is
what its holders read. Counting returns numbers only, never rows.

A count reads the table past every Provider Policy, so only someone who reads
every row of the table with their own SQL can count it. Workspace
administrators can, because they hold [All data access](#all-data-access).
Someone without it whose own Provider Policy or source permissions narrow the
table sees **Only someone who reads every row can count** instead. Each count is recorded in the
Workspace's audit events, with the table and not the conditions.

## Save a Provider Policy

1. Open **Protection → Provider Policies** and open a table.
2. Choose **Add rule**, pick the roles, and choose what they read. For
   **Rows where**, add the conditions. For **Source permissions**, you can
   add conditions. A role already in another rule can't be picked.
3. Set what **Everyone else** reads. People with
   [All data access](#all-data-access), such as Workspace administrators,
   read every row whatever Everyone else reads.
4. Choose **Save**. Parable checks every condition against the table's
   columns, then lists each role whose access changes, before and after. A
   role with All data access is never in the list, because no save changes
   what its holders read. The review also says when the people the change
   narrows lose stored results that read the table, and, when the change
   alters what you read from the table, what you read before and after. A
   save never changes what you read when you hold All data access, so the
   review does not say it then. Choose **Save Provider Policy** to save, or
   **Keep editing**.

**Discard** drops your unsaved changes to the table.

Each table saves on its own. If another administrator saved the same table
after you opened it, your save is refused; choose **Load their version** and
make your change on top of it. Every save is kept in the Policy's history and recorded
in the Workspace's audit events, with each role's access before and after but
not the conditions. Removing every rule and setting Everyone else back to All
rows clears a Policy and keeps its history.

A save takes effect at once, on Parables people already have open too: each
open Parable in the Workspace drops the Plot results it kept and reads its
Pages again under the saved Policy, so nobody keeps seeing rows it now hides.
Results that a browser stored for a Parable that is closed now, or on another
Workspace's address, never answer again either: the Provider Policies are part
of the key each browser stores results under, so the next time a person opens
a Parable, their Pages read under the saved Policy.

## Source permissions

Some Providers say who can open each record in the Provider, such as the
people and groups a Google Drive file is shared with. **Source permissions**
decide whether reads in your Workspace follow that sharing. Two switches on
**Protection → Provider Policies**, in the **Source permissions** card,
control them. Both start off. The same card holds
[manager reads](#manager-reads).

| Switch | Off | On |
| - | - | - |
| **Enforce source permissions** | Every table that no Provider Policy names reads all rows. | On each table whose Provider says who can open each row, and that no Provider Policy names, each person reads only the rows they can open in the Provider. Other tables still read all rows. |
| **Link-only sharing admits its audience** | A row shared only through a link, with anyone who has the link or with a domain, admits nobody beyond its other sharing. Parable can't tell who has a link. | Such a row admits the audience its link names. |

Some tables can hold sensitive data, but their Provider doesn't say who can
open each row, such as a Workday HRIS RaaS custom report. While **Enforce
source permissions** is on, only people with
[All data access](#all-data-access) read such a table, and the roles that a
rule gives **All rows** or **Rows where** on it. The Provider Plugin's page
names each such table.

A Provider Policy on a table decides what that table's readers read, whether
the switches are on or off, with one difference for **Everyone else**. While
**Enforce source permissions** is on, Everyone else's **All rows** on such a
table reads only the rows each person can open in the Provider, as on a
table that no Policy names. So adding a rule for one role still changes
nothing for anyone else. To let a role read every row of such a table, give
the role a rule that reads **All rows**. To let a person read every row of
every table, give them [All data access](#all-data-access).

Every read follows the switches: SQL, Plots, Pages and Ponder. A person
reads a table under source permissions through their own sharing in the
Provider. Parable matches them to their Provider accounts by the email they
sign in with. A person with no account in the Provider reads only rows that
are open to everyone. If Parable can't yet tell who can open a table's rows,
for example because the Provider's sharing has not been read since it was
connected, a read of that table is refused rather than showing every row.

Parable reads each Provider's sharing again after each sync of it. A change
of sharing in the Provider, such as removing a person from a group, reaches
reads in Parable after the Provider's next sync. Until then, people read by
the sharing Parable read last.

To change a switch:

1. Open **Protection → Provider Policies**.
2. Choose the switch in the **Source permissions** card. Parable says what
   the change does.
3. Choose **Turn on** or **Turn off** to save it, or **Cancel**.

A change takes effect at once, as a Policy save does: each open Parable in
the Workspace drops the Plot results it kept and reads its Pages again under
the new switches, and the results that browsers stored before the change never
answer again. While **Enforce source permissions** is on, browsers store no
Plot results for the Workspace, because sharing in a Provider can change at
each sync.

If another administrator changed the switches after you opened the page,
your change is refused and the card shows their switches. Every change is
kept in the switches' history and recorded in the Workspace's audit events,
with the person and each switch before and after. People who can see but not
change Provider Policies see the switches and can't change them. Agents
can't read or change them.

### Manager reads

**Manager reads** let a manager read the Parable Pulse activity of their
direct reports: the apps they use and when, window titles, and the text on
their screen. A connected Provider that lists reporting lines, such as
Workday or Google Workspace, names each person's manager. Manager reads are
off by default.

Manager reads change what a manager reads only where source permissions
decide the Pulse rows: while **Enforce source permissions** is on, or where
a rule reads **Source permissions** on a Pulse table. There, each person
reads only their own Pulse rows, and a manager also reads the rows of each
direct report while manager reads are on. A holder of
[All data access](#all-data-access) reads every Pulse row. A role that a rule
gives **All rows** on a Pulse table reads every row of that table. Elsewhere,
every member who can read the Provider Pool reads every Pulse row.

To turn manager reads on:

1. Tell your Workspace's people that their manager can read their Parable
   Pulse activity.
2. Open **Protection → Provider Policies**.
3. In the **Source permissions** card, choose **Managers read their direct
   reports' Pulse activity**.
4. Under **Reporting lines from**, choose the Provider that names each
   person's manager. The list shows only the connected Providers that list
   reporting lines.
5. Select **I told this Workspace's people that their manager can read their
   Parable Pulse activity.**
6. Choose **Turn on**.

The card then shows the Provider and when you confirmed that people were
told.

* Only direct reports count. A manager's manager reads nothing more.
* A row from a Mac with no bound person stays closed to every manager.
* While no connected Provider lists reporting lines, the switch is
  unavailable, and the card says what turns it on.
* **Change Provider** takes the reporting lines from another Provider. It
  needs the same statement that people were told.
* To turn manager reads off, choose the switch and choose **Turn off**. From
  the next read, a reporting line no longer lets a manager read the activity
  of their direct reports. Turning off needs no statement.
* If the Provider is no longer connected, or no longer lists reporting lines,
  Parable refuses the save and shows the Providers you can choose now. If
  another administrator changed the source permissions settings after you
  opened the page, Parable refuses the save and the card shows their
  settings.
* Each change is recorded in the Workspace's audit events, with the person,
  the Provider before and after, and the statement that people were told.
  Each read through a reporting line is logged with the manager, the table
  and the number of direct reports.
* People who can see but not change Provider Policies see the setting and
  can't change it. Agents can't change it.

**What each person sees.** While manager reads are on, the page where a
person connects Parable Pulse on their Mac shows this notice before they
choose **Connect this Mac**:

> **Your manager can read your activity**
>
> In \<Workspace>, your direct manager can read the activity this Mac sends:
> the apps you use and when, window titles, and the text on your screen.

A person who connected their Mac before manager reads turned on does not
see that page again. So tell your people before you turn manager reads on,
as step 1 says. The Pulse menubar does not show the notice yet
([PARABLE-7329](https://linear.app/parable-work/issue/PARABLE-7329)).

### Source permissions in a rule

A rule, or Everyone else, can read **Source permissions**. The people it
names then read only the rows they can open in the Provider, on that table
alone. Use it to make one role follow the Provider's sharing while another
role reads All rows, whether **Enforce source permissions** is on or off.

* **Only where the Provider says who can open each row.** The option is
  available only on such a table. On another table, the page shows it
  unavailable, and Parable refuses a save that uses it.
* **Conditions are optional.** With conditions, a row must pass them and be
  one the person can open. With none, the person reads every row they can
  open.
* **It adds up with the other rules.** All rows in any rule that names a
  person gives them every row. Rows where adds the rows it keeps. Hidden adds
  nothing.

### See what source permissions do

The **What source permissions do** card on **Protection → Provider
Policies** shows what source permissions do, before and after you turn them
on. It has four tabs. People who can see Provider Policies can open it.

| Tab | What it shows |
| - | - |
| **Freshness** | For each Provider that says who can open each row: when Parable last read its sharing, and the oldest sync that sharing came from. |
| **Unlinked accounts** | Accounts in a Provider that are shared on some rows but that no member of the Workspace reads through. |
| **Preview** | For one member, how many rows of each table they can open in the Provider. |
| **Explain** | For one member and one row, why they can or can't open it. |

**Freshness.** Syncs usually run once a day. A Provider's sharing is
**Current** when Parable read it in the last 30 hours, **Aging** after 30
hours and **Stale** after 36 hours. Parable's operators get an alert at the
same times. Aging or stale sharing still decides reads; nothing reads as
empty because it is old. **Not built** means Parable has not read the
Provider's sharing yet. Until it does, a read of its tables under source
permissions is refused.

**Unlinked accounts.** Parable matches each member to their accounts in a
Provider by the email they sign in with. An account that no member matches
gives nobody its rows, for example the account of someone who signs in with
another email. The tab lists such accounts with the most sharing first.

To give such an account to the member it belongs to, choose **Link** on its
row, enter the email the member signs in with, and choose **Link**. The
member then reads what the account can open in the Provider, as if the
account had their sign-in email. People who can change Provider Policies can
link accounts.

* The link applies from the next time Parable reads the Workspace's
  sharing, which follows the Workspace's next sync. Until then, the link
  shows **Next access run**.
* An account has one link at most. To give it to another member, remove the
  link first.
* A link gives nothing while the member is not an active member of the
  Workspace (the link shows **Not active**), or while the Provider says the
  account is suspended.
* **Linked accounts** lists the links under the accounts. **Remove** takes
  the account's rows away from the member at the next read of the
  Workspace's sharing.
* Each link and each removal is recorded in the Workspace's audit events,
  with the person who made it, the account and the member. An agent can't
  link or remove an account.

**Preview.** Enter the email a member signs in with and choose **Preview**.
For each table whose Provider says who can open each row, Parable counts the
table's rows and the rows the member can open, as their reads would with
**Enforce source permissions** on and the link-only setting as it is now.
The preview shows numbers, never rows. A table that a Provider Policy names
is marked, because the Policy's rules decide what people read there. A
member with [All data access](#all-data-access) reads every row with SQL
that names no Parable; the preview shows what they read in a Parable.

**Explain.** Enter the member's email, choose a table, and enter the row's
value in the column the field names, such as a file's `id`. Parable says
whether the member can open the row and why. For example: "[ben@acme.com](mailto:ben@acme.com)
reads this row because it grants group:finance and they belong to it
through user:ben". For each way the row is shared, it shows the sharing and
how the member has it: their own account, a group they belong to, their
domain, or every user of the Provider.

A preview or an explanation reads the table past every Provider Policy. So
only someone who reads every row of a table with their own SQL can see its
counts or explain its rows, as for **Count rows**. Workspace administrators
can, because they hold [All data access](#all-data-access). Each preview and
each explanation is recorded in the Workspace's audit events, with the
member it is about and, for an explanation, the table. The row is not
recorded.

## Stored results and Refreshes

A Pipeline or a Report stores its results once, for everyone who opens them.
A stored result computed from every row of a table can't be cut down to one
person's rows, so:

* someone a Provider Policy or source permissions narrow or hide a table for
  can't open a stored result that read that table, and a Report doesn't show
  them that result's row count;
* their Refresh of such a result is refused, because it would store only
  their rows for everyone who opens it. Someone the Policies and source
  permissions don't narrow can refresh it, and so can the result's schedule.
  A Refresh by someone with [All data access](#all-data-access) reads every
  row, as a scheduled Refresh does, so it opens only for people nothing
  narrows on those tables.

A stored result built on another stored result answers to the tables that
result read as well. Someone a Provider Policy narrows on one of them can't
open it or refresh it.

A Plot that reads the table live, rather than from a stored Refresh, is
filtered for each reader.

## Related tables

* **Quarantine and quality tables** follow their table. The
  `providers_quarantine` and `providers_quality` tables of a Provider table
  read as empty for anyone that table's Provider Policy or source permissions
  narrow or hide it for. A quarantine table whose table the catalog no longer serves reads as
  empty for everyone.
* **Child tables**, such as `issues__labels`, are tables of their own. A child
  table needs its own Provider Policy; its parent's doesn't apply to it.

## Tables that are gone

A Provider Policy belongs to one table. When the catalog no longer serves
that table, the Policy applies to nothing, and the page lists it under
**Policies on tables that are gone**, where **Clear** removes it.

A table that arrives through a new tap, or from a re-created custom tap, is a
new table to Parable and starts with no Provider Policy. Until you give it
one, everyone whose role can read it reads every row.

## Catalog statistics

Someone a Provider Policy or source permissions narrow or hide a table for
doesn't see its statistics, because they describe rows the person can't
read: its row count and validation rates in the catalog's table stats, in the
Plot editor and in a SQL tool's table metadata, its row count on
**Protection → Provider Policies**, and its rows in the
[quality tables](https://docs.parable.work/protocols/sql/data-catalog/provider-quality.md), the
`providers_quality.summary` tables included. While **Enforce source
permissions** is on, that covers each table whose Provider says who can open
each row, unless a rule gives the person's role All rows on it. People with
[All data access](#all-data-access) see every statistic.

## All data access

All data access is a Workspace permission, `tenant.data.unrestricted`. A
person whose Workspace roles hold it reads every row of every Provider table,
past Provider Policies and source permissions, wherever they read the table
themselves:

* SQL that names no Parable, run from Parable;
* SQL tools that connect with a SQL token, which read with the token owner's
  roles;
* Ponder's SQL, which reads as the person who asked;
* in a Parable: its Pages and Panes, SQL run in it, and the Lab Page's SQL;
* the Refreshes and Previews they run, and the stored results they open.

So a Plot on a Page shows a holder the same rows as the same SQL in that
Parable. A Parable's own Policies, its filter Policies and each Pane's
Policies, still apply to holders as to everyone else.

The Provider Pool tools for agents are an exception. A statement that
`search_available_data`, `plan_sql` or `query_provider_pool` runs reads under
the Provider Policies and source permissions for every person, holders of All
data access included. So an agent that acts for a Workspace Administrator
reads only what the Policies give the administrator's roles
([MCP](https://docs.parable.work/protocols/mcp.md#query-provider-data)).

Under **View as**, a holder reads what the person they preview reads. All
data access does not apply to the preview.

A Refresh or Preview that a holder runs reads every row, as a scheduled
Refresh does. Its stored result opens only for people that no Provider
Policy and no source permissions narrow on the tables it read. A Refresh by
anyone else is refused when a Provider Policy narrows them on a table it
reads ([Stored results and Refreshes](#stored-results-and-refreshes)).

The Workspace Administrator role holds All data access. Another role holds it
only when it is given the permission by name. The Data Access role does not
hold it. Staff roles never give it: Parable staff read your data only as
described [below](#who-can-change-provider-policies).

Each such read is recorded in the Workspace's audit events, with the person,
the Workspace and where they read:

| Where | The event also names |
| - | - |
| SQL that names no Parable, from Parable or a SQL tool | A hash of the SQL |
| SQL in a Parable | The Parable and a hash of the SQL |
| A Plot read on a Page or a Pane | The Parable, the Plot and a hash of its SQL |
| A Refresh or Preview they run | The Parable, the run and whether it is a Preview |

The event never holds the SQL itself. Parable also logs each Provider table
the read scans, with the person.

## Who can change Provider Policies

| Who | What they can do |
| - | - |
| Workspace administrators | See and change Provider Policies, the source permissions switches and [manager reads](#manager-reads), link source accounts to members, and count the rows of any table, because they hold [All data access](#all-data-access). |
| Parable staff with administrative access to the Workspace | See and change them when their support access includes Provider Policies, to support you. |
| Other members | Nothing. The page is not available to them. |
| Ponder and other agents | Nothing. Agents can't read or change Provider Policies, the source permissions switches, manager reads or account links, and can't choose or change anyone's roles. |

Roles decide which rows each person reads, so changing someone's roles is a
protection change too. Only a person can make it, and only a person chooses
the roles an invitation gives or sets the Workspace's default role. An
invitation an agent sends gives the default role. So no agent can give anyone
All data access.

When Parable staff whose support access lets them query your Workspace's
data run SQL that names no Parable, from Parable or a SQL tool, they read
every row of every Provider table, past Provider Policies. Parable logs each
such read with the person and the tables it read. In a Parable, and with any
other access, Parable staff read by the roles they hold in your Workspace, or
what Everyone else reads when they hold none.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.