Skip to content

feat(oauth): import the Muse Code CLI credential behind a ToS warning - #3337

Merged
lidge-jun merged 5 commits into
devfrom
codex/meta-muse-device-oauth
Sep 3, 2026
Merged

lidge-jun merged 5 commits into
devfrom
codex/meta-muse-device-oauth

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

Adds meta-muse, an OAuth provider that reuses the API key the Muse Code CLI already holds, for operators who signed that CLI in and would rather not provision a second key.

This ships because the repository owner authorized it for his own account. An earlier phase in this unit closed the same idea as a NOOP, and that reasoning stands: proving a credential works is not the same as being allowed to use it, so an agent must not spend a user's ToS risk on its own initiative. A user spending his own deliberately is a different act — and the repository already models it, since anthropic and google-antigravity sit in the same HIGH_RISK map for the same reason.

Two measurements shaped the design

~/.config/muse/auth.json holds no secret — it is a pointer to a macOS Keychain item. That item carries both an access_token and an api_key, and only the api_key authenticates: the OAuth access token returns 401 invalid_api_key on /v1/models while the sibling key returns 200. So this is a static-key credential with nothing to refresh — the shape command-code already uses.

Import-only, macOS-only

muse login has no non-interactive mode, so a spawned child could outlive cancellation; and polling for the pointer file is satisfied instantly by the one already on disk, which would reimport the old account on a force-login. When no credential is present the provider says what to run instead of running it.

The warning reaches both surfaces, which took two fixes

  • The GUI map alone was not enough. Reauthentication called loginOAuth directly, so a user who had already logged in could refresh a high-risk credential without ever seeing the modal. onReauth now routes through the warning-aware path, carrying accountId so acknowledgement continues the same operation rather than a plain login against the active account.
  • login-cli.ts never reads the registry note, so ocx login meta-muse had no warning at all. loginMetaMuse emits it through ctrl.onProgress before it touches the pointer or the Keychain.

The disclosures say what is actually known

Meta scopes this credential to its own CLI, and how these calls settle is not observable from the API — so the note says treat every call as billable rather than asserting pay-as-you-go as fact. It also states plainly that the key is copied into OpenCodex's auth store, because it is: runLogin persists it like every other OAuth credential.

Also included

  • Two price overlays. Overlays resolve by exact provider id, so a provider whose entire warning is "treat every call as billable" would otherwise report no cost at all.
  • A privacy:scan detector for the measured LLM|<digits>|<tail> key shape, exercised through a new exported scanText seam — a test that re-declared the regex would stay green after the production detector was deleted.
  • supportsPerAccountQuota stays false, with a test. That predicate gates fetchAccountQuota, whose fallback sends any non-Kiro/non-Antigravity bearer to Anthropic's usage endpoint; flipping it without a dedicated branch would ship a Meta key to Anthropic.

Quota is deferred. Meta does report subscription windows, but only as a response.subscription_usage SSE event on streaming turns — that needs a passive read-and-cache seam rather than a probe, and it touches the streaming path and account attribution. Planned as wp5 in 050_wp5_passive_muse_quota.md.

Verification

  • bun test on the six touched suites — 166 pass, 0 fail, 1417 assertions.
  • cd gui && bun test tests/oauth-tos-warning-gate.test.tsx — 12 pass, 0 fail.
  • bun x tsc --noEmit — exit 0.
  • bun run privacy:scan — passed.
  • bun run lint:gui — clean. cd gui && bun run build — success.
  • cd docs-site && bun install --frozen-lockfile && bun run build — 417 pages.
  • bun run test:changed — 14157 pass / 11 skip / 1 fail. The single failure is tests/lab-fabric-task.test.ts (CL-07 producer, ~760ms timeout), unrelated: that file passes 49/49 standalone with this branch applied, and it failed the same way on the wp1 PR.
  • The repository-wide local suite was not run, per standing user instruction.
  • No test reads the real Keychain or reaches the network.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. (New docs-site provider section stating the unsupported-use boundary, macOS/CLI requirement, auth-store persistence, and the meta-model alternative.)
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. (Credential is read through injected deps and never logged — a test asserts a canary appears in no message, progress line, or stack. defaultRefreshPolicy: "disabled" prevents unattended traffic on a vendor-restricted credential. Refresh cannot re-import and overwrite a different account's slot. New scanner rule covers the key shape.)

Summary by CodeRabbit

  • New Features
    • Added Meta Muse Code (CLI) as a macOS-only authentication option.
    • Added Muse Spark 1.3 model routing and cost estimates.
    • Added safeguards to detect and protect Meta API keys.
  • Changes
    • Added a high-risk Terms-of-Service warning before Meta Muse login and reauthentication.
    • Improved account-specific OAuth continuation after warning acknowledgment.
  • Documentation
    • Documented Meta Muse setup, limitations, credential handling, and alternatives.
  • Tests
    • Added coverage for authentication, warning flows, privacy scanning, model routing, and pricing.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant