Skip to content

Connect Notion to ChatGPT without oversharing

To connect Notion to ChatGPT without exposing private pages, the connection has to carry each person's own access rather than a shared workspace credential.

Nachi Raman 5 min read
Two connection paths to a workspace, one shared and one per person, with the visible page set differing between them

What it takes to connect Notion to ChatGPT without exposing private pages

Assistants reach a wiki over the Model Context Protocol, and the request usually arrives as a single sentence: give the company's assistant access to the wiki, but not to the pages people keep to themselves.

The instinct is to solve it with a rule. Connect the workspace once, then write a policy that hides the private pages. That approach fails at the first step, because the thing doing the hiding has already been handed a credential that can see everything.

The control that decides the outcome is earlier and simpler: whose access the connection carries. Everything else is narrowing on top of a decision that has already been made.

A shared token has one answer for everybody

A workspace-level token is a single identity. Whatever it can open, it can open for every call that goes through it. There is no caller distinction inside it, because it does not carry one.

So if that token belongs to an account with broad workspace access, which is usually how these are created, then every person who can reach the connection has that account's reach. An engineer asking the assistant to summarize a page gets an answer built from pages their own account could not open. Nothing was misconfigured. The credential is doing exactly what a shared credential does.

Writing restrictions on top of that helps with which tools are callable. It does not help with which pages are visible to a tool that is callable, because page visibility was settled by the credential.

A per-person connection inherits the permissions you already set

The alternative is for each person to connect their own Notion account. The connection then carries their access, and the underlying system's own page permissions apply without being reimplemented anywhere.

This is the part worth being clear about, because it is a limit as much as a feature. Elaichi does not model your wiki's page tree, and it does not decide which pages are private. It carries an identity to the system, and that system applies the permissions its administrators already configured. If a page is shared too widely inside the workspace, a per-person connection will faithfully expose it too widely, and the fix belongs in the workspace rather than here.

What that arrangement gives you is that the assistant stops being a way around the permissions you already have. A person's agent reaches what the person reaches.

Connector credentials are not held by the control plane in either case. A separate credential service owns per-account secrets, encrypted at rest with AES-256-GCM, and owns refresh. A refresh that fails marks the connection needs_reauth rather than failing silently, which matters because a silent credential failure is indistinguishable from an agent choosing not to answer.

Sharing is an explicit grant, not a consequence of rank

Once several people have their own connections, the next question is who can see them. The answer is narrower than most access models.

There is one sharing primitive: a grant of view, use or edit on a resource to a user, a team, or the whole organization. A member sees only what they own or what was explicitly shared with them. No organization-level permission silently widens a listing, and org owners and admins are inside that rule rather than exempt from it.

That has a practical consequence for rollouts. An admin who expects to open a console and survey everybody's connections will not find that view, because it would be exactly the kind of implicit widening the model refuses. Visibility is something granted, and the grant is recorded.

Narrowing which tools exist at all

Under the credential question sits the ordinary governance layer, and it is still worth using. It sits behind sign-in rather than inside it, which is a distinction worth keeping separate.

Restrictions decide which connectors and which individual tools a target may reach, with targets of role or user only. There is no organization target: the org default is the absence of any rule, which means allow-all, so policy is written against roles rather than set globally.

A read-only posture is a reasonable default for a wiki. Write access is the capability people ask for later, and granting it after a month of observed behavior is a better-informed decision than granting it on day one.

Two details decide whether a rule does what you meant. Blocks match on the tool name or on the pinned operation, while allows match on the pinned operation only, because an advertised tool name can be edited by whoever maintains the connector's documentation and is therefore controlled by the governed party. And the allowlist stage engages on the presence of an allow rule rather than its contents, so an allow rule naming nothing denies everything.

Enforcement is checked at four points against the same resolver rather than once at the entrance: browse, connect, advertise and execute, plus a final check on the fully-substituted outbound URL. A tool withheld by a restriction is never advertised, so the model does not see it and cannot propose it.

Pin the parts that should never vary

Where the operation is fine and only its target needs fixing, frozen parameters are a better fit than a block.

A frozen key is stripped from the advertised schema, so the model never sees it. A frozen value is merged over caller arguments at execution, so sending the key anyway cannot un-freeze it. Precedence runs entry defaults, then caller or model arguments, then frozen parameters.

Pinning a database or a parent page this way keeps the capability the team asked for and removes the way it goes wrong, which is usually a better trade than removing the capability.

What you can prove afterward

The question that follows an unexpected edit is specific: which workspace. Not which user was signed in, and not which tool was called in the abstract.

One entry is written per tool-call attempt, succeeded or failed, and both name the account. The connection recorded is the one actually reached, taken from the execution rather than the intent, which is what makes the record answer the question instead of restating the request. Alongside it: the operation and tool, the classification, whether it was approved, the outcome, and an error code.

Argument names and counts are logged. Argument values never are. That boundary is deliberate and cuts both ways. It is why the trail can be exposed to a reviewer without exposing page contents, and it is why the trail will not tell you what an agent wrote.

The audit log is append-only, newest first, and filterable by free text, category, actor, action kind and time. It is eventually consistent, so a row may take a moment to appear. A departed member renders as "Former member" rather than vanishing from the history.

A free read-only Auditor seat exists precisely so that the person reviewing this is not sharing somebody's admin login to do it.

When this is more machinery than you need

If one small team uses one workspace, everybody on the team is allowed to read all of it, and nobody outside the team will connect, a shared token is not a governance failure. It is an accurate description of the situation, and adding per-person connections buys nothing but setup.

The threshold is the first time two groups need different answers to the question of whether a person may open a given page. At that point a shared credential cannot represent the policy, and no rule written above it can.

The same decision for an engineering team is worked through in a Cursor rollout. See what else connects or how access is described for reviewers.

FAQ

Frequently asked questions

Does a shared workspace token leak private pages?

It exposes whatever that token can see to everybody who can call through it. If the token belongs to an account with broad workspace access, then every caller effectively has that access, regardless of what their own account would be allowed to open. The fix is a per-person connection rather than a rule written on top of a shared one.

Can an org admin see connections other people created?

Not by default. A member sees only what they own or what was explicitly shared with them, and no organization-level permission silently widens a listing. Org owners and admins are included in that rule, so visibility comes from an explicit grant rather than from rank.

What happens to personal connections when somebody leaves?

Removal runs a preflight. A personal connection referenced by a toolbox entry has to be transferred to the org, a team or another member, or deleted, or the removal is refused. Unreferenced personal connections are cleaned up, and a private connection is not transferable at all.

Which workspace did the agent actually write to?

The audit trail records the connection actually reached, taken from the execution rather than from the intent, so a person with two workspaces connected gets a definite answer rather than an inference. One entry is written per tool-call attempt, whether it succeeded or failed.

Put agents to work on your own systems

14 days on Gold, no credit card. Start with one app and one team.

Works with
Claude ChatGPT Cursor and any other MCP client, or the Elaichi Agent.
When the trial ends
Nothing is deleted. Connections, roles and the audit log stay where they are, so subscribing picks up exactly where you left off.