MoonshotAI / MoonshotAI/kimi-code

[ACP] API-key login does not satisfy the session auth gate — session/new always returns auth_required (-32000)

Open
#1,330 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

What version of Kimi Code is running?

0.22.0

Which open platform/subscription were you using?

open platform

Which model were you using?

kimi-k2.7-code

What platform is your computer?

Darwin 25.3.0 arm64 arm

What issue are you seeing?

When a user authenticates with an API key (open-platform path) instead of OAuth, the ACP adapter rejects every session/new (and session/load / session/resume / authenticate) with auth_required (-32000), even though the API key is valid and usable in the TUI. The initialize handshake succeeds (it carries no credentials), so a client sees: init OK → session/new auth failure.

What steps can reproduce the bug?
  • Log in with an API key via the open-platform path (so config.providers[] = { type: "kimi", baseUrl, apiKey } is written, but no token is written to ~/.kimi-code/credentials/kimi-code.json).
  • Start the ACP server: kimi acp.
  • As a client, send initialize → succeeds, returns authMethods: [{ id: "login", type: "terminal", ... }].
  • Send session/new → fails with JSON-RPC error code: -32000 ("Authentication required").

This reproduces against any ACP-compliant client (Zed, JetBrains, a raw JSON-RPC client). It is not client-specific.

What is the expected behavior?

If the user has a valid, non-empty apiKey configured for any provider, harnessIsAuthed() should report hasToken: true (or the gate should be skipped for API-key providers), so session/new succeeds.

Additional information

The session gate harnessIsAuthed() only inspects the OAuth token file; it has no awareness of API-key providers.

packages/acp-adapter/src/server.ts:

async function harnessIsAuthed(harness: KimiHarness): Promise<boolean> {
  const status = await harness.auth.status();
  return status.providers.some((entry) => entry.hasToken === true);
}

async newSession(params) {
  if (!(await harnessIsAuthed(this.harness))) {
    throw RequestError.authRequired();   // -32000
  }
  // ...
}

The chain KimiAuthFacade.status() → KimiOAuthToolkit.status() → managerFor(...).hasToken() → OAuthManager.loadState() → FileTokenStorage.load() reads only ~/.kimi-code/credentials/.json (default name kimi-code). managerFor unconditionally constructs an OAuthManager — there is no branch for API-key providers, and status() always resolves the managed:kimi-code slot.

Meanwhile, API-key login (applyOpenPlatformConfig in packages/oauth/src/open-platform.ts) writes:

config.providers[providerKey] = { type: "kimi", baseUrl: ..., apiKey: ... };

under a different provider key (e.g. moonshot-cn), to the config file only. It does not write a credentials file and does not set an oauth ref. Therefore hasToken() returns false, the gate fails, and session/new throws auth_required.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/acp-adapter/src/server.ts at harnessIsAuthed() and trace KimiAuthFacade.status() through packages/oauth to managerFor() and FileTokenStorage.load(). Compare that path with applyOpenPlatformConfig in packages/oauth/src/open-platform.ts, which stores API keys in config.providers. Done means a configured non-empty API key allows session/new and related session operations while OAuth authentication continues to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, authentication, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.