Skip to content

Password (KIMI_CODE_PASSWORD) authentication runs bcrypt on every API request and makes Kimi Web significantly slower #1904

Description

@quark-zju

What version of Kimi Code is running?

0.27.0

Which open platform/subscription were you using?

platform.kimi.ai

Which model were you using?

No response

What platform is your computer?

Linux 6.12.63-current-sunxi64 aarch64 unknown

What issue are you seeing?

When Kimi Web is accessed using the credential configured through KIMI_CODE_PASSWORD, authenticated REST requests and WebSocket initialization are noticeably slow, especially when kimi web is running on a slow machine, such as a Raspberry Pi.

Using the persistent server token against the same running server is fast.

The difference appears to be caused by password authentication performing a bcrypt comparison for every protected request. Server-token authentication uses a fast timing-safe comparison and short-circuits before reaching bcrypt.

Note: The password used for testing contained only letters, digits, -, _, and ., so this is separate from WebSocket subprotocol syntax or credential escaping issues.

What steps can reproduce the bug?

  1. Start Kimi Web with password authentication enabled:

    KIMI_CODE_PASSWORD='test-password_123' kimi web --foreground --no-open --host 127.0.0.1 --port 58627

  2. Open the bare server URL without the generated token fragment: http://127.0.0.1:58627/ (without #token=)

  3. Enter test-password_123 in the server credential dialog.

  4. Observe the time required for the Web UI to initialize and for authenticated API operations to complete. Refresh the page, it can take 20 seconds (when served by a Raspberry Pi).

  5. Open a new private browser window, or clear site data, open the same URL: http://127.0.0.1:58627/ (without #token=)

  6. Enter the server-token printed from kimi web, not the password.

  7. Observe that initialization and subsequent refreshes are significantly faster, even though this is the same server process.

What is the expected behavior?

Password authentication should not perform an expensive bcrypt comparison independently for every REST request and WebSocket authentication step.

Ideally, the password should be verified once and exchanged for a temporary session credential. Subsequent requests should use that credential and have performance comparable to the persistent server-token path.

Lowering the bcrypt cost does not seem like the preferred solution because it would weaken password hashing without addressing the repeated-verification design.

Additional information

The current source appears to explain the behavior.

KIMI_CODE_PASSWORD is hashed with bcrypt cost 12:

Credential validation tries the persistent token first and falls back to bcrypt password verification:

isValid: async (candidate) =>
deps.tokenStore.isValid(candidate) ||
(await verifyPassword(candidate, deps.passwordHash)),

Consequently:

  • A valid server token succeeds immediately and skips (the slow) bcrypt.
  • A valid password first fails the token comparison and then performs bcrypt.
  • The global authentication hook invokes this validation for every protected REST request.
  • WebSocket upgrade authentication invokes the same validator.

Related sources:

A possible solution would be to authenticate the password once and issue a short-lived session token, rather than using the password itself as the bearer credential for every request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions