Skip to main content
Documentation navigation

KAI AUTH / DEVELOPERS

Better Auth 1.7.1Updated Content: Simplified Chinese
View Markdown
On this page

Auth CLI:让 Agent 配置登录

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

安装与运行

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

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

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

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

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 继续配置

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。

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 相同的字段:

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和令牌校验与 claims完成接入;生成文件不等于业务应用已经支持登录。

给 Agent 的任务示例

开发者完成本机 kai-auth login 后,可以提供以下任务:

使用 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 额外身份验证。它与下文用于删除项目等管理动作的 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 获取额外验证结果。

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。成功示例:

{
  "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:

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。回调和客户端规则见应用登记与回调。

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

删除项目的再次验证

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

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 浏览器页面。

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

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 文件后,可以完成删除:

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 退出流程见退出与撤销。

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 登录。

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