---
module: platform.guide-access
title: Guide Access Control — Audience Tiers & Role Visibility
tab: Overview
order: 15
audience: bcos
---

> **BCOS admin only.** This is the authoritative answer to "who can see what in the Guide".
> Verified against the live API on **2026-07-14** by querying `/guide/api/v1/guide/nav` as each
> role. Do not re-derive this from source; if you change a tier, update this page.

## Where the Guide actually runs

The Guide is deployed to **bcos.dev only** (`guide.bcos.dev`, API `api.bcos.dev/guide/...`).

- It is **not** in production. `api.bcos.cloud/guide/*` hits the NGINX catch-all and returns
  `HTTP 200` + the "HiveIQ API Gateway" page for **any** path, including paths that do not exist.
  A `200` from there is not a health check; do not read it as "the Guide is up in prod".
- **`guide.bcos.cloud` does not exist** (no DNS record on 1.1.1.1 or 8.8.8.8).

## The four audience tiers

Every doc carries an `audience:` field in its frontmatter. That single field is the whole access
model. `MarkdownGuideService.visible()` resolves it against the caller's role:

| tier | who sees it | gate |
|---|---|---|
| `customer` | everyone signed in | (default) |
| `internal` | MSP_ADMIN + BCOS_ADMIN | `isInternal()` |
| `dev` | **BCOS_ADMIN only** | `isBcos()` |
| `bcos` | **BCOS_ADMIN only** | `isBcos()` |

**Anonymous callers get nothing:** `/nav` returns `401` with no token.

⚠️ **`dev` and `bcos` are both BCOS-only.** `dev` is developer/architecture content and must never
be MSP-visible (issue #18). Only `internal` is shared with MSP admins. If a doc must stay in-house,
tag it `dev` or `bcos`; never `internal` or `customer`.

## Role visibility matrix

| audience | tab | CUSTOMER | MSP_ADMIN | BCOS_ADMIN |
|---|---|---|---|---|
| `customer` | Customer | 66 | 66 | 66 |
| `customer` | The Data | 1 | 1 | 1 |
| `internal` | Internal | – | 66 | 66 |
| `internal` | Technical | – | 1 | 1 |
| `internal` | Testing | – | 66 | 66 |
| `dev` | Internal | – | – | 15 |
| `dev` | Overview | – | – | 35 |
| `bcos` | **Architect** | – | – | **81** |
| `bcos` | **Claude** | – | – | **81** |
| `bcos` | Overview | – | – | **9** |
| | **modules visible** | **66** | **66** | **125** |
| | **apps visible** | **13** | **13** | **19** |

### What each role gets

- **CUSTOMER** — the `Customer` tab only. 66 modules, no internal apps.
- **MSP_ADMIN** — Customer, `internal`-tier `Internal`, and `Testing`. **No** Architect, Claude, or
  any `dev` architecture (`technical.*` / `platform.*` Overviews, agent-module internals). Same 66
  modules as CUSTOMER, with the extra operational + test tabs on them.
- **BCOS_ADMIN** — everything: `dev` (Architect, Claude, dev Overview/Internal) and the `bcos` tier
  (`processes.*`, `devops.dev`, `devops.prod`, `milestone.2026-07`, this page).

## Architect + Claude are BCOS-only (fixed 2026-07-14)

Until issue **#16**, all 162 `Architect` and `Claude` docs were tagged `audience: dev`, so **every
MSP_ADMIN could read them in full** — internal architecture, source paths, DB tables, service
ports, NGINX routes. They are now `audience: bcos`.

The fix was a content retag, **not** a code change. Remapping the `dev` tier itself would also have
stripped the 15 `Internal`, 35 `Overview` and 66 `Testing` docs from MSP, which is not intended.

## For a Claude session

Read the Guide as **BCOS_ADMIN** (`bcos_a@bcos.dev`) or the `Architect`/`Claude` tabs will be
absent from the response — and their absence looks identical to "this module has no Claude tab".
An MSP_ADMIN token silently returns a truncated tab list, with **no error**.

```bash
TOKEN=$(curl -s https://api.bcos.dev/auth/api/login -H 'Content-Type: application/json' \
  -d '{"email":"bcos_a@bcos.dev","password":"<pw>"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')
curl -s https://api.bcos.dev/guide/api/v1/guide/nav -H "Authorization: Bearer $TOKEN"
curl -s https://api.bcos.dev/guide/api/v1/guide/modules/technical.incident -H "Authorization: Bearer $TOKEN"
```

Module keys: `technical.<service>` · `<app>.<module>` · `agent.<module>` · `platform.*` ·
`processes.*` and `devops.*` (BCOS-only). There is **no** `technical.guide` module; the Guide does
not document itself apart from this page.

## Environment cap

`guide.served-audiences` (env `GUIDE_SERVED_AUDIENCES`, `application.properties`) caps which tiers
an instance serves at all, *before* the role check. It currently defaults to **all four tiers**
(`customer,internal,dev,bcos`). If the Guide is ever deployed to production, set this explicitly —
the default serves everything.
