# Public and authenticated surfaces

A surface is public only when its answer is the same for everybody: the site, this documentation, the machine-readable descriptions, the agent card and the health endpoint. Everything whose answer depends on a workspace needs a session or an integration key. A third group is closed on purpose — the application's own generated API description among them — and stays closed.

- **Status:** Available
- **Audience:** both, developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/security/public-vs-private/

## The rule that decides

Ask one question of any surface: does the answer change depending on who is asking? If it does not — a specification, a page of prose, a liveness probe — it can be public, and making it public is usually the better engineering choice, because a description everyone can fetch is a description nobody has to guess at. If the answer does change, the surface is authenticated, with no middle category for "public but obscure".

Obscurity is what the middle category actually offers, and it is worth nothing once an address has appeared in a browser history, a proxy log or a support conversation. Connect has no surface that is protected by being hard to find.

## What answers without a session

| Surface | Reachable without signing in | What it is for |
|---|---|---|
| The public site and this documentation | Yes | Reading, and being read by search and AI crawlers |
| `llms.txt`, the documentation manifests and the Markdown alternates | Yes | Machine readers that want structure rather than a rendered page |
| The Agent Card at the well-known path | Yes | Agent-to-agent discovery of what Connect is and how to reach it |
| The published OpenAPI, Arazzo and AsyncAPI descriptions | Yes | Designing an integration before you have any credentials |
| The health endpoint | Yes | Liveness only. It reports nothing about any workspace |
| Public tools on the MCP server | Yes | Questions about Connect itself, answered from the documentation |
| The application at `/app`, the public API, workspace MCP tools | No | Anything scoped to a workspace |
| The application's own generated API description and its browsers | Closed | Nothing. These are switched off rather than protected |
| Provider callbacks | Unauthenticated, but verified | See [Verifying an inbound webhook](/docs/security/webhook-verification/) |

> **Note** There is exactly one health path. Aliases such as `/healthz` or `/readyz` do not exist here, and a probe configured against one of them reports a healthy service as down — which is a monitoring fault that reads convincingly as an outage.

## Why the application's own description is off

A framework will happily generate an interactive description of every route it serves, including the ones only the operator uses. That artefact is useful during development and is a map of the whole interior afterwards. It is closed here, and the public description under `/developers/` is written deliberately instead: it covers the surface integrators are meant to use, and it does not grow a new entry every time an internal handler is added.

The same reasoning governs the machine files. `llms.txt` is a map of what a reader may read; it names public pages and never application paths, and the documentation gate fails the build if one appears in it.

## What public does not mean

- It does not mean a crawler can reach workspace content. Nothing scoped is rendered on a public page, at any depth.
- It does not mean unauthenticated writes. Every public surface here is a read, with the single exception of verified provider callbacks.
- It does not mean anonymous sign-in. Google is the only way in, and no password prompt exists to be attacked, because there are no passwords.
- It does not mean permanent. A public artefact is generated by a build, and the build refuses to publish one that contradicts the capability registry.

## Telling the two apart in practice

1. Open the address in a browser with no session.
   - Result: A public surface answers. An authenticated one sends you to sign in rather than returning a partial answer.
2. If you are integrating, start from the published description rather than from what the app happens to call.
   - Result: You build against the surface that is meant to be stable, not against an internal path that can move in any release.
3. For a machine client, read the crawler policy and the agent card first.
   - Result: Both say what is intended for automated reading, which is a better guide than probing for what answers.

## Questions

### Is the documentation you are reading generated from the same facts as the product?

It is built from a capability registry rather than written free-hand, and the build refuses a page that claims something the registry does not record. That is why a page can say a capability is a foundation rather than available and why no page can quietly overclaim one.

### Can I use the health endpoint to monitor my own workspace?

No. It answers whether the service is alive, and it deliberately reports nothing about any workspace — a public endpoint that varied by tenant would be a disclosure with a monitoring label on it. Workspace health lives inside the app.

### Why publish an API description at all if the API needs a key?

Because designing an integration and being allowed to run it are different problems. The description lets a developer, or an agent acting for one, understand the shape before anybody issues a credential. See [The public API](/developers/public-api/).

## Related

- [The public API](https://connectbyjbrh.com/developers/public-api/)
- [Authenticating to the MCP server](https://connectbyjbrh.com/developers/mcp-authentication/)
- [Crawler policy](https://connectbyjbrh.com/developers/crawler-policy/)
- [Verifying an inbound webhook](https://connectbyjbrh.com/docs/security/webhook-verification/)
- [Signing in with Google](https://connectbyjbrh.com/docs/account/google-sign-in/)

## What this page is based on

- Connect source pack section 10 — Google-only sign-in, the one health path, and the closed generated description (`docs-source/sources/GENERAL.md`)
- Connect capability registry (`docs-source/facts.py`) — `public_docs`, `llms_txt`, `mcp_server`, `a2a_agent_card`, `public_openapi`, `integration_keys`
- Connect protocol record (`docs-source/facts.py`) — MCP requires authentication for anything that is not public
