# You do not have permission

A refusal is one of three things. The audience boundary refuses a path that is not part of the customer surface. The workspace boundary does not refuse at all — data in another workspace is invisible, so you see nothing rather than a denial. Your role refuses an action inside your own workspace. The symptom differs in each case, and so does the fix.

- **Status:** Available
- **Audience:** both
- **In the app:** #/account, #/autonomy
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/troubleshooting/permission-denied/

## What the symptom looks like

Either a screen or an action reports that it is not permitted, or — more confusingly — a screen loads and is simply empty when you know the data exists. Those two symptoms come from different mechanisms and it is worth being precise about which one you have, because chasing an empty screen as though it were a permission problem wastes the afternoon.

**A refusal** — Something said no. The request reached a boundary that recognised it and declined.
**An emptiness** — Nothing said no. The query ran and matched no rows, because the rows it would have matched belong to another workspace and are not visible to this one.

## The three causes

| Boundary | What it protects | What you see | What changes it |
|---|---|---|---|
| Audience | The customer surface, which is an allowlist rather than a blocklist | A refusal on a screen or an action that works for the operator | The capability being added to the customer surface deliberately, not a setting |
| Workspace | Isolation between workspaces, enforced three separate times | An empty screen or a record that cannot be found | Being in the workspace that owns the record — nothing else |
| Role | What a member of this workspace may do | A refusal naming the action, inside a workspace you can otherwise use | A workspace administrator granting the permission |

> **Note** The audience boundary fails closed by design: anything it does not recognise becomes a blocked request rather than being passed through hopefully. That is why a brand-new capability can work perfectly for the operator and refuse for a customer — the feature is fine and the surface has not been extended to it yet.

## The refusals that are correct

A few refusals are the product working as intended rather than a gap to be closed. Verifying customer payments and the operator's own pricing are operator work — running the platform, not using Connect — and a customer session is refused there rather than shown a reduced version. Enquiries addressed to the operator through the public site sit outside every workspace for the same reason.

The Assistant has narrower rights than the person using it, and that is also deliberate. It cannot set pricing and it cannot clear a do-not-contact entry. Both are decisions a person should make knowingly, and an assistant that could be talked into either would be a liability rather than a help.

## What Connect completed

- The request was authenticated and resolved to a workspace before the refusal — a refusal is a decision made with full knowledge of who was asking, not a failure to identify you.
- The refusal was recorded with its reason, because a refusal is a decision and the decision log keeps those too.
- Everything you are permitted to see continued to work normally during and after it.

## What Connect did not complete

- The action itself did not run, partially or otherwise. Nothing was written, sent, changed or deleted by a refused request.
- No allowance was spent on it, and no model call was made for it.
- Nothing was returned from another workspace. An empty result is emptiness, never a partial view of somebody else's data.
- No fallback was attempted — a refused path is not retried through another route to see whether that one permits it.

## What you can do, and what an administrator can do

1. Decide first whether you saw a refusal or an emptiness.
   - Result: A refusal is about permission; an emptiness is almost always the wrong workspace, which is a different fix entirely.
2. If it is an emptiness, confirm which workspace your session resolved to.
   - Result: Two people can be looking at the same product and different data without either being wrong.
3. If it is a refusal on an action inside your own workspace, ask a workspace administrator.
   - Result: Role is the one of the three that a person inside the workspace can actually change.

An administrator can grant a permission to a member, change a member's role, or remove a membership. What an administrator cannot do is extend the customer surface — that boundary is part of the application, and a capability reaching it is a product change with its own audience check.

## When to escalate

Escalate when a capability works for the operator and refuses for a customer with no stated reason. That asymmetry is a real class of defect here and it is tracked deliberately: every capability one audience has and the other does not is either recorded as a known gap with a reason, or it is a fault. A report of the form 'this works on one account and not the other' is exactly the right shape.

Say which audience you were, which screen or action it was, and what you saw — a refusal or an emptiness. Those three facts identify the boundary involved without anybody needing a log.

## Questions

### Why do I get an empty screen rather than a clear denial?

Because isolation is enforced by filtering rather than by refusing. A record belonging to another workspace is not matched by your query at all, so there is nothing to deny — the honest description is invisible, not forbidden.

### It works for the operator. Is that a bug?

Sometimes, and it is worth reporting either way. Two capabilities are correctly operator-only because they are platform operation. Everything else is meant to reach both audiences over the same implementation, so an unexplained asymmetry is treated as a defect.

### Can the Assistant do things I cannot?

No — its rights are narrower than yours, not wider. It cannot set pricing and cannot clear a do-not-contact entry, which are the two places where an agreeable assistant would be most dangerous.

## Related

- [A screen returned 403](https://connectbyjbrh.com/docs/troubleshooting/403-on-a-screen/)
- [Authorisation](https://connectbyjbrh.com/docs/security/authorization/)
- [The customer facade](https://connectbyjbrh.com/docs/security/customer-facade/)
- [Data that should be here is not](https://connectbyjbrh.com/docs/troubleshooting/data-not-visible/)
- [Workspace administration](https://connectbyjbrh.com/docs/account/workspace-admin/)
- [A tenant facade that fails closed](https://connectbyjbrh.com/research/closed-by-default-facade/)

## What this page is based on

- docs-source/sources/GENERAL.md §1 — the customer allowlist, path rewriting and the parity rule
- docs-source/sources/GENERAL.md §2 — the three places isolation is enforced
- docs-source/sources/GENERAL.md §8 — the Assistant's narrower rights
- Connect capability registry (docs-source/facts.py)
