星海智算开发文档
应用开发SDK 与 HTTP 参考

会话与应用间授权

RuntimeSession、组织目录、AppGrant 与开发调试应用间中转的逐操作 HTTP 参考。

本文只覆盖应用服务端运行身份、组织目录和应用间授权。应用版本与上传见开发者应用 API 参考,模型、媒体和异步任务见应用中心 HTTP API 参考。完整语言无关合同可下载 OpenAPI 3.1 YAML

1. 地址、身份与通用约定

正式应用只使用平台注入的 JUSP_APP_SESSION_BASE_URL、应用凭据文件和 appKey。平台负责把会话服务地址指向受控 AppStore 内部入口;应用不应拼接、猜测或向用户展示真实内部地址。应用凭据必须与 URL 中的 appKey 匹配,服务端按应用 ServiceAccount 身份校验;不接受请求体中的 tenant、account、workspace、organization 或 role 作为身份来源。

每个请求建议发送随机 X-Request-IDsessionIdlaunchCode、grant 都是不透明值,不入日志、不写浏览器脚本。启动码、grant 和会话响应不使用统一 data 信封,按下列对象结构解析。

认证面认证方式用途
正式 RuntimeSession平台托管应用凭据exchange、resolve、renew、组织目录、生产 AppGrant
开发调试 RuntimeCLI 短期 Bearer会话解析、组织目录、当前版本的开发者 grant 和 /v1/inter-app 中转

常见错误:400 修正请求;401 重新打开或重新认证;403 身份/角色不允许;404 资源不存在、失效或受控隐藏;409 读取最新状态;429 按 Retry-After;503 依赖暂不可用。只有带稳定幂等键的操作才可在网络状态不明时查询后重试。

2. RuntimeSession

POST {JUSP_APP_SESSION_BASE_URL}/apps/{appKey}/runtime-sessions:exchange

应用在用户打开后收到一次性 launchCode,向平台交换短期运行会话。

请求体:

{"launchCode":"一次性启动码"}

launchCode 必填且非空。服务端原子消费启动码并创建会话;错误 appKey 不会消费启动码,并发只有一个请求成功。成功为 200,返回 RuntimeSession;缺少/非法请求为 400,启动码拒绝或已消费为 401,app 凭据不匹配为 403,handler 未接线(内部服务接口未配置)实际返回 500。响应不明时不要盲目重放,重新从应用中心打开应用。

GET {JUSP_APP_SESSION_BASE_URL}/apps/{appKey}/runtime-sessions/{sessionId}:resolve

读取当前 appKey 下仍有效的会话。无请求体,成功 200。不存在、过期、撤销、跨 app 或主体不匹配统一受控 404;应用凭据不匹配为 403;handler 未接线(内部服务接口未配置)实际返回 500。只缓存成功结果,缓存不能超过 expiresAt

POST {JUSP_APP_SESSION_BASE_URL}/apps/{appKey}/runtime-sessions/{sessionId}:renew

旧会话仍有效时重新核对当前用户、组织关系、应用角色和应用状态,并返回新会话。请求体省略或严格为 {};非空其它 JSON 为 400。成功 200,默认新会话有效 24 小时;同一旧会话并发续期返回同一新会话,旧会话最多保留 1 分钟用于并发收口。默认从初次交换最多连续续期 7 天。

404 RUNTIME_SESSION_NOT_FOUND 表示旧会话不存在;401 RUNTIME_SESSION_REAUTHENTICATION_REQUIRED 表示超过绝对续期窗口;403 RUNTIME_SESSION_ACCESS_REVOKED 表示权限、主体或应用状态已不允许;409 RUNTIME_SESSION_RENEWAL_BLOCKED 表示当前续期被状态机阻止;依赖不可用为 503 RUNTIME_SESSION_RENEWAL_UNAVAILABLE。失败关闭,重新打开应用。

RuntimeSession 响应

{
  "sessionId":"session_...",
  "appKey":"my-app",
  "appVersionId":"appver_...",
  "subject":{"tenantId":"...","accountId":"...","workspaceId":"...","userId":"...","organizationId":"...","membershipId":"..."},
  "appRoles":["my-app.editor"],
  "expiresAt":"2026-09-03T12:00:00Z"
}

sessionId/appKey/appVersionId/subject/appRoles/expiresAt 是公开字段;organizationIdmembershipId 在无组织上下文时可以省略,appRoles 始终为数组且可为空。不要依赖内部 appId、旧会话收口字段或其它上下文引用。

3. 组织目录

两个接口都只接受平台托管应用凭据;组织、调用者和应用从 RuntimeSession 推导。普通成员、个人空间、过期会话、跨应用会话和无组织上下文不能访问组织目录。

联网调试改用 CLI Bearer,前缀为 {JUSP_APPSTORE_DEVELOPER_BASE_URL}/apps/{appId}/versions/{versionId}/runtime-sessions/{sessionId},末尾同样为 /organization-directory/groups:list/organization-directory/members:list。会话解析为 GET <此前缀>:resolve。路径中的 app/version/session 必须全都匹配本次授权;错误绑定统一隐藏为 404。SDK 自动选择这条公开调试路径,不要求开发者填写正式运行地址。

浏览器确认页选择本人或获准测试账号;目录仍要求所选账号是组织管理员。调试会话有效 1 小时,到期或失权需重新授权,不能通过正式续期接口延长。

POST .../organization-directory/groups:list

请求体严格为 {},成功 200

{"appKey":"my-app","organizationId":"org_...","items":[{"groupId":"g1","parentGroupId":"","name":"研发","groupPath":["研发"],"depth":0,"directMemberCount":2,"branchMemberCount":5}]}

仅当前组织管理员会话允许读取;非法 body 为 400 INVALID_REQUEST,非管理员为 403 ORGANIZATION_MANAGER_REQUIRED,会话不存在为 404 RUNTIME_SESSION_NOT_FOUND,Tenant/角色依赖不可用为 503 ORGANIZATION_DIRECTORY_UNAVAILABLE

POST .../organization-directory/members:list

请求体字段均可选:groupIdincludeDescendantssearchpagepageSizepageSize 最大 100;实现接受非负 page/pageSize,默认值由 Tenant 查询实现决定,建议客户端显式发送 page:1,pageSize:50。未知字段、非法 JSON、负 page/pageSize 或 pageSize>100 为 400 INVALID_REQUEST

成功 200

{"appKey":"my-app","organizationId":"org_...","items":[{"membershipId":"m1","accountId":"a1","displayName":"成员","groupId":"g1","groupPath":["研发"],"organizationRoles":["organization.member"],"appRoles":["my-app.viewer"],"membershipVersion":3,"appRoleVersion":2}],"page":1,"pageSize":50,"total":1}

只返回低敏成员、组织角色、当前应用角色及两个版本号;不返回手机号、邮箱、余额、平台内部角色或其它应用角色。错误状态与 groups:list 相同。

4. 生产 AppGrant

POST {JUSP_APP_SESSION_BASE_URL}/apps/{callerAppKey}/app-grants

调用应用用自己的 RuntimeSession 请求调用另一个应用。请求体五个字段必填:runtimeSessionIdcalleeAppKeyscopeidempotencyKeyrequestDigestrequestDigest 必须为 sha256: 加 64 位小写十六进制;scope 是 2–128 字符的小写开头标识。apiVersion 可选,若使用必须与双方声明匹配。

成功 200 返回一次性明文 grantexpiresAt,默认有效 2 分钟,明文只出现一次。相同幂等键和相同规范请求复用同一事实;同键不同 payload 为 409 APP_GRANT_IDEMPOTENCY_CONFLICT。请求/能力前提不满足为 400404 APP_GRANT_PRECONDITION_NOT_FOUND,能力未声明为 403 APP_CAPABILITY_NOT_DECLARED,签名/存储依赖不可用为 503 APP_GRANT_SERVICE_UNAVAILABLE

POST {JUSP_APP_SESSION_BASE_URL}/apps/{calleeAppKey}/app-grants:resolve

被调用应用使用自己的凭据解析 grant。请求体:grantscoperequestDigest。成功 200 返回 grantId、caller/callee appKey 与版本、subjectcallerAppRoles、scope、幂等键、摘要、expiresAt,不返回明文 grant。被调用方必须在业务副作用前再次核对 scope 和 digest;无效、过期、已消费或错误 callee 为 404 APP_GRANT_NOT_FOUND

POST {JUSP_APP_SESSION_BASE_URL}/apps/{calleeAppKey}/app-grants:launch

请求体与 resolve 相同。成功 200 返回一次性 launchCodeexpiresAt,handler 默认有效 1 分钟,只用于应用跳转,不替代后端 RPC。grant 不存在为 404 APP_GRANT_NOT_FOUND,交接依赖不可用为 503 APP_HANDOFF_UNAVAILABLE

5. 开发调试应用间中转

POST /api/v1/appstore/developer/apps/{appId}/versions/{versionId}/app-grants

由绑定候选版本的 CLI Bearer 调用。请求体:calleeAppKeyapiVersionscopeidempotencyKeyrequestDigest;调用方不能提交 runtimeSessionId。平台校验候选版本 dependencies、目标生产版本 integration 和 onlineDebug。成功 200 返回 2 分钟 grant、apiVersionsourceChannel=developer_debug;无效/被拒绝为 409 DEVELOPER_APP_GRANT_REJECTED,前提隐藏为 404

ALL /v1/inter-app/{calleeAppKey}/{apiVersion}/{businessPath}

使用同一 CLI Bearer,并发送 X-Jusp-App-Grant。实现路由允许所有 HTTP 方法;OpenAPI 对常用的 GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD 分别声明,业务客户端仍应以被调用应用自己的 API 合同为准。平台只按 grant 解析出的目标生产版本转发,剥离开发者 Authorization、Cookie 和内部身份头,不跟随重定向、不自动重试,响应正文最大 16 MiB。缺少 grant 为 401 APP_GRANT_MISSING,会话/授权无效或路由不可见为受控 404,依赖不可用为 503

中转不提供任意 service discovery,不接受调用方指定上游地址,也不替提供方校验领域请求体之外的业务摘要和 scope;业务请求必须使用提供方公开的 apiVersion 与 capability。

6. 双本地联网授权与会话

以下路径统一以前缀 https://app-api.jusuanhub.com:10443/api/v1/appstore/developer/apps/{appId}/versions/{versionId} 开始。每一方只使用自己 CLI 获得的 Bearer;appId/versionId 必须属于该凭据。平台校验双方选择的是同一获批用户、组织和当前身份,不接受请求体传入主体或角色。

方法与后缀请求体成功结果
POST /debug-receiverscallerAppKeyapiVersionscopes200,receiverRef/callerAppKey/apiVersion/scopes/expiresAt
DELETE /debug-receivers/{receiverRef}200 {"revoked":true}
POST /debug-peer-grantsreceiverRef、calleeAppKey、apiVersion、scope、requestDigest、idempotencyKey200,grant/apiVersion/sourceChannel/expiresAt
POST /debug-peer-grants:resolvegrant、scope、requestDigest200,前述 AppGrant 解析对象,不返回明文 grant
POST /debug-peer-grants:launchgrant、scope、requestDigest200,launchCode/expiresAt
POST /debug-runtime-sessions:exchange仅 launchCode200,目标应用自己的 RuntimeSession
GET /runtime-sessions/{sessionId}:resolve200,本次 CLI 或自己配对派生的会话

scopes 必填,1–32个能力,必须与提供方版本明确开放的 onlineDebug 能力一致。apiVersion 与双方声明一致;摘要固定 sha256: 加64位小写十六进制,幂等键必填且最多255字符。未知请求字段和非法 JSON 返回400。接收许可最长一小时,grant 最长两分钟,启动码最长一分钟且单次;会话到期不超过双方源授权期限。

同一幂等键和相同请求可复用授权,resolve 不消费授权;同键不同摘要返回 409 DEBUG_PEER_IDEMPOTENCY_CONFLICT。错误目标、版本、主体、能力、失效或撤销统一返回 404 DEBUG_PEER_NOT_FOUND,依赖不可用为 503 DEBUG_PEER_UNAVAILABLE。启动码错误不消费;数据库写入失败不留下已消费但无会话的半结果。交换成功后不得重用启动码。

配对引用可交给另一开发者,但它不是凭据,不能据此冒充对方。提供方退出或撤销后,既有 grant 和派生会话继续解析也会被拒绝。开发会话不能通过正式续期变成长期会话;到期重新运行 CLI。

业务请求直接发往明确配置的本地提供方,只带短期 grant 和业务数据,不带调用方 CLI token、Cookie 或 RuntimeSessionsourceChannel=developer_local 区分于上一节中转模式。submissions.view 可在声明允许时申请通用启动交接,但只读范围和禁止编辑必须由提供方业务接口落实。完整启动命令见 jusp CLI 指南

本页目录