华为云作品展览馆发布实战:STS 自委托与五道发布门禁

举报
yd_296261293 发表于 2026/11/03 11:03:18 2026/11/03
【摘要】 复盘华为云作品展览馆发布全链路:为什么发布接口只认 900 秒 STS 临时凭证、如何用 IAM 自委托生成、五道本地发布门禁各挡什么坑,附真实命令、返回码与作品 ID。

华为云作品展览馆发布实战:STS 自委托与五道发布门禁

引子

最近要把一个作品发布到「华为云开发者作品展览馆」。看起来只是"上传一个 zip",实际走通之后才发现,平台设计了一套相当严谨的链路:

身份校验靠 STS 临时凭证 + 自委托,内容审核靠五道本地门禁。

这篇文章把这套流程完整拆开复盘,包括每一步的真实命令、每道门禁的作用,以及几个必须踩过才知道的坑。

一、为什么不能直接用 AK/SK 发布?

发布接口是:

POST /open-api-public/v1/gallery/works

但它不接受你的永久 AK/SK,而是要求请求头携带:

X-Tmp-Ak / X-Tmp-Sk / X-Security-Token

也就是临时凭证(STS),且必须由 IAM 自委托(SELF_VERIFY) 生成。网关会用这份临时凭证调用 STS.GetCallerIdentity 解析账号(Domain)ID,校验通过后再注入 X-Domain-Id 供服务端记录作者。

这样设计的好处很清楚:

  • 永久 AK/SK 不需要出现在任何请求里;
  • 临时凭证 900 秒过期,泄露面极小;
  • 服务端能确认"调用者确实是该 Domain"。

二、四步生成可用的 STS

1. 配置 hcloud 凭证

npx huaweicloud-devkit auth init

它会提示两种方式:交互终端输入,或设置 HW_ACCESS_KEY/HW_SECRET_KEY 环境变量。前者适合本机,后者适合非交互环境。

2. 解析 Domain ID

resolve-domain.mjs --hcloud /root/.local/bin/hcloud
# 输出:#domain=4c39fe5b... name=hw030690224

3. 生成 STS(900 秒有效)

gen_sts.py --account 4c39fe5b... --hcloud /root/.local/bin/hcloud \
           --creds-out ./sts-creds.json --sh-out ./sts-creds.sh

产物 sts-creds.json 里除了 AK/SK/Token,还有一个关键的 _refresh 字段:

{"accountId":"...","agencyUrn":"iam::...:agency:SELF_VERIFY","region":"cn-north-4"}

有了它,后续接口返回 401 时可以自动刷新,不必手动重跑。

4. 验证 STS

api.mjs GET /v1/gallery/camps --creds-file ./sts-creds.json
# #status=200

三、五道发布门禁

真正的发布脚本在发请求前会本地复检五道门禁,任何一道不过就拒绝发布:

门禁 检查内容 失败后果
preflight Python 依赖 + Chromium + CJK 字体 无法截图/生成封面
ensure-utf8 项目文件编码是否为 UTF-8 中文乱码
screenshot-guard 截图产物是否存在且可用 封面空白
封面校验 产物存在 + 16:9 比例 展示变形
详情包校验 zip 存在 + README 在根目录 详情页空白

其中最容易被忽略的是 ensure-utf8——我第一次发布就卡在这里:

✖ [ensure-utf8] 标记文件不存在: /tmp/utf8-gate-ok
❌ 1 个门禁未通过 — 禁止发布。

补跑一次编码检查后才通过:

ensure-utf8.mjs /path/to/project
# ✅ 编码门禁通过(检查 1 个文件,UTF-8 保留 1,自动修正 0)

教训一:门禁是"标记文件"驱动的。少了某个标记,不是"没检查",而是"没通过"。

四、发布参数与结果

参数 JSON 的必填项:

{
  "idempotencyKey": "gallery-publish-<domainID>-<timestamp>",
  "accessKeyId": "<STS AK>",
  "secretAccessKey": "<STS SK>",
  "securityToken": "<STS Token>",
  "trainingCampId": "<活动 ID>",
  "workName": "<作品名>",
  "introduction": "<15~50 字符简介>",
  "coverImage": "<封面 PNG 绝对路径>",
  "detailZip": "<详情 zip 绝对路径>",
  "gitUrl": "<https://... .git>",
  "gitBranch": "<分支>",
  "envUrl": ""
}

注意两个细节:

  1. 字段名是 coverImage / detailZip,不是 coverImagePath / detailsZipPath——脚本会对未知 key 直接报错拦截;
  2. introduction 有严格的 15~50 字符限制(中英文、标点都算)。我写的简介是 42 字符,正好合格。

提交成功返回:

#status=201
workId=007809cb69c00000
workUrl=https://gallery.developer.huaweicloud.com/gallery/007809cb69c00000
reward=success value=200

作品页可以公开访问,作者、活动、简介、详情全部正确显示。

五、几个实战坑

坑 1:hcloud 不在 PATH

auth sync 报 KooCLI current profile unresolved,原因是 hcloud 未安装。装上后必须先接受隐私协议(非交互环境用 echo y |),否则命令直接报 Invalid character。

坑 2:region 必须显式给

auth_switch(mode=import) 如果 creds-import.json 里没有 region,会直接报错:

invalid_region: region is required to persist credentials

坑 3:封面生成是"阻塞 + 耗时"的

build-cover.mjs 会真的启动浏览器、打开页面、截图、合成,单次约 60~120 秒。preflight 首次还要下载字体与 Chromium,可能 5~10 分钟。必须给足超时。

坑 4:Git 信息要"核对远端分支"

read-git-info.mjs 不只是读本地配置,还会 git ls-remote 核对分支是否真实存在——这避免了"提交到不存在的分支"这种低级失败。

六、小结

这套发布流程的设计思路值得借鉴:

  1. 最小权限:用 900 秒的 STS 替代永久 AK/SK,且由自委托生成;
  2. 本地门禁前置:五道检查在发请求之前完成,避免"传上去才发现封面不对";
  3. 幂等键:idempotencyKey 防止重试导致重复发布;
  4. 产物即证据:门禁检查的是真实文件(字体渲染、比例、zip 结构),而不是"你声称做了"。

把这套链路跑通一次之后,后续作品发布就变成了可重复、可校验的工程动作,而不是"玄学上传"。

本文基于本人在华为云开发者作品展览馆的真实发布记录整理,命令、门禁名称、返回码与作品 ID 均来自实际执行,纯原创,欢迎交流。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。