---
title: "Auth CLI：让 Agent 配置登录"
description: "Auth CLI 帮助开发者在本机登录 KAI 管理账号，让 Agent 管理组织、项目和应用，并为业务应用生成 OAuth/OIDC 接入配置。"
url: "https://auth.kai.com/docs/auth-cli"
language: "zh-CN"
version: "Better Auth 1.7.1"
updated: "2026-09-22"
---

# Auth CLI：让 Agent 配置登录

Auth CLI 帮助开发者在本机登录 KAI 管理账号，让 Agent 管理组织、项目和应用，并为业务应用生成 OAuth/OIDC 接入配置。

## 安装与运行

命令名为 `kai-auth`，包名为 `@kai/auth-cli`，需要 Node.js 24.3.0 或更高版本。当前可从仓库构建本地安装包；以下流程不依赖 npm 上已发布的包。

在仓库的 Yarn 开发环境中构建：

```sh
yarn workspace @kai/auth-cli build
yarn workspace @kai/auth-cli pack --out /tmp/kai-auth-cli.tgz
```

将生成的安装包放到开发者本机，然后运行：

```sh
npm install -g /tmp/kai-auth-cli.tgz
kai-auth browser install
kai-auth --help
```

`browser install` 为开发者管理登录下载与 CLI 匹配的 Playwright Chromium。已有 Chrome 或 Edge 时，也可以在登录时指定 `--browser chrome` 或 `--browser msedge`。应用侧 `oauth step-up` 使用系统浏览器，不要求下载这个 Chromium；不支持自动打开浏览器的环境可用 `--no-open`。

源码开发可用 `yarn auth:cli --help`，它先构建再运行 CLI；已有构建产物时可用 `node packages/cli/dist/index.js --help`。运行使用对应平台安装的依赖；不要把 Linux 容器中的 `node_modules` 用于宿主 Node。交互登录需要图形浏览器，应在开发者可操作的环境中执行。

## 开发者先登录，Agent 继续配置

```sh
kai-auth login --profile default --origin https://auth.kai.com
kai-auth status --profile default --json
```

`login` 打开独立的 Playwright 浏览器并进入 `/console`。开发者在该窗口完成正常登录及所需验证，CLI 保存本机管理会话。它不导入已有浏览器 profile，也不要求把密码或验证码放进命令、项目文件或 Agent 对话。

后续命令默认使用 `default` profile；可以用 `--profile NAME` 区分账号或环境。`--origin` 仅用于 `login`，其他管理命令使用 profile 中保存的服务地址。未登录、会话失效或权限不足时，命令会报错。`login` 会自动清除已过期的本机会话；已有未过期 profile 需要重新登录时，先运行 `logout` 再 `login`，或者选择一个新的 profile 名称。

Agent 必须在能访问该本机 profile 的环境中运行。本版没有独立的远程无界面登录流程；远程 Agent 无法直接复用开发者另一台机器上的登录状态。

这是开发者管理会话。业务应用的 OAuth access token 不会因此获得管理 API 权限。组织、项目和应用操作继续由服务端校验身份、角色、资源归属与组织状态，敏感操作保留原有的再次验证要求。

## 完整示例：创建应用并生成接入文件

以下示例使用 `jq` 提取命令输出中的 ID。它创建 public Web 应用，通过 Authorization Code + PKCE 登录，不需要 client secret。将回调地址替换成业务应用实际使用的 HTTPS 地址。

先创建组织和项目；已有资源可用 `list` 查询并直接使用返回的 ID。

```sh
ORGANIZATION_ID=$(
  printf '%s' '{"name":"Example Team","slug":"example-team"}' |
    kai-auth organizations create --stdin --json |
    jq -er '.data.id'
)

PROJECT_ID=$(
  printf '%s' '{"name":"Example App","slug":"example-app"}' |
    kai-auth projects create --organization "$ORGANIZATION_ID" --stdin --json |
    jq -er '.data.id'
)
```

创建应用的 JSON 使用与管理 API 相同的字段：

```sh
cat > application.json <<'JSON'
{
  "name": "Example Web",
  "clientType": "public",
  "applicationKind": "web",
  "accessMode": "authenticated_users",
  "scopes": ["openid", "profile", "email"],
  "requiredScopes": ["openid"],
  "optionalScopes": ["profile", "email"],
  "signInMethods": ["authorization_code"],
  "redirectUris": ["https://app.example.com/oauth/callback"],
  "postLogoutRedirectUris": ["https://app.example.com/signed-out"]
}
JSON

APPLICATION_ID=$(
  kai-auth applications create \
    --organization "$ORGANIZATION_ID" \
    --project "$PROJECT_ID" \
    --file application.json --json |
    jq -er '.data.application.id'
)

kai-auth init \
  --organization "$ORGANIZATION_ID" \
  --project "$PROJECT_ID" \
  --application "$APPLICATION_ID" \
  --redirect-uri https://app.example.com/oauth/callback \
  --directory ./my-app --json

kai-auth config show --directory ./my-app --json
kai-auth config env --directory ./my-app --json
kai-auth doctor --directory ./my-app --json
```

每一步失败后先处理错误，再继续下一步。`authenticated_users` 允许非组织成员登录；仅对组织成员开放时改为 `members_only`。`profile` 和 `email` 在此示例中是可选权限，应用必须处理用户未授权这些信息的情况。

`init` 读取已登记应用，在目标目录创建：

| 文件            | 用途                                     |
| --------------- | ---------------------------------------- |
| `kai-auth.json` | 公开的应用接入配置，供 CLI 和 Agent 读取 |
| `.env.example`  | 环境变量示例，不会自动加载进业务应用     |
| `KAI_AUTH.md`   | 供开发者与 Agent 使用的接入说明          |

生成操作不覆盖已有文件；发生冲突时先审查现有内容，或选择新目录。`--redirect-uri` 必须是该应用已经登记的回调；有多个回调时必须显式选择，命令不会自动修改回调白名单。配置中的 `issuer` 来自 Discovery，可以与登录使用的服务 `origin` 不同。

`.env.example` 包含 `KAI_AUTH_ORIGIN`、`KAI_AUTH_ISSUER`、`KAI_AUTH_CLIENT_ID`、`KAI_AUTH_CLIENT_TYPE`、`KAI_AUTH_SCOPES` 和 `KAI_AUTH_SIGN_IN_METHODS`；浏览器授权应用还包含 `KAI_AUTH_REDIRECT_URI`。confidential 应用的 `KAI_AUTH_CLIENT_SECRET` 仅为空白占位。生成文件不包含管理会话或实际 client secret。

配置生成后，Agent 还需要结合业务应用的框架实现 OIDC 登录入口、回调、PKCE、`state`、`nonce`、令牌验证和应用自己的会话。使用 Discovery 中的端点，按照[Authorization Code + PKCE](/docs/authorization-code)和[令牌校验与 claims](/docs/claims)完成接入；生成文件不等于业务应用已经支持登录。

## 给 Agent 的任务示例

开发者完成本机 `kai-auth login` 后，可以提供以下任务：

```text
使用 kai-auth --json 为当前项目接入 KAI 登录。先检查 status 和组织、项目、
应用列表，确认目标资源；需要创建或更新时先读取对应 schema，再提交 JSON。
为选定应用运行 init，阅读 KAI_AUTH.md，并按本项目的框架实现标准 OIDC
Authorization Code + PKCE、回调校验与应用会话。使用 config show/env 获取
公开配置，运行 doctor 后，再验证业务应用真实登录、回调和退出流程。
client secret 只从安全文件交给服务端环境，不放入前端代码或命令输出。
```

本页的机器可读地址为 `/docs/auth-cli/index.md`；也可以通过 `/llms.txt` 查找其余接入资料。

## 应用侧的额外身份验证

`kai-auth oauth step-up` 为应用发起 [OAuth 额外身份验证](/docs/step-up)。它与下文用于删除项目等管理动作的 `kai-auth step-up` 是不同流程，不读取或转发管理 profile 的 Cookie，也不直接调用 KAI 的私有验证接口。

当前命令适用于已登记的 **native / public** 应用，必须启用 Authorization Code、允许 `openid`，并配置精确的本机回调，例如 `http://127.0.0.1:8765/oauth/callback`。该回调需要事先加入应用白名单，并由 `init --redirect-uri` 写入配置。命令不会放宽回调校验、自动增加白名单或把端口替换为随机值；端口被占用时先处理冲突。Web 和 confidential 应用按其运行环境接入标准授权码流程；Device-only 应用必须先登记并启用 Authorization Code，不能通过向 Device 请求添加 `acr_values` 获取额外验证结果。

```sh
kai-auth doctor --directory ./native-app --step-up --json

kai-auth oauth step-up \
  --directory ./native-app \
  --expected-sub CURRENT_USER_SUBJECT \
  --max-proof-age 300 \
  --timeout 600 \
  --json
```

`--expected-sub` 必填，取当前业务已验证身份的 `sub`，不能填写邮箱、昵称，也不能根据本次回调临时更换预期用户。issuer 从接入配置固定读取。

CLI 先启动只监听本机的回调，再打开系统浏览器。用户在 KAI 页面亲自完成登录和额外验证；CLI 使用新的随机 state、nonce 与 S256 PKCE 兑换授权码，并验证 ID token 签名、issuer、audience、nonce、用户、额外验证策略及时间。它请求 `openid` 及应用登记的全部必选权限，不额外请求可选权限，也不把这次证明保存为管理登录会话。若必选权限包含 `offline_access`，命令会在发起授权前报配置错误；该命令不申请长效访问授权，需要调整应用的必选权限配置后重试。

- `--max-proof-age` 默认 300 秒，限制实际证明的新鲜度；刷新令牌不能重新计算此时间。
- `--timeout` 默认 600 秒，限制本次命令等待时间；取消、超时或中断不会被当作验证成功。
- `--no-open` 只把授权入口写到 stderr，供用户在能够访问本机回调的浏览器中打开；它不自动批准、不提交密码，也不是远程无界面认证。
- `--proof-file NEW_PRIVATE_FILE` 显式要求把通过校验的签名 ID token 保存到新的私有文件，权限为 `0600`，不覆盖已有文件。普通命令输出不包含 ID token、access token、refresh token、授权码或 Cookie。

成功结果只区分 `verified` 与 `password_only`，不返回 TOTP、Passkey 等实际方式；当前版本不包含手机批准。`password_only` 表示密码证明校验成功，不表示已经满足高等级要求；业务只接受高等级验证时仍须要求 `verified`。普通 JSON 输出是 CLI 的本机验真报告，不是可以转交给任意服务器的签名凭证；其他服务需要验证专门面向自己的 OAuth 证明，不能盲目信任这份 JSON 或面向 CLI client ID 的 ID token。

使用 `--json` 时，stdout 只输出一份机器可读结果；进度写入 stderr。成功示例：

```json
{
  "ok": true,
  "data": {
    "status": "verified",
    "issuer": "https://auth.kai.com",
    "subject": "CURRENT_USER_SUBJECT",
    "acr": "urn:kai:acr:step-up",
    "authTime": 1790000000,
    "expiresAt": 1790000300
  }
}
```

`authTime` 与 `expiresAt` 均为秒级 Unix 时间；后者是 ID token 的到期时间，不会延长 `--max-proof-age` 规定的证明有效窗口。显式保存证明时，结果另含 `proofFile` 路径。未完成、超时或验证失败时返回 `ok: false` 和脱敏的 `error.code` / `error.message`，并以非零状态退出；不会返回成功状态或未校验的令牌。

`doctor --step-up` 只检查本地配置、Discovery 和这条流程需要的公开能力，不会替代真实用户验证，也不保证远端应用登记没有变化。完整登录、取消、错误回调、时间过期和同一账号核对仍应实际验收。

## 命令与输入契约

| 命令                                             | 主要参数与用途                                                                                               |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `browser install`                                | 安装默认 Chromium                                                                                            |
| `login`                                          | `--profile NAME --origin URL`；可选 `--browser chrome` 或 `--browser msedge`                                 |
| `status`、`logout`                               | 查看或清除所选 profile 的本机登录状态                                                                        |
| `organizations list`                             | 查看当前账号可用的组织                                                                                       |
| `organizations get/create/update/delete`         | get、update、delete 使用 `--organization UUID`                                                               |
| `projects list/get/create/update/delete`         | 必须指定 `--organization UUID`；get、update、delete 另需 `--project UUID`                                    |
| `applications list/get/create/update/delete`     | 必须指定 `--organization UUID --project UUID`；get、update、delete 另需 `--application UUID`                 |
| `step-up start/prove/send-otp/verify-otp/cancel` | 通过 `--file` 或 `--stdin` 提供 JSON；除 start 外还需 `--transaction UUID`                                   |
| `oauth step-up`                                  | 应用侧额外验证；`--directory DIR --expected-sub SUBJECT`，可选时间限制、`--no-open`、`--proof-file NEW_FILE` |
| `schema NAME`                                    | 输出指定输入的 JSON Schema                                                                                   |
| `init`                                           | 指定组织、项目、应用 UUID；可选 `--directory DIR --redirect-uri URL`                                         |
| `config show/env`                                | 读取 `--directory DIR` 下的接入配置或生成环境变量说明                                                        |
| `doctor`                                         | 检查 `--directory DIR` 下的配置及服务端 Discovery；`--step-up` 追加本机 OAuth 额外验证检查                   |

create、update 使用 `--file PATH` 或 `--stdin` 二选一读取 JSON。输入在发请求前通过 API 的 Effect Schema 验证；服务器仍会检查当前数据和权限。可读取以下 schema：

```sh
kai-auth schema organization-create --json
kai-auth schema organization-update --json
kai-auth schema project-create --json
kai-auth schema project-update --json
kai-auth schema application-create --json
kai-auth schema application-update --json
kai-auth schema project-delete --json
kai-auth schema step-up-start --json
kai-auth schema step-up-prove --json
kai-auth schema step-up-send-otp --json
kai-auth schema step-up-verify-otp --json
kai-auth schema step-up-cancel --json
```

JSON Schema 用于了解字段结构；跨字段限制也会在实际命令执行时验证。例如 `requiredScopes` 与 `optionalScopes` 必须同时给出、不重叠，并合起来等于 `scopes`；native 应用必须为 public。回调和客户端规则见[应用登记与回调](/docs/applications)。

delete 必须显式提供 `--confirm`，值等于待删除对象的 UUID。删除项目还需要通过 `--file` 或 `--stdin` 提供有效的 `project-delete` 再次验证凭证。凭证绑定具体动作、对象、会话与版本并由服务端验证，`--confirm` 不能代替它。

## 删除项目的再次验证

使用相同的 profile 发起、验证并消费 step-up 事务，不能从另一个浏览器登录会话复制凭证。先为目标项目启动事务：

```sh
kai-auth step-up start --stdin --json <<JSON
{"action":"project_remove","resourceId":"$PROJECT_ID"}
JSON
```

读取响应中的 `data.transaction`。`transactionId` 用作后续的 `--transaction`；每次提交使用最新返回的 `transactionRevision` 作为 `expectedTransactionRevision`。`allowedMethods` 列出可用方式，`otpTargets` 给出可用联系人的 ID 和脱敏地址。

| 命令                 | 输入 JSON 字段                                                                              |
| -------------------- | ------------------------------------------------------------------------------------------- |
| `step-up prove`      | `expectedTransactionRevision`、`method`（`password` 或 `totp`）、`proof`（密码或六位 TOTP） |
| `step-up send-otp`   | `expectedTransactionRevision`、`method`（`email_otp` 或 `sms_otp`）、`contactId`            |
| `step-up verify-otp` | `expectedTransactionRevision`、`challengeId`、`code`（六位验证码）                          |
| `step-up cancel`     | `expectedTransactionRevision`                                                               |

开发者通过受保护的输入文件或 stdin 提供密码、TOTP 或验证码，避免放入命令行参数、shell 历史、普通项目文件或日志。不要把证明输入交给无关工具。只选服务器允许的验证方式；这里的管理 `step-up` 命令不直接执行 Passkey，需要 Passkey 时在控制台完成管理操作。应用侧 `oauth step-up` 则将验证交给 KAI 浏览器页面。

例如，把验证输入安全保存在项目以外的私有文件后：

```sh
kai-auth step-up prove --transaction "$TRANSACTION_ID" \
  --file "$PRIVATE_PROOF_INPUT_FILE" --json
```

密码或 TOTP 验证使用 `prove`。邮件或短信验证先调用 `send-otp`，再使用其返回的 `challengeId` 和最新事务版本调用 `verify-otp`。仅当返回 `data.transaction.state` 为 `ready` 时，`data.proof` 才是可用于删除的请求体；否则继续按事务状态处理，不能自行填造凭证。

将 ready 响应中的 `data.proof` 保存为权限受限的临时 JSON 文件后，可以完成删除：

```sh
kai-auth projects delete --organization "$ORGANIZATION_ID" \
  --project "$PROJECT_ID" --confirm "$PROJECT_ID" \
  --file "$PRIVATE_DELETE_PROOF_FILE" --json
```

凭证只能使用一次并有有效期。事务不再需要时使用 `step-up cancel`；失败或版本变化时读取错误并重新确认当前状态，不重复提交旧凭证。

## 机密应用与本机凭据

confidential 应用只适用于能保守秘密的服务端。创建这类应用时，CLI 将一次性 client secret 写入本机的新文件，权限为 `0600`，结果只返回文件路径。默认文件放在 CLI 配置目录，也可用 `applications create --secret-file PATH` 指定一个不存在的文件。将秘密通过服务端的秘密管理机制提供给应用，不能放进前端 bundle、版本库或普通日志。

CLI 配置目录依次采用 `KAI_AUTH_CONFIG_DIR`、`$XDG_CONFIG_HOME/kai-auth`、`~/.config/kai-auth`。profile 凭据与业务项目文件分开保存，应只允许所需的本机开发者或 Agent 访问。`kai-auth logout --profile NAME` 对尚未过期的会话先执行服务端注销，再清除该 profile 的本机登录状态；服务端连接失败时保留 profile 供重试注销。业务应用的 OIDC 退出流程见[退出与撤销](/docs/logout)。

## JSON 输出与诊断范围

所有命令支持 `--json`，stdout 只输出一个 JSON 对象，进度发往 stderr。成功形态为 `{"ok":true,"data":...}`；失败形态为 `{"ok":false,"error":{"code":"...","message":"..."}}`，有请求编号时附带 `requestId`。`doctor` 的检查失败额外在 `data` 中保留逐项报告，错误码为 `DIAGNOSTICS_FAILED`。失败退出码非零。Agent 应同时检查退出码和 `ok`，解析时不要合并 stderr 与 stdout。

命令不会打印 session cookie 或 client secret。`doctor` 校验本地接入配置和实时 Discovery，包括 issuer、协议端点、scope、grant 和 PKCE 等配置。每项报告 `pass`、`fail` 或 `skipped`；它不重新核对远端应用当前的登记状态，也不执行真实 OAuth 登录。

通过检查只说明已检查的条件符合要求，不代表完整授权、回调、换取令牌或应用会话已经验证。真实登录仍需在业务应用中完成，并检查用户拒绝授权、可选权限未获准、回调错误和退出等结果。
