用 IAM 自委托换 STS 临时凭证:给开放 API 做最小权限鉴权的完整落地
第三方开放平台如果要求调用方带着"临时凭证"来,而不是让你把永久 AK/SK 塞进请求头,那基本就是让你走 STS 这条路。最近在对接一个华为云开放 API 时把这条链路完整跑通了,记下来,包括几个文档里不太显眼的坑。
## 为什么不能直接用永久 AK/SK
永久访问密钥的问题很直接:它有账号级的全部资源权限,不受授权策略限制,一旦泄露就是灾难。开放平台要求"最小权限 STS 临时凭证",本质上是要求调用方先自己缩权,再拿一个有存活期的凭证过来。
华为云的做法是 `STS AssumeAgency`:你创建一个委托(agency),把你自己的权限"委托"给这个委托身份,然后扮演它换取临时凭证。如果只是自用、不需要跨账号,就建一个信任方指向自己的"自委托"。
## 第一步:建自委托
用 KooCLI 建委托,关键参数是信任的域。自委托就是让 trust_domain 指向自己:
```bash
hcloud IAM CreateAgency \
--cli-region=cn-north-4 \
--agency.name=SELF_VERIFY \
--agency.domain_id=<你的账号 Domain ID> \
--agency.trust_domain_name=<你的账号 Domain Name> \
--agency.duration=1
```
返回里会带 `agency_urn`,形如:
```
iam:::agency:SELF_VERIFY
```
`duration` 单位是天,写 1 就是 24 小时,到期自动失效,不用手动回收。
这里第一个坑:**`trust_domain_name` 填的是账号名,不是 IAM 用户名**。填错会报 `invalid trust domain`,看不出具体是哪个字段错了。
## 第二步:换临时凭证
```bash
hcloud STS AssumeAgency \
--cli-region=cn-north-4 \
--agency_urn=iam:::agency:SELF_VERIFY \
--agency_session_name=myjob \
--duration_seconds=3600
```
返回结构:
```json
{
"assumed_agency": { "urn": "sts:::assumed-agency:SELF_VERIFY/myjob" },
"credentials": {
"access_key_id": "HSTA...",
"secret_access_key": "...",
"security_token": "hQpjbi1ub3J0aC00...",
"expiration": "2026-10-21T19:05:40.752Z"
}
}
```
三件套到手:临时 AK、临时 SK、SecurityToken。注意 `expiration` 是 UTC,换算本地时间别算错,我一开始按本地时间理解,差点以为只有几分钟可用。
## 第三步:调用方怎么用
开放 API 一般要三个头:
```
X-Tmp-Ak:
X-Tmp-Sk:
X-Security-Token:
```
实测把这三个头带上去,鉴权环节就直接过了。
## 踩到的三个坑
**坑一:`securitytokens` 接口不支持 `hw_ak_sk` 方式。**
我最初的思路是不签名,直接把 AK/SK 放进 body:
```json
{"auth":{"identity":{"methods":["hw_ak_sk"],
"hw_ak_sk":{"access":{"key":"..."},"secret":{"key":"..."}}}}}
```
这是华为云另一种临时凭证接口的用法,但那个接口不支持这个 method,直接返回:
```
400 {"error":{"code":400,"message":"Unsupported method:[\"hw_ak_sk\"]"}}
```
换成 KooCLI 由它自动签名才走通。所以别想着绕开签名,老老实实用 SDK/CLI。
**坑二:KooCLI 只配环境变量不够。**
只设 `HUAWEICLOUD_SDK_AK` / `HUAWEICLOUD_SDK_SK` 会报:
```
[USE_ERROR]配置文件中不存在配置项,请您执行`hcloud configure set`添加配置项
```
必须落一个配置项。但直接改默认 profile 会覆盖掉机器上原有的账号配置,正确做法是建独立 profile:
```bash
hcloud configure set --profile=tmpjob \
--cli-access-key=... --cli-secret-key=... --cli-region=cn-north-4
hcloud STS AssumeAgency --cli-profile=tmpjob ...
```
用完 `hcloud configure delete --profile=tmpjob` 删掉,不污染原有环境。
**坑三:平台还会校验业务侧白名单。**
拿到 STS 只代表"鉴权通过"。我对接的那个发布接口还额外校验了提交内容里的仓库域名——只认固定的几个代码托管域名,自建托管的仓库即使公网可克隆也一律拒收:
```
400 {"code":"XXX.GIT_URL_DOMAIN_FORBIDDEN",
"reason":"authorized: xxx.com, yyy.com, ..."}
```
这类校验在鉴权之后,所以别把"鉴权过了"当成"请求能过"。调之前先把业务字段的合法取值范围摸清楚,比调一次报错改一次省时间。
## 用完记得清
临时凭证 1 小时自动失效不用管,但自委托是持久对象,用完该删:
```bash
hcloud IAM DeleteAgency --cli-profile=tmpjob \
--agency_uri=iam:::agency:SELF_VERIFY
```
顺手把临时 profile 也删掉。这两步不做,账号里就多留了一份长期可用的提权路径——虽然它只信任你自己,但审计上是多余的。
## 小结
整条链路就三步:建自委托 → AssumeAgency 换三件套 → 带上三个头调用。坑都在细节里:trust_domain 填账号名、KooCLI 必须落配置项且要用独立 profile、鉴权通过不等于业务校验通过、用完要回收持久对象。
- 点赞
- 收藏
- 关注作者
评论(0)