131 lines
9.4 KiB
Markdown
131 lines
9.4 KiB
Markdown
# 凭据、权限与初始化
|
||
|
||
状态:P1 已实现。业务接口每次在数据库事务内校验凭据摘要、撤销/到期、应用与命名空间启停,以及动作和队列范围。授权与写入使用同一事务;管理变更与已经获得授权锁的请求按事务先后次序生效。
|
||
|
||
## 初始化一个新的接入应用
|
||
|
||
前置:专用 MySQL 数据库已经执行 orbit-migrate up,使用持有初始化权限的数据库管理连接。此命令创建新应用、命名空间、队列和凭据,不会覆盖现有同名应用。
|
||
|
||
```sh
|
||
mkdir -p .local
|
||
chmod 700 .local
|
||
go run ./cmd/orbit-admin bootstrap \
|
||
--application sample-app \
|
||
--namespace default \
|
||
--environment development \
|
||
--queue files \
|
||
--output .local/development.credentials.json
|
||
```
|
||
|
||
ORBIT_MYSQL_DSN 通过环境注入,命令不读取 .env。所有名称必填,以字母/数字开头,后续允许字母、数字、`_ . : -`;environment 最长 32,其余最长 128。输出文件必须不存在,以 0600 创建;原始凭据不会打印到 stdout/stderr。`.local/` 和 `*.credentials.json` 已被 Git 忽略。
|
||
|
||
输出 JSON 包含 application_id / namespace_id / queue_id / credential_id / token / expires_at。初始凭据有效期为 30 天,权限包括当前命名空间内的五个 P1 动作和全部队列。初始队列 max_concurrency=4、rate_per_second=10、max_unfinished_tasks=100000;并发、开始限速与积压背压已生效,语义及管理方式见 [队列接口](queues.md)。这些默认值是开发基线,不是容量承诺。
|
||
|
||
如果希望在第一次初始化时同时创建控制台管理员,可在同一条 bootstrap 事务中提供账号,并从标准输入交付密码:
|
||
|
||
```sh
|
||
secret-manager read orbit/console-admin-password | \
|
||
go run ./cmd/orbit-admin bootstrap \
|
||
--application sample-app \
|
||
--namespace default \
|
||
--environment production \
|
||
--queue files \
|
||
--console-username admin \
|
||
--console-display-name 'Orbit 管理员' \
|
||
--console-password-stdin \
|
||
--output .local/production.credentials.json
|
||
```
|
||
|
||
`--console-password-stdin` 要求密码至少 12 个字节,密码不会出现在命令参数、日志或交付 JSON 中。业务凭据、控制台账号和两条初始化审计会在同一个数据库事务中提交;任何一步失败都会整体回滚。交付 JSON 只会额外包含 `console_username`,后续新增控制台账号仍使用 [`orbit-admin console-user create`](../console.md)。
|
||
|
||
资源、凭据摘要和初始化审计在一个事务中提交。交付文件先写入并同步到磁盘,成功后再提交事务。如果文件写入失败则回滚并移除文件;如果已经交付后提交无法确认,保留文件并报错,应使用其中凭据核对结果,不能直接覆盖或重复创建。
|
||
|
||
初始文件包含真实秘密,应保管在受限目录或导入秘密管理系统。运行账户与迁移/初始化账户分开;生产只通过 HTTPS 使用凭据。
|
||
|
||
## 轮换与撤销
|
||
|
||
凭据轮换和撤销只允许在受保护的数据库管理环境执行,不提供公网管理接口。轮换保留 `credential_id`,因此订阅和 Worker 实例的授权绑定仍指向同一记录;新的 Worker 进程必须按现有进程身份规则重新连接,旧令牌不能再通过任何 API 或 WSS 认证。平台不会批量改写在途任务、交付记录或历史会话证据。
|
||
|
||
先读取脱敏状态和当前版本:
|
||
|
||
```sh
|
||
go run ./cmd/orbit-admin credential status \
|
||
--namespace-id <namespace_id> \
|
||
--credential-id <credential_id>
|
||
```
|
||
|
||
状态输出不包含令牌、秘密摘要或权限正文;`revision` 是后续变更的并发条件。
|
||
|
||
```sh
|
||
go run ./cmd/orbit-admin credential rotate \
|
||
--namespace-id <namespace_id> \
|
||
--credential-id <credential_id> \
|
||
--expected-revision 1 \
|
||
--valid-for 720h \
|
||
--reason "scheduled credential rotation" \
|
||
--output .local/rotated.credentials.json
|
||
```
|
||
|
||
命令先读取并核对版本,生成一个固定 `operation_id`、令牌和绝对到期时间,写入新的 `0600` 私有操作文件,然后提交数据库事务。文件不得已存在;提交结果不明、网络断开或数据库返回未知错误时必须保留文件,并使用同一个文件执行 `credential apply --file`,不能重新执行 `rotate` 生成第二个秘密。`--valid-for` 限定在 1 小时到 1 年。数据库只保存秘密摘要、请求摘要和脱敏回执。
|
||
|
||
```sh
|
||
go run ./cmd/orbit-admin credential apply \
|
||
--file .local/rotated.credentials.json
|
||
```
|
||
|
||
`apply` 会严格拒绝软链接、非 0600 文件、未知 JSON 字段、重复 JSON 对象和修改过的操作内容。重复应用已提交的文件只返回原回执,回执中的 `deduplicated` 为 `true`,不会重新轮换或新增审计。
|
||
|
||
发生泄露或 Worker 必须立即停用时执行撤销:
|
||
|
||
```sh
|
||
go run ./cmd/orbit-admin credential revoke \
|
||
--namespace-id <namespace_id> \
|
||
--credential-id <credential_id> \
|
||
--expected-revision 2 \
|
||
--output .local/revoke.operation.json \
|
||
--reason "incident response"
|
||
```
|
||
|
||
撤销同样先写入固定操作文件,再提交事务;提交不明时用 `credential apply --file .local/revoke.operation.json` 重试。撤销只标记凭据失效,不删除订阅、任务、交付或历史记录。即使应用或命名空间已停用,管理撤销仍可执行。重复应用同一撤销文件只返回原回执,不追加重复审计。审计主体取自 MySQL 管理连接的 `CURRENT_USER()`,审计摘要不包含秘密原文或秘密摘要。
|
||
|
||
## 凭据格式与作用域
|
||
|
||
```text
|
||
orb1.<namespace_id>.<credential_id>.<32-byte-base64url-secret>
|
||
```
|
||
|
||
服务端仅保存 SHA-256 秘密摘要。ID 不是授权证明,秘密不进入 URL。客户端请求:
|
||
|
||
```text
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
权限存储格式如下,当前由受控初始化及管理侧写入,不能通过普通任务请求修改:
|
||
|
||
```json
|
||
{
|
||
"actions":["tasks:submit","tasks:read","tasks:cancel","queues:read","queues:manage"],
|
||
"queues":["*"]
|
||
}
|
||
```
|
||
|
||
actions 不支持通配符;queues 可列出队列 ID,星号仅表示当前命名空间内全部队列。创建队列必须具有 queues:manage 和全部队列范围。请求不接受自定义 namespace_id 来跨越隔离边界。
|
||
|
||
原始秘密错误、凭据撤销/过期、应用或命名空间停用统一返回 401。合法身份缺少动作权限返回 403。读取不在范围内的单个资源返回 404,避免披露资源内容。
|
||
|
||
SDK 使用 `orbit.Options{Token: token}`。健康查询不发送凭据。当前不启用业务权限缓存,撤销校验不依赖缓存过期。
|
||
|
||
P3 增加 schedules:read 和 schedules:manage。bootstrap 显式传 --schedule-access 才授予;创建/发布计划还需要 tasks:submit 与队列范围。已有计划属于命名空间,创建凭据到期或撤销不自动暂停计划;停止新触发应暂停计划,或禁用应用/命名空间。详见 [计划接口](schedules.md)。
|
||
|
||
P2 增加 workers:connect 和 workers:consume。bootstrap 只有显式提供 --worker-access 时才同时授予这两项开发权限;现有凭据不自动变化。Worker 还需独立的进程恢复秘密和尝试秘密,见 [Worker 契约](worker.md)。
|
||
|
||
P3 应用额度管理新增 `application:resources:read` 和 `application:resources:manage`。只有显式 `--resource-access` 才授予,作用域是所属应用的全部命名空间,普通队列管理不能替代。查询返回聚合计数,不开放其他命名空间的任务数据。`bootstrap --application-id <现有应用ID>` 可由数据库管理员增加命名空间,与 `--application` 二选一;验证应用启用及额度记录存在后,同事务创建新资源,所有秘密交付约定保持不变。应用默认未终结上限 1000000、并发 10000、开始速率 100000/秒;详见 [应用共享配额](application-resources.md)。
|
||
|
||
P3 独立任务核查、人工重试和操作审计分别增加 `tasks:review`、`tasks:retry`、`tasks:audit:read`,bootstrap显式 `--recovery-access` 才授予三项;默认凭据和 `--worker-access` 都不自动获得。核查/重试记录真实认证凭据及证据,读取任务详情仍需tasks:read,见[人工恢复](task-recovery.md)。
|
||
|
||
P3 结果订阅核心新增 `events:read`、`events:manage` 和 `events:consume`,bootstrap 仅显式 `--event-access` 时授予。订阅绑定创建凭据与单个队列,不能用同命名空间的另一张凭据消费或管理。当前 HTTP/WSS、管理及消费 SDK 已接入;凭据重绑继续开发,详见 [订阅接口](subscriptions.md)。
|
||
|
||
P4定义发布新增`workflows:definitions:read`与`workflows:definitions:publish`,仅显式`--workflow-access`授予。创建/读取元数据作用于命名空间,发布及读取完整版本额外校验全部引用队列;默认提交/Worker凭据不获此权限。发布不创建任务,不要求tasks:submit,详见[定义API](workflow-definitions.md)。
|
||
|
||
P4/P5实例公共接入增加`workflows:start/read/control/signal/recover`及`workflows:audit:read`。五个独立CLI开关`--workflow-run-access`、`--workflow-control-access`、`--workflow-signal-access`、`--workflow-recovery-access`、`--workflow-audit-access`分别明确授予。前四个同时包含实例读取;audit只授予流程操作审计读取。原`--workflow-access`仍仅授予定义读/发布,任务`--recovery-access`不授予流程恢复。全部固定队列仍按当前凭据校验,详见[实例权限表](workflows.md#1-路由权限与-sdk)。初始化权限集合在交付凭据前校验。
|