Skip to content

docs(mau): document client identity and correct the read-only rule - #463

Open
ttypic wants to merge 1 commit into
integration/mau-connection-failuresfrom
integration/mau-docs
Open

ttypic wants to merge 1 commit into
integration/mau-connection-failuresfrom
integration/mau-docs

Conversation

@ttypic

@ttypic ttypic commented Oct 1, 2026 •

Copy link
Copy Markdown

Add docs/Client-Identity.md: server/device classification by auth
mode, the client ID precedence, values the CLI refuses, target vs
identity --client-id, and the multi-user demo pattern (two terminals
with --client-id for a demo, a client-scoped token to reproduce device
behaviour exactly).

  • Rewrite the --client-id help, the token --client-id help and the
    ABLY_API_KEY / ABLY_TOKEN env-var text, which presented
    --client-id none as a normal option and described per-run random
    client IDs.
  • Correct the rule in AGENTS.md, the ably-new-command skill and the
    src/flags.ts comment that client identity is irrelevant for read-only
    commands: under MAU billing reads carry the session's client ID and
    are counted; they just have no reason to act as someone else.

- Add docs/Client-Identity.md: server/device classification by auth
  mode, the client ID precedence, values the CLI refuses, target vs
  identity --client-id, and the multi-user demo pattern (two terminals
  with --client-id for a demo, a client-scoped token to reproduce device
  behaviour exactly).
- Rewrite the --client-id help, the token --client-id help and the
  ABLY_API_KEY / ABLY_TOKEN env-var text, which presented
  `--client-id none` as a normal option and described per-run random
  client IDs.
- Correct the rule in AGENTS.md, the ably-new-command skill and the
  src/flags.ts comment that client identity is irrelevant for read-only
  commands: under MAU billing reads carry the session's client ID and
  are counted; they just have no reason to act as someone else.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cli-web-cli Ready Ready Preview Oct 1, 2026 12:56pm UTC

Request Review

@claude-code-ably-assistant

Copy link
Copy Markdown

Walkthrough

This PR corrects a subtle but important misconception in docs, code comments, and flag descriptions: the claim that client identity is "irrelevant" for read-only commands. In reality, every CLI command carries a client ID (and Ably counts it under MAU billing) — read-only commands simply have no reason to act as a different client, so clientIdFlag is still correctly omitted. The PR also adds a new docs/Client-Identity.md reference page documenting server vs. device traffic classification, client ID resolution order, and token auth behaviour.

Changes

Area Files Summary
Docs docs/Client-Identity.md (new) 85-line reference covering MAU classification (server/device), client ID precedence chain, deprecated values, and multi-user simulation patterns
Docs docs/Environment-Variables/General-Usage.md Adds a cross-reference link to the new Client-Identity doc
Config / Agent instructions AGENTS.md Corrects clientIdFlag guidance and adds Client-Identity.md to the docs/ listing
Skills .claude/skills/ably-new-command/SKILL.md, references/patterns.md Replaces "identity is irrelevant for reads" with the accurate "reads carry identity but have no reason to act as someone else"
Commands src/commands/auth/issue-ably-token.ts, src/commands/auth/issue-jwt-token.ts Removes the misleading --client-id "none" example; rewrites client-id flag description to warn anonymous tokens are rejected by identified-client apps
Utils / Data src/data/env-vars.ts Rewrites ABLY_API_KEY and ABLY_TOKEN client ID help text with accurate per-install identity and MAU billing detail
Flags src/flags.ts Updates clientIdFlag JSDoc and description to reflect session identity semantics and token auth behaviour

Review Notes

  • Behavioural change (minor UX): The --client-id "none" example is removed from auth issue-ably-token examples, and "none" is now described as deprecated in docs/Client-Identity.md. No runtime behaviour changes — the deprecated value still works with a warning.
  • MAU billing clarification: The corrected rule ("reads carry identity, they just don't need to act as someone else") affects how future contributors use clientIdFlag. Reviewers should verify the rationale in docs/Client-Identity.md matches the actual SDK/billing behaviour.
  • No new runtime dependencies.
  • Skills updated in sync with the flag description change — important because stale skills would cause Claude to regenerate incorrect code.
  • No test changes — the PR is purely documentation and description corrections; existing unit tests (including the client-id-target-guard test) cover the identity vs. target distinction.

@claude-code-ably-assistant claude-code-ably-assistant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: docs(mau): document client identity and correct the read-only rule

Overview: Pure documentation PR — adds a new docs/Client-Identity.md, updates skill files to correct the rationale for omitting clientIdFlag from read-only commands, and sharpens flag/env-var descriptions throughout. No functional logic changes. I checked all factual claims against the implementation.

Verified accurate

  • JWT rejection before connecting (line 1731-1736 of base-command.ts) — confirmed via this.fail() call
  • "none" is deprecated but still functional with a warning (line 1652-1656 of base-command.ts) — confirmed
  • Empty string "" and "*" are rejected via InvalidClientIdError — confirmed in src/services/client-identity.ts
  • Classification table (API key → server; JWT with x-ably-clientType: server → server; other tokens → device) — matches ably-client-factory.ts

One concern worth addressing

docs/Client-Identity.md line 73 — self-contradictory MAU claim

Both run under the server classification, so they are not counted or capped as devices. Ably counts client IDs wherever they appear, including in message payloads, so each simulated name may still register as an MAU.

The first sentence correctly states server-classified traffic is not counted as device MAU. The second sentence says the same names "may still register as an MAU," which directly contradicts that. More specifically, the phrase "including in message payloads" implies Ably scans message content to count MAU — that's not how Ably billing works. MAU is connection-based, not payload-scanning.

If the intent is to say "server-classified connections still appear in Ably's analytics with those client IDs" that's a different (and narrower) claim. If the intent is to warn users that server classification isn't a billing escape hatch, the rationale needs to be grounded in the actual billing mechanic. As written, it could cause readers to incorrectly believe they're accumulating MAU charges when they're not, or to make unnecessary architectural changes.

Suggested fix: either drop the second sentence (the first already covers the important point), or replace it with a specific, accurate statement about what Ably does track for server-classified traffic.

Minor

The DXRFC-029 reference in the opening paragraph is an internal document external contributors can't look up. Fine to leave as context for rationale, just worth knowing it will be opaque to OSS contributors.

Otherwise the doc is well-structured, the code-behaviour alignment is accurate, and the skill/AGENTS updates correctly capture the new rationale.

@umair-ably
umair-ably added this pull request to stack #465 October 1, 2026 14:14
@sacOO7
sacOO7 requested a lite review from Copilot October 5, 2026 09:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Documentation and help text still contain inconsistencies around deprecated none, command-local client IDs, and native token identity handling.

Review effort: Lite
Findings: 4 Low severity

Open (4)
What changed in this PR

Documents client identity and MAU classification while correcting CLI help, environment-variable guidance, and read-only command instructions.

Changes:

  • Adds client identity and classification documentation.
  • Updates client-ID and token help text.
  • Corrects identity guidance across project documentation and skills.
File Description
src/​flags.ts Updates client-ID guidance.
src/​data/​env-vars.ts Corrects authentication identity guidance.
src/​commands/​auth/​issue-jwt-token.ts Updates token help.
src/​commands/​auth/​issue-ably-token.ts Updates token help.
docs/​Environment-Variables/​General-Usage.md Links client identity documentation.
docs/​Client-Identity.md Adds identity and MAU documentation.
AGENTS.md Corrects read-only identity guidance.
.claude/​skills/​ably-new-command/​SKILL.md Updates command-generation guidance.
.claude/​skills/​ably-new-command/​references/​patterns.md Updates get-command guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/Client-Identity.md
| `ABLY_TOKEN` holding a JWT with `x-ably-clientType: server` | `@ably/pubsub-server` | Server |
| `ABLY_TOKEN` holding any other JWT, or a native Ably token | `@ably/pubsub-device` | Device |

The device package has no HTTP client, so commands that use Ably's HTTP API (`channels publish`, `channels history`, `push ...` and others) fail under a device-classified token, pointing you at an API key or a server-scoped token. Realtime commands such as `channels subscribe` work on either side.
Comment thread docs/Client-Identity.md
Comment on lines +27 to +34
Under API key auth, the client ID is resolved once per process, from the first of:

1. `--client-id <id>`, on commands that offer it
2. `ABLY_CLIENT_ID`
3. `client.id` in the config file (`~/.ably/config`)
4. A default generated once per install (`ably-cli-<8 hex chars>`) and saved as `client.defaultId` in the config

Every client the command builds, every command in an interactive session, and every token minted by `ably auth issue-ably-token` / `issue-jwt-token` without `--client-id` uses that one ID. Commands without a `--client-id` flag still act as it. `ably bench` commands append a per-process suffix to the default, so that many concurrent bench processes stay under the per-client-ID connection cap.
Comment thread docs/Client-Identity.md
Comment on lines +49 to +53
Values the CLI refuses:

- `""` — an empty client ID. It used to fall back silently to a random ID.
- `"*"` — the wildcard. The CLI acts as, and issues tokens to, one concrete client ID.
- `"none"` — deprecated. It still acts with no client ID, with a warning, but apps that require identified clients reject that traffic.
Comment thread docs/Client-Identity.md
- `"*"` — the wildcard. The CLI acts as, and issues tokens to, one concrete client ID.
- `"none"` — deprecated. It still acts with no client ID, with a warning, but apps that require identified clients reject that traffic.

Under token auth the client ID is the token's and is never overridden; `--client-id` is ignored with a warning. A JWT without an `x-ably-clientId` claim is rejected before connecting.

This branch was successfully deployed

1 active deployment
Preview — 454c967c Deployed Oct 1, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants