# Protected sections

> For the complete documentation index, see [llms.txt](https://docs.writedocs.io/llms.txt).

Tabs, products, versions, languages or dropdowns that only signed-in readers can open - a partner area, internal docs - on the WriteDocs platform.

Any tab, product, version, language or dropdown can be protected: give it `access`, the name of an access rule, and every page under it opens only for the readers that rule lets in - with a password, or for a list of email addresses. Use it for the parts of your docs that aren't for everyone: a partner program, internal runbooks, a customer-only API.

```json
{
  "navigation": {
    "tabs": [
      { "tab": "Guides", "pages": ["index", "guides/start"] },
      {
        "tab": "Partners",
        "access": "partners",
        "lock": true,
        "pages": ["partners/intro", "partners/payouts"]
      },
      { "tab": "Internal", "hidden": true, "access": "staff", "pages": ["internal/runbook"] }
    ]
  }
}
```

> **Warning**
>
> Only the WriteDocs platform protects these pages. `writedocs.json` names the rule; the rule itself - its password or its list of emails - is set up on the platform, never in your project. A build hosted anywhere else serves the pages to everyone, and `writedocs build` and `writedocs validate` say so every time.

**`access`** `string`

The name of an access rule: 1 to 40 lowercase letters, numbers and hyphens, like `partners` or `team-2`. Every page under the item - its sidebar, however deep, its own `page`, and the API pages an OpenAPI group in it generates - is protected by that rule. The name isn't a secret: anyone can read it in `writedocs.json`. Two items can use the same rule.

**`lock`** `boolean` default: `false`

Shows a padlock next to the item's name wherever it's listed - the tabs, a tab's menu, the switchers in the top bar and the sidebar, and the mobile menu - so readers know they'll be asked to sign in. Screen readers announce it as "Requires sign-in". Only for an item with `access`: `writedocs validate` rejects it anywhere else.

`access` works on the same items as `hidden`. It can't go on an item with `href` (a link has no pages to protect) or in `global.dropdowns`.

## Rules inside rules

When a protected item holds another protected item, the inner rule wins: its pages are protected by the inner rule only.

```json
{
  "tab": "Partners",
  "access": "partners",
  "products": [
    { "product": "Program", "pages": ["partners/intro"] },
    { "product": "Revenue", "access": "staff", "lock": true, "pages": ["partners/revenue"] }
  ]
}
```

Here `partners/intro` needs the `partners` rule, and `partners/revenue` needs `staff` - a partner can't open it.

## What readers see

- **Protected doesn't mean hidden.** A protected item stays in the tabs and menus, so readers know it's there - add `lock` to show it needs a sign-in. Opening one of its pages asks for the rule's password or email first.
- **Protected and hidden.** To keep the item out of every menu too, add `"hidden": true` - see [Hidden sections](https://docs.writedocs.io/docs/configuration/hidden-sections/). Share its pages' addresses with the people it's for; they still sign in.
- **The site's address (`/`) never opens a protected page**, and a folder address opens a public page when the folder has one. A folder with only protected pages in it asks for the sign-in.

## What's left out of public files

A protected page is never listed where anyone can read it:

- it isn't in `sitemap.xml`, and it tells search engines not to index it, whatever its own `seo` says;
- it isn't in `llms.txt` or `llms-full.txt`, and the site's [MCP server](https://docs.writedocs.io/docs/configuration/mcp/) doesn't serve it;
- it gets no link-preview image;
- the site's search never finds it;
- the old address of an API page whose endpoint has no tag (`/api/untagged/...`, from before Writedocs 0.10.14) redirects to it only for readers the rule lets in.

An OpenAPI group shown as [Scalar's API reference](https://docs.writedocs.io/docs/openapi/overview/#scalars-api-reference) is protected like the rest: its reference page carries your spec inside the page, never in a file of its own, so the spec is behind the rule too, and its download button is turned off.

## Search

Each access rule has a search of its own. Searching from a protected page finds the pages of its rule - from every item that uses it - and never another rule's pages or the site's public ones. With `"searchPublic": true` on the protected item, its search finds the public pages too:

```json
{ "tab": "Partners", "access": "partners", "searchPublic": true, "pages": ["partners/intro"] }
```

A part that is protected and hidden searches only among its own pages, like any hidden section.

## What isn't protected

- **Images and files.** An image or a download stays public, even when only a protected page uses it - anyone with its address can open it. What's protected is the page: its text, its Markdown copy and its search results. Keep anything sensitive out of images and downloads.
- **Snippet components.** A `.jsx` or `.tsx` snippet is built into a script file of the site's, and that file isn't protected - keep sensitive text in the page itself, or in an `.mdx` snippet, which becomes part of the page.
- **The item's name and description**, in the tabs and menus, unless the item is `hidden`.
- **A redirect** in `writedocs.json` that leads to a protected page: the redirect itself is public, and only shows the page's address.
- **`writedocs dev`**: nothing is protected in the preview on your computer - every page opens.

## On your own host

`access` needs the WriteDocs platform: on any other host, the pages are public, like any other page. To keep docs private there, put a login in front of their addresses - on Cloudflare, with Cloudflare Access - or publish them as a separate site.