传统M2M通信依赖长期有效的client_secret,存在硬编码泄露、轮换困难及权限粒度过粗等安全风险。为消除此类隐患,本方案利用ECS实例的PKCS#7格式身份签名作为动态联邦凭证,通过IDaaS验证后换取短期有效的AccessToken,并进一步获取RAM STS Token,从而彻底避免在ECS中存储任何静态密钥。
适用范围
IDaaS实例:已开启M2M管理, 并剩余可添加应用数不小于2(本文案需新增两个M2M应用)。
网络环境:ECS实例可访问EIAM实例的公网域名(
https://<实例ID>.aliyunidaas.com)。账号权限:具备RAM主账号或RAM管理员权限。
方案背景
在传统的机器间(M2M)通信中,应用程序通常需要持有 client_id 和 client_secret 来向身份提供商申请 Access Token。然而,client_secret 作为长期有效的静态凭据,存在以下安全风险:
泄露风险:密钥常被硬编码在代码、配置文件或环境变量中,易通过源码泄露或日志记录被窃取。
轮换困难:手动轮换密钥流程复杂,且容易导致业务中断。
权限管理粒度粗:难以针对特定的物理实例进行细粒度的访问控制。
本方案利用阿里云 ECS 的实例标识(PKCS#7 签名格式)作为联邦认证凭证。ECS 实例在运行时动态获取包含自身身份信息的签名,IDaaS 通过预信任的阿里云根证书验证该签名的合法性。整个过程无需在 ECS 实例中存储任何静态密钥,实现了更高安全等级的无凭据访问。
方案架构
本方案整合了云服务器 ECS、EIAM 云身份服务和访问控制 RAM,通过 OIDC (OpenID Connect) 协议建立信任链,实现免密认证。
核心工作流程如下:
获取实例身份签名:部署在 ECS 实例上的业务应用,向 ECS 元数据服务请求一个基于 PKCS#7 格式的实例标识签名。此签名包含了实例的身份信息,并由阿里云官方根证书签发,具备权威性和不可伪造性。
换取 EIAM AccessToken:应用将此 PKCS#7 签名作为客户端断言(
client_assertion),向 EIAM 的令牌端点请求 AccessToken。EIAM 通过预置的联邦信任源(信任阿里云根证书)验证该签名的有效性。验证通过后,EIAM 颁发一个与特定 M2M 应用关联的、有时效性的 AccessToken。换取 RAM STS Token:应用携带上一步获取的 EIAM AccessToken,调用 RAM 的
AssumeRoleWithOIDC接口。RAM 会验证此 AccessToken 的合法性(通过其预配置的 OIDC 身份提供商),并检查其声明(Claims)是否满足角色信任策略中定义的条件。访问云资源:验证通过后,RAM 颁发一个有时效性的 STS Token(包含
AccessKeyId、AccessKeySecret和SecurityToken)。应用最终使用此 STS Token 安全地调用其他阿里云服务的 API。
关键组件角色:
云服务器 ECS:作为可信的计算环境,提供动态生成实例身份签名的能力。
EIAM 云身份服务 (IDaaS):作为联邦身份提供商。
M2M Client 应用:代表 ECS 实例上的应用发起认证请求。
M2M Server 应用:作为 OIDC Provider,定义了颁发给 RAM 的 AccessToken 的受众和范围。
访问控制 RAM:作为服务提供方,建立对 EIAM 的 OIDC 信任,并根据角色信任策略颁发最终的 STS Token。
步骤一:在EIAM中配置联邦信任源与M2M应用
此步骤在 EIAM 中创建联邦信任源和两个 M2M 应用,用于建立对 ECS 实例身份的信任,并为后续的 OIDC 联邦做准备。
创建PKCS#7联邦信任源
此信任源用于让 EIAM 能够验证来自 ECS 实例的 PKCS#7 身份签名。
登录IDaaS管理控制台,在顶部切换至目标地域。在左侧导航栏中,选择EIAM 云身份服务。
在页面右侧区域,定位目标EIAM实例,单击操作列下的访问控制台,进入该实例的管理后台。
在EIAM实例管理后台的左侧菜单栏,单击登录,随后单击。
在弹出的面板中选择PKCS#7并单击下一步。设置如下信息后,单击确定。更多信息请参见联邦信任源管理。
配置项
说明
示例值
联邦信任源名称
自定义联邦信任源名称。
test-ecs-credential-source
信任来源
选择信息来源。本方案选择阿里云。
阿里云
填写验签证书
单击获取云厂商证书,即可完成验签证书和云账户 ID的自动填写。
-
创建M2M Client应用
此应用代表 ECS 实例上的业务程序,用于发起认证请求。
在EIAM实例管理后台的左侧菜单栏,选择。
单击添加应用,设置应用名称为“M2M Client”,单击立即添加,进入应用详情页。
在客户端权限管理页签下,打开自定义权限开关。
在通用配置页签下,单击。设置如下信息后,单击确定。更多信息请参见创建联邦凭证。
配置项
说明
示例值
联邦信任源
指定前面步骤创建的联邦信任源。
test-ecs-credential-source
联邦凭证名称
自定义联邦凭证名称。
test-ecs-credential
校验条件模式
本方案指定为指定云服务器实例模式。
指定云服务器实例模式
云服务器实例ID
指定已有的云服务器ECS实例ID,通过单击右侧的
,可填写多个。i-bp1******wfkx
创建M2M Server应用
此应用作为 OIDC Provider,定义了颁发给 RAM 的 AccessToken 的受众(aud)和范围(scope)。
在EIAM实例管理后台的左侧菜单栏,选择。
单击添加应用,设置应用名称为“M2M Server”,单击立即添加,进入应用详情页。
在服务端权限开放页签下,单击权限应用下的服务端权限开放开关,在弹出的面板中,设置受众标识后,单击确定。
说明受众标识建议设置为:
cloud:idaas:sts:alibabacloud:<account-id>。其中<account-id>需替换为当前的阿里云主账号 ID。单击,设置如下信息后,单击确定。
权限名称:自定义权限名称,如:
assume-role。权限标识:自定义权限标识,建设设置为:
role:assume。
在授权应用下开启M2M客户端开关,并在权限列表中勾选选择上一步添加的权限(如:
assume-role),单击确定。
步骤二:在 RAM 中建立对 EIAM 的信任
此步骤在 RAM 中创建一个 OIDC 身份提供商和一个可信实体为该提供商的 RAM 角色。
创建OIDC身份提供商
进入RAM控制台的OIDC配置页面,单击创建身份提供商。
在创建身份提供商页面,设置如下信息后,单击创建身份提供商。更多信息请参见管理OIDC身份提供商。
配置项
说明
示例值
身份提供商名称
同一个阿里云账号下必须唯一。
test-oidc-provider
颁发者URL
进入M2M 应用(Server)详情页,复制下 Issuer 处显示的URL,并填写至此处。
https://8******n.aliyunidaas.com/api/v2/iauths_system/oauth2
验证指纹
填写完颁发者URL后,可单击获取指纹,阿里云将自动计算出验证指纹并显示。
-
客户端ID
进入M2M 应用(Server)详情页,复制处的值,并填写至此处。
cloud:idaas:sts:alibabacloud:13******76
创建RAM角色
进入RAM控制台的角色页面,单击创建角色。创建OIDC身份提供商的RAM角色
在创建角色页面的右上角,单击切换编辑器并选择可视化编辑模式。
设置主体。
选择身份提供商。
单击身份提供商下方的编辑。随后,在弹出的添加主体面板,设置身份提供商类型为OIDC,身份提供商为前一步骤创建的OIDC身份提供商(例如:
test-oidc-provider),最后单击确定。
设置限制条件。
单击添加条件,设置条件键为
oidc:sub、运算符为StringEquals、条件值为“M2M Client”应用的 client_id,最后单击确定。说明在M2M Client 应用详情页面的,即可查看client_id。
单击页面底部的确定,在弹出的面板中设置角色名称后,单击确定。
在角色详情页面,单击,根据需求设置权限策略(例如:
AliyunOSSReadOnlyAccess),最后单击确认新增授权。
步骤三:在 ECS 实例中获取 EIAM AccessToken
此步骤在 ECS 实例内部执行,通过脚本获取实例身份签名,并用它换取 EIAM AccessToken。
获取ECS实例标识签名
本示例以Linux操作系统为例。
登录目标服务器ECS。详情可参考选择ECS远程连接方式。
在服务器终端中执行以下脚本,最终输出的结果字符串即为ECS实例标识签名。更多信息可参见获取实例标识文档/签名。
# 请替换以下的<IDaaS 实例 ID>为当前IDaaS 实例 ID,如:idaas_xxx IDAAS_INSTANCE_ID="<IDaaS 实例 ID>" # 1. 获取ECS访问凭证,需设置有效期,不可包含标头X-Forwarded-For TOKEN=$(curl -s -X PUT "http://100.100.100.200/latest/api/token" -H "X-aliyun-ecs-metadata-token-ttl-seconds:1200") # 2. 构造完整的 URL(注意:audience参数的值是 URL 编码后的 JSON 字符串) # 获取当前时间戳(秒级) SIGNING_TIME=$(date +%s) URL="http://100.100.100.200/latest/dynamic/instance-identity/pkcs7?audience=%7B%22aud%22%3A%22$IDAAS_INSTANCE_ID%22%2C%22signingTime%22%3A$SIGNING_TIME%7D" # 3. 获取ECS实例标识签名 curl -s -w '\n' -H "X-aliyun-ecs-metadata-token: $TOKEN" "$URL"audience 参数的生成规则:
获取ECS实例标识签名时,请求参数必须包含
audience字段,其取值需按以下流程生成。构造
audience的原始内容,格式为 JSON 字符串,字段说明如下:aud:固定为 IDaaS 实例 ID。signingTime:生成签名时的 Unix 时间戳(秒)。
# URIEncode 前(JSON 字符串) {"aud":"idaas_xxx","signingTime":1750131608}对上述 JSON 字符串进行 URIEncode 编码,编码结果作为
audience的最终取值。# URIEncode 后(作为 audience 参数值) %7B%22aud%22%3A%22idaas_xxx%22%2C%22signingTime%22%3A1750131608%7D
获取M2M AccessToken
正确设置以下脚本中的变量和参数后,在服务器终端中执行。更多信息可参见PKCS#7 签名认证。
curl -s --request POST \
--url '<M2M应用(Client)的令牌端点>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=app_xxx' \
--data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer' \
--data-urlencode 'client_assertion=xxx' \
--data-urlencode 'scope=xxx|xxx' \
--data-urlencode 'application_federated_credential_name=xxx'<M2M应用(Client)的令牌端点>
进入M2M应用(Client)详情页,在处,即可查看令牌端点的URL地址。例如:
https://8******n.aliyunidaas.com/api/v2/iauths_system/oauth2/token。请求参数
参数
说明
grant_type
固定值为:
client_credentials。client_id
M2M应用(Client)的应用ID。例如:
app_nfb******dzq。进入M2M应用(Client)的详情页,在处,即可查看。
client_assertion_type
固定值为:
urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer。client_assertion
上一步获取的ECS实例标识签名。
scope
格式:
M2M应用(Server)的受众标识|M2M应用(Server)的权限标识。例如:
cloud:idaas:sts:alibabacloud:62******39|role:assume。application_federated_credential_name
M2M应用(Client)的联邦凭证名称。例如:
test-ecs-credential。响应结果
{ "token_type": "Bearer", "access_token": "eyJraQ******E13GvA", "expires_in": 3600, "expires_at": 1766063256 }参数
说明
token_type
固定值为
Bearer。access_token
IDaaS EIAM签发的AccessToken,后续业务可根据此Token获取RAM的STS Token。
expires_in
access_token的有效时长,单位为秒。expires_at
access_token的过期时间(Unix时间戳),单位为秒。
步骤四:使用 AccessToken 换取 RAM STS Token
通过调用 RAM 接口
AssumeRoleWithOIDC获取扮演角色的临时身份凭证(STS Token)。详情请参见获取扮演角色的临时身份凭证。可使用 OpenAPI Explorer 调试该接口,调试成功后可自动生成 SDK 代码示例。请求参数
名称
描述
示例值
OIDCProviderArn
前面步骤创建的OIDC 身份提供商的 ARN,请参见查看OIDC身份提供商信息。
acs:ram::13******76:oidc-provider/test-idaas-providerRoleArn
前面步骤创建的角色的ARN。请参见如何查看RAM角色的ARN。
acs:ram::13******76:role/test-idaas-roleOIDCToken
在获取M2M AccessToken步骤中得到的
access_token。eyJraQ******E13GvARoleSessionName
自定义会话名称。
TestSession
响应参数
在响应结果中,
SecurityToken、AccessKeyId、AccessKeySecret即为获取的STS Token。示例如下:{ "RequestId": "9518******49FB", "OIDCTokenInfo": { "Issuer": "https://******.aliyunidaas.com/api/v2/iauths_system/oauth2", "IssuanceTime": "2025-12-18T13:52:35Z", "VerificationInfo": "Success", "ExpirationTime": "2025-12-18T14:52:35Z", "Subject": "app_nfb******dzq", "ClientIds": "cloud:idaas:sts:alibabacloud:13******76" }, "AssumedRoleUser": { "Arn": "acs:ram::13******76:role/test-idaas-role/TestSession", "AssumedRoleId": "300******402:TestSession" }, "Credentials": { "SecurityToken": "CAISyg******d5diAA", "AccessKeyId": "STS.NXYh******A5R", "AccessKeySecret": "FpdgA******2eoN", "Expiration": "2025-12-18T15:20:33Z" } }
通过STS Token调用云产品API。
调用API时,必须同时传递三个参数(
SecurityToken、AccessKeyId、AccessKeySecret)。若使用STS类型的AccessKey ID但未携带SecurityToken,请求将因认证失败而被拒绝。目标 API 必须包含在目标角色(前面步骤创建的角色)的权限策略授权范围内,否则请求将被拒绝。
例如:在创建RAM角色时,若已为角色添加
AliyunOSSReadOnlyAccess权限策略,则此时可使用STS Token调用OSS的所有读操作的API。REST API:需在请求中包含
security-token参数(URL签名)或x-oss-security-token请求头(Header签名)。OSS SDK:需在初始化客户端时显式传入SecurityToken(如Java SDK中
DefaultCredentialProvider的securityToken参数)。
应用于生产环境
将此方案应用于生产环境时,请重点关注成本、可用性和风险防范。
最佳实践:
凭证管理:切勿将脚本中的
client_id等敏感信息硬编码在代码中。建议使用配置中心(如 Nacos)或环境变量进行管理。Token 缓存:为降低延迟和减少 API 调用次数,应用程序应在内存中缓存获取的 AccessToken 和 STS Token。
Token 刷新:建议在 Token 有效期剩余 10% 或一个固定的时间窗口(例如 5 分钟)时进行异步刷新,避免服务因 Token 过期而中断。
并发控制:在多线程或多实例环境中,应使用锁机制来避免在 Token 即将过期时多个进程或线程并发刷新,导致对 EIAM 和 RAM 服务造成不必要的压力。
风险防范:
网络依赖:本方案要求 ECS 实例能够访问 EIAM 的公网接口。若 ECS 处于无公网出口的 VPC 中,此方案将不可用。
配置风险:方案涉及 ECS、EIAM、RAM 三个产品的联动配置,环节较多,需要精确匹配各组件的 ID、URL 和 ARN。配置错误可能导致认证失败。
计费说明
EIAM 云身份服务:使用本方案需要购买 EIAM 实例,并确保 M2M 应用配额充足(至少需要 2 个)。具体费用请参考M2M应用计费说明。
其他云服务:通过 STS Token 访问其他云服务(如 OSS、SLS)时,将按各服务的标准计费。
常见问题
获取M2M AccessToken时,脚本执行失败
请按以下步骤检查:
网络连通性:在 ECS 实例上执行
curl -v https://<EIAM 实例 ID>.aliyunidaas.com,检查是否能成功访问 EIAM 的公网域名。元数据服务:执行
curl http://100.100.100.200/latest/meta-data/,检查实例元数据服务是否可访问。脚本变量:仔细核对脚本中的
IDAAS_INSTANCE_ID、TOKEN_ENDPOINT、CLIENT_ID等变量是否填写正确。ECS 实例授权:检查 EIAM 的 M2M Client 应用中配置的“云服务器实例ID”是否为当前执行脚本的 ECS 实例的 ID。
获取M2M AccessToken 时,EIAM 返回 invalid_scope 错误
这是因为 scope 参数格式不正确,请进行如下检查:
检查分隔符:EIAM 要求
scope参数中的多个值使用竖线|分隔,而非 OAuth 2.0 标准的空格。请确保格式为<M2M Server的受众标识>|<M2M Server的权限标识>。检查授权:确认 M2M Client 应用是否已在 M2M Server 应用的“授权应用”页签中被授权,并勾选了相应权限。
调用 AssumeRoleWithOIDC 时,RAM 返回 InvalidIdentityToken 错误
通常由 OIDC 身份提供商的配置与 EIAM 应用配置不匹配导致。请务必确保 RAM OIDC 身份提供商的“颁发者URL”和“客户端ID”与 EIAM M2M Server 应用的“颁发者 URL”和“受众标识”完全一致。
调用 AssumeRoleWithOIDC 时,RAM 返回 AccessDenied 错误
这表示 RAM 角色信任策略的条件不满足,请进行如下检查:
检查
oidc:sub:确认 RAM 角色信任策略Condition中的oidc:sub值是否为 EIAM M2M Client 应用的client_id。此处极易误填为 Server 应用的 ID。检查
oidc:aud:确认Condition中的oidc:aud值是否与 RAM OIDC 身份提供商的“客户端ID”一致。