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

# Workshop 9 (optional): Access Control

> Decide who may see which records in the knowledge graph, then test and roll out the policy safely.

This workshop decides **who may see which records** in the knowledge graph. By default every signed-in user can read everything that was ingested. That is right for most firms, most of the time. It is wrong when the graph holds contracts under confidentiality terms, HR data, work behind an ethical wall, or a client that insists on restricted access. [Access control](/implementation/key-concepts#access-control) filters every graph query to the records the person is entitled to, so the same question returns different answers for different people.

Run this workshop only when you need it. It matters for accuracy because a policy with a gap does not raise an error. It quietly hides records, and a golden question that passed in validation starts failing for real users.

<Warning>
  Run this workshop **after the [ontology](/implementation/key-concepts#ontology) is agreed** (Workshop 3) and after a pilot ingestion has put real records in the graph. The policy refers to entity type names and relationship names exactly as they are stored. If the ontology renames a relationship later, the policy silently stops matching it.
</Warning>

## At a glance

| | |
| - | - |
| **Purpose** | Decide which entity types are private, how people get access to them, and how you will test and roll out the policy |
| **When** | Phase 4 Validate (week 6–7), after the pilot ingestion. Optional. |
| **Duration** | 90 minutes, plus a 60-minute test session with the pilot users |
| **Attendees** | Experio: FFE (leads), Experio SMEs as needed. Client: PM, super user, the data owner for each restricted area (for example Legal, HR), IT admin, and the sponsor for sign-off |
| **Inputs** | Agreed ontology; data mappings loaded (people and their assignments must be in the graph); the client's written confidentiality rules; a list of pilot users with their roles |
| **Outputs** | Completed [access-control policy worksheet](/implementation/templates); a test plan with at least three personas; a rollout date for shadow and for enforce |
| **Admin pages** | Staff admin > Graph Authorization (policy rows); **Administer > Access Control** (Scoping policy, Preview as user, Diagnostics); **Administer > System Settings** (enforcement mode) |

## Before the workshop

**FFE and Experio SMEs:**

* Read [Graph Access Control](/admin-guide/graph-access-control) end to end. The setup order and the traps on that page are what you will follow after the workshop.
* List **every entity type** in the graph, not only the ones you expect to restrict. Include `Document` and any other labels the pipeline writes. A label with no baseline row is treated as private, so you need the full list.
* For each candidate private type, check that a relationship connects it to a person, directly or through something the person already reaches. Open **Model & Define > Ontology** and write the relationship names down exactly.
* Prepare 3–5 test users in **Administer > User Profile Management**, one per level you expect to test (see the persona table below). Each test user must exist as a person in the graph with real work relationships.

**Client homework:**

* The data owner brings the rule in plain words: "Only Legal and the people on the engagement may see a contract."
* The super user brings the list of pilot users, their roles, and who they report to.
* IT confirms whether any rule comes from a contract or regulation. Those rules need the sponsor's sign-off.

## Agenda

| Time | Topic |
| - | - |
| 0:00–0:10 | Why access control, and what it costs (records nobody can reach) |
| 0:10–0:30 | Classify every entity type: private or public read |
| 0:30–0:55 | How a person reaches a private record: grant rules, propagation, containment |
| 0:55–1:05 | Managers: should they inherit what their reports can see? |
| 1:05–1:20 | Test personas and expected results |
| 1:20–1:30 | Rollout plan (disabled, shadow, enforce), owners, sign-off |

## Running the workshop

### 1. Classify every entity type

Walk the entity type list one row at a time. Ask:

* "If any employee could see every record of this type, would anyone object?" If no, mark it **public read**.
* "Who is allowed to see it, in your words?" Write the answer down verbatim. It becomes the grant rule.
* "Is there anything attached to it that is just as sensitive?" Obligations inside a contract, for example. Those types must be private too, or the detail leaks through them.

Keep the private list short. Every private type hides some records from everyone, because some records have no path to any person. The admin guide shows real numbers for this under [What making a label private actually costs](/admin-guide/graph-access-control#what-making-a-label-private-actually-costs).

### 2. Decide how a person reaches a private record

Access in Experio starts from **work**. A **grant rule** names a relationship that attaches a person to the graph, such as `WORKS_ON_PROJECT`. From what the person holds, **propagation rules** extend access one step at a time: "if you hold this, you may also read that, over this relationship". **Roll-up axes** describe containment, where holding a parent gives you what is filed under it.

Ask the room:

* "How does a person earn access? By being staffed on the work? By being in a department?"
* "If you can see the project, should you see the contract that governs it? All contracts with that client, or only this one?"
* "If you can see a contract, should you also see its amendments and obligations?"
* "Is there anyone who needs access but is never staffed on the work (Legal, Finance, leadership)? How do we connect them?"

<Warning>
  Access through department or practice membership (a "membership" rule) is **retired**. Do not design the policy around "everyone in Legal sees all contracts" unless you also agree how the graph will hold a relationship from each Legal person to the work. A person with no work relationships sees **no** private records, and no rule changes that. See [Create the grant rules](/admin-guide/graph-access-control#setting-up-a-new-deployment).
</Warning>

When someone needs access without being staffed, you have two honest options. Either load a relationship that records their responsibility (from a small structured file the data owner maintains), or rely on the management roll-up. Decide which in the room. The first option changes the ontology and a data mapping, so it goes back to the super user as a change request.

### 3. Decide on the management roll-up

Ask: "Should a manager see what their direct and indirect reports can see?" If yes, the policy uses the reporting relationship as a management axis. This is optional. It widens access for everyone with reports, so the sponsor should agree.

### 4. Agree the test personas

Pick at least three real pilot users at different levels. One account cannot tell a working policy from a broken one. For each persona, write down which golden questions they will ask and what you expect them to see.

### 5. Agree the rollout

Access control has three modes, set in **Administer > System Settings** (`GRAPH_AUTHORIZATION_MODE`):

| Mode | What happens | Use it for |
| - | - | - |
| **disabled** | No filtering. The default. | Until the policy rows are entered |
| **shadow** | The decision is computed and logged, but the answer still comes from the unfiltered query | One to two weeks with pilot users, while you compare results |
| **enforce** | Every graph read is filtered to the person's entitlement | Go-live, after sign-off |

Agree a date for shadow, a date for enforce, and who signs off the switch.

## Worked example: Northbridge Consulting

Helen Park (Contracts Counsel) states the rule: "Contracts are confidential. Legal and the people on the engagement may see them. Everyone can see clients, projects and people." Priya Shah (COO) confirms that managers should see what their teams see.

**Classification**

| Entity type | Default access | Reason |
| - | - | - |
| Client, Project, Employee, Practice, Skill, Proposal | public read | Needed firm-wide for proposals and staffing |
| **Contract** | private | Confidentiality terms in MSAs and SOWs |
| **Obligation** | private | Carries the contract's terms; would leak them otherwise |
| Document (and every other label the graph holds) | decide per label | Contract files are Document nodes too. Test in shadow that a restricted user cannot read contract text through document search before you decide |

**How people reach contracts** (read each row as: hold the left, and you may also read the right)

| If you hold | over | direction | you may also read |
| - | - | - | - |
| `Project` | `GOVERNS` | inbound | `Contract` (the SOWs for your project) |
| `Contract` | `AMENDS` | inbound | `Contract` (its amendments) |
| `Contract` | `IMPOSES` | outbound | `Obligation` |
| `Client` | `WITH_CLIENT` | inbound | `Contract` (Legal only, see below) |

* **Grant rule (team):** `WORKS_ON_PROJECT`. A consultant holds the projects they are staffed on.
* **Legal:** Helen's team is never staffed on projects. The room agrees to add one relationship to the ontology, Employee **COUNSEL\_FOR** → Client, loaded from a small `legal_coverage.csv` that Helen maintains. A second team grant rule on `COUNSEL_FOR` gives Legal the clients they cover, and the last row above gives them those clients' contracts.
* **Management roll-up:** `REPORTS_TO` (stored report → manager), entered as a roll-up axis with direction `up` and attached to no baseline.

**Test personas**

| Persona | Level | Test questions | Expected result |
| - | - | - | - |
| Helen Park | Legal, covers Lakeshore Health | Q8, Q9 | Sees the Lakeshore MSA and its obligations; Q9 lists only covered clients' contracts |
| Consultant on the Lakeshore cloud migration | Staff | Q7, Q8 | Sees the SOW for their project; Q8 returns nothing if the MSA does not govern their project |
| Alex Romero | Manager in Technology | Q7 | Sees SOWs for every project his reports are on |
| New joiner, no assignments | Staff | Q7, Q1 | No contracts at all; Q1 still answers fully (projects are public) |

## Entering it in Experio

Policy rows are **database rows entered in the staff admin**, not configuration that ships with a release. Nothing is seeded. Only a staff administrator can edit them. Follow the order in [Setting up a new deployment](/admin-guide/graph-access-control#setting-up-a-new-deployment) exactly:

<Steps>
  <Step title="Roll-up axes">
    In **Staff admin > Graph Authorization > Roll-up axes**, add one row per containment relationship, then the management axis if you agreed one. Direction is mechanical: `down` follows the arrow as stored, `up` walks it in reverse. Northbridge adds only `REPORTS_TO`, direction `up`.
  </Step>

  <Step title="Baselines">
    In **Baselines (OWD)**, add a row for **every** label in the graph, `private` or `public_read`. A missing row means private.
  </Step>

  <Step title="Attach containment axes">
    Open each baseline that should inherit down a hierarchy and set its roll-up axis. Leave the management axis unattached.
  </Step>

  <Step title="Grant rules and propagation rules">
    Add team grant rules for the work relationships, then the propagation rules from your worksheet. Leave grantee principal, grantee selector, source principal and record filter empty.
  </Step>

  <Step title="Check the policy">
    In **Administer > Access Control**, read the **Scoping policy** tab. Then use **Preview as user** for each test persona, and open **Diagnostics** for graph reachability and unreachable records.
  </Step>

  <Step title="Shadow, then enforce">
    In **Administer > System Settings**, set `GRAPH_AUTHORIZATION_MODE` to `shadow`. Run the persona tests with pilot users. After sign-off, switch to `enforce`. The screen shows a confirmation before enforce takes effect.
  </Step>
</Steps>

### What users will notice

* **Fewer citations.** Citations are filtered by the user's access. On a broad question ("list all our contracts"), a restricted user can get a correctly scoped answer with **no** citation chips, because the sample the citations are drawn from is capped before filtering. A narrower question, naming a client or project, brings citations back. Tell pilot users this before enforce. See [Citations, and why a scoped answer can have none](/admin-guide/graph-access-control#citations-and-why-a-scoped-answer-can-have-none).
* **Different answers to the same question.** This is intended. Record the persona on every golden-question score after enforce.
* **Records nobody can reach.** Diagnostics counts them. Fix them upstream with a data mapping or an [enrichment rule](/implementation/key-concepts#enrichment-rule) that adds the missing relationship, not by widening the policy.

## Common pitfalls

| Pitfall | Symptom | Fix |
| - | - | - |
| A label missing from Baselines | That type disappears for everyone | List every label, including `Document` |
| Containment axis not attached to a baseline | No inheritance; the axis is treated as the management axis | Check every containment axis is named on a baseline |
| Management axis set to `down` | Managers silently stop inheriting | Set it to `up` |
| No grant rule | Everyone sees nothing | Add the team rule on the work relationship |
| Relationship name typed differently from the graph | Rule matches nothing; counts read zero | Copy names from **Model & Define > Ontology** |
| Tested with one account | Cannot tell "works" from "broken" | Test three or more personas at different levels |
| Going straight to enforce | Pilot users lose answers on day one | Run shadow first |
| Ontology renamed after the policy was entered | Policy stops matching | Re-check the policy after every ontology change |

## Exit criteria

* [ ] Every entity type in the graph is classified private or public read, and the data owner has signed the list
* [ ] Every private type has at least one written path from a person (grant rule plus propagation)
* [ ] People who need access without being staffed have an agreed relationship, with an owner for its data
* [ ] Management roll-up decision recorded
* [ ] At least three test personas with expected results per golden question
* [ ] Policy rows entered in the staff admin in the documented order
* [ ] Preview as user matches the expected results for every persona; Diagnostics reviewed
* [ ] Shadow mode run with pilot users; sponsor sign-off recorded in the decision log
* [ ] Enforce date agreed, and pilot users told about fewer citations on broad questions

## Next

Continue to [Workshop 10: Assistants & Agent Flows](/implementation/ws-assistants-and-flows). Re-score the golden questions per persona in [Accuracy validation](/implementation/accuracy-validation) once the policy is in shadow mode.
