使用访问凭据访问阿里云OpenAPI最佳实践

更新时间:

访问凭据一旦发生泄露,会给云上资源和用户业务带来很大的安全隐患。本文为您介绍如何在不同的场景中安全使用访问凭据访问阿里云OpenAPI。

什么是访问凭据

访问凭据是指用户证明其身份的一组信息。用户通过开发工具(API、CLI、SDK、Terraform等)访问阿里云时,需要提供正确的访问凭据才能验证身份。常见的访问凭据类型:

  • AccessKey:访问密钥AccessKey(简称AK)是阿里云提供给阿里云账号(主账号)和RAM用户(子账号)的永久访问凭据,一组由AccessKey ID和AccessKey Secret组成的密钥对。更多信息,请参见创建AccessKey

  • STS Token:安全令牌(STS Token)是阿里云提供给RAM角色的临时访问凭据,可以自定义时效和访问权限。更多信息,请参见什么是STS

常见的访问凭据泄露案例

  • 开发者直接将AK硬编码在业务代码中,有代码仓库阅读权限的开发者均能获取到AK信息。开发者直接将业务代码上传到开源社区或代码托管服务,导致AK的进一步泄露。

  • 用户为了能够让自己的客户端直接调用到OpenAPI,将AK写到客户端代码中。攻击者通过反编译客户端代码,获取到AK信息。

  • 开发者的技术文档或者分享材料中包含AK信息。

  • 产品说明文档中包含的样例代码含有AK信息。

  • 用户无权限控制的接口中返回了访问凭据信息。

访问凭据的安全使用方案

访问凭据的安全使用方案的主要思路:降低访问凭据的暴露时间和暴露范围。常见场景的访问凭据安全使用方案如下表所示。

方案名称

适用场景

容器实例角色扮演

如果您的应用程序部署在阿里云ACK容器集群上,则可以基于RRSA(RAM Roles for Service Accounts)功能,在容器集群内实现应用隔离的RAM角色功能,各个应用可以扮演独立的RAM角色,访问阿里云OpenAPI。

ECS实例角色扮演

如果您的应用程序部署在阿里云ECS实例上,则可以通过ECS实例RAM(Resource Access Management)角色让ECS实例扮演具有某些权限的角色,访问阿里云OpenAPI。

员工使用STS Token进行开发调试

针对研发、运维、产品等职能员工,需要使用AccessKey进行运维、管理、调试等操作,建议通过角色SSO的方式,扮演其对应职能的RAM角色,获取STS Token。

函数计算使用STS Token

如果您在函数计算(FC)上部署的应用程序需要访问其他云资源,则可以通过函数计算RAM角色将FC函数和RAM角色关联,使用STS Token(Security Token Service)访问云资源,解决永久凭据可能导致的安全风险问题。

配置系统环境变量

对于不适用以上方案的场景,建议您使用配置系统环境变量的方式,访问阿里云OpenAPI。

容器实例角色扮演

前提条件

  • 适用于支持RAM的云服务

  • RRSA功能目前仅支持1.22及以上版本的集群,即ACK集群基础版ACK集群Pro版ACK Serverless集群基础版ACK Serverless集群Pro版

  • 使用V2.0版本的阿里云SDK。

  • 自建网关类产品的自研SDK无法使用。

原理介绍

基于RRSA功能,您可以在集群内实现Pod级别隔离的应用关联RAM角色功能。各个应用可以扮演独立的RAM角色并使用获取的临时凭证访问云资源,从而实现应用RAM权限最小化以及无AccessKey访问阿里云OpenAPI避免AccessKey泄露的需求。

3

从用户侧视角来看,RRSA功能的工作流程如下。

  1. 用户提交使用了服务账户令牌卷投影功能的应用Pod。

  2. 集群将为该应用Pod创建和挂载相应的服务账户OIDC Token文件。

  3. Pod内程序使用挂载的OIDC Token文件访问STS服务的AssumeRoleWithOIDC接口,获取扮演指定RAM角色的临时凭证。

    说明
    • 请提前修改RAM角色配置,允许Pod使用的服务账户扮演该RAM角色。更多信息,请参见AssumeRoleWithOIDC

    • 从文件中读取的OIDC Token是一个临时Token,建议应用程序每次在使用时都从文件中读取最新的Token,集群会在Token过期前更新替换文件内已有的Token。

  4. Pod内程序使用获取到的临时凭证访问云资源OpenAPI。

配置方法

代码示例

目前,阿里云V2.0 SDK已经内置了支持使用RRSA OIDC Token进行OpenAPI认证的功能,所有基于V2.0 SDK生成并且支持STS Token认证的云产品SDK都将默认支持RRSA OIDC Token认证。支持此功能的SDK版本信息和参考代码如下。

编程语言

支持认证的SDK版本

使用示例

Go

Alibaba Cloud Credentials for Go 1.2.6及以上版本。更多信息,请参考方式六:使用OIDCRoleArn

Go SDK使用示例

Java

Alibaba Cloud Credentials for Java 0.2.10及以上版本。更多信息,请参考方式六:使用OIDCRoleArn

Java SDK使用示例

Python 3

Alibaba Cloud Credentials for Python 0.3.1及以上版本。更多信息,请参考方式六:使用OIDCRoleArn

Python 3 SDK使用示例

Node.js和TypeScript

Alibaba Cloud Credentials for TypeScript/Node.js 2.2.6及以上版本。更多信息,请参考方式六:使用OIDCRoleArn

Node.js和TypeScript使用示例

ECS实例角色扮演

前提条件

  • 适用于支持阿里云RAM的云服务

  • 使用V2.0版本的阿里云SDK。

  • 自建网关类产品的自研SDK无法使用。

原理介绍

实例RAM角色允许您将一个角色关联到ECS实例,在ECS实例内部基于STS(Security Token Service)临时凭证访问其他云产品的API,临时凭证将周期性更新。既可以保证云账号AccessKey的安全性,也可以借助访问控制RAM实现精细化控制和权限管理。

1

工作流程如下:

  1. 应用程序访问ECS实例元数据获取STS临时凭证。详细信息,请参见ECS实例元数据概述

  2. 使用STS临时凭证访问云资源。详细信息,请参见什么是STS

配置方法

为ECS实例授予RAM角色。详细信息,请参见通过ECS实例RAM角色授权ECS访问其他云服务

示例代码

Alibaba Cloud Credentials是阿里云为阿里云开发者用户提供身份凭证管理工具,使用Credentials工具可以为您提供更加便捷的方式使用ECS实例角色扮演功能,以调用云服务器ECS的DescribeRegions接口为例,参考代码如下。

编程语言

使用示例

Go

Go语言代码示例

Java

Java语言代码示例

Python

Python语言代码示例

PHP

PHP语言代码示例

Node.js

Node.js语言代码示例

.NET

.NET语言代码示例

员工使用STS Token进行开发调试

场景描述

针对研发、运维、产品等职能员工,需要使用AccessKey进行运维、管理、调试等操作,建议通过角色SSO的方式,扮演其对应职能的RAM角色,获取STS Token。

配置方法

函数计算使用STS Token

场景描述

客户在FC函数上部署的应用程序需要访问其他云资源,传统的方式是客户将RAM用户的AK(Access Key)固化在函数中,如果将AK写在配置文件中,容易造成AK泄露,维护困难等问题。FC函数RAM角色通过将FC函数和RAM角色关联,使用STS Token(Security Token Service)访问云资源,解决永久凭证可能导致的安全风险问题。

方案架构

本方案通过FC函数角色实现临时凭证的获取和使用。该架构和流程通过动态管理和临时授予访问权限,避免了长期暴露AK的风险,提高了系统的安全性和灵活性。管理员仅需一次性配置角色和权限,后续函数在运行时即可动态获取和使用临时凭证,简化了运维管理工作。

管理员创建一个受信给函数计算的Role(角色),并对该角色授予相应的权限。角色权限包含访问需要的云资源的权限(图中1)。管理员将创建好的角色配置到对应的FC函数上,使函数与角色关联(图中2)。客户应用程序从函数上下文中获取临时安全凭证(STS Token)(图中3),该过程中函数计算会使用云服务的身份调用AssumeRole接口,从RAM/STS服务获取STS Token(图中i)。 客户应用程序使用获取到的STS Token来调用目标云资源服务的API(图中4)。资源服务API处理请求并返回访问结果,客户端应用程序接收到返回的结果后完成相应的业务逻辑。

image

配置方法

具体操作,请参见通过FC函数角色实现临时凭证的获取和使用

配置系统环境变量

配置方法

配置环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET

  • Linux和macOS系统配置方法

    执行以下命令:

    export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>

    <access_key_id>需替换为已准备好的AccessKey ID,<access_key_secret>替换为AccessKey Secret。

  • Windows系统配置方法

    1. 新建环境变量文件,添加环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET,并写入已准备好的AccessKey ID和AccessKey Secret。

    2. 重启Windows系统。

阿里云SDK代码示例

阿里云SDK支持通过定义ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET环境变量来创建默认的访问凭证。调用接口时,程序直接访问凭证,读取您的访问密钥(即AccessKey)并自动完成鉴权。以调用云服务器ECS的DescribeRegions接口为例,参考代码如下。

编程语言

使用示例

Go

Go语言代码示例

Java

Java语言代码示例

Python

Python语言代码示例

PHP

PHP语言代码示例

Node.js

Node.js语言代码示例

.NET

.NET语言代码示例

通用代码示例

对于自建网关类产品的自研SDK等无法使用阿里云SDK的场景,以Java语言为例,可以采用下面的方式加载环境变量。

import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;

public class DemoTest {
    public static void main(String[] args) throws Exception{
        Config config = new Config();
        // Which type of credential you want
        config.setType("access_key");
        // AccessKeyId of your ram user
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        // AccessKeySecret of your ram user
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        Client client = new Client(config);
    }
}

访问凭据泄露处理方案

相关文档

更多云上安全实践,请参阅以下文档: