用最专业的眼光看待互联网
立即咨询在这篇文章中,我们将介绍如何利用 AWS Secrets Manager 的新 API 调用 BatchGetSecretValue 来检索多个秘密,从而提高客户端应用程序的安全性和效率。通过使用 Secrets Manager,您可以避免在应用代码中硬编码凭证,实现动态检索,以降低意外或无意的访问风险。
之前,若应用程序使用 Secrets Manager,并需检索多个秘密,则必须依次调用 ListSecrets 以识别需要的秘密,再对每个秘密调用 GetSecretValue。现在,引入的 BatchGetSecretValue API 使得一次可以检索多个秘密,降低了代码复杂度,提高了批量检索的性能,还减少了触达 Secrets Manager 服务配额的风险。
尽管您可以利用此功能一次性检索多个秘密,但 Secrets Manager 的访问控制仍保持不变。这意味着,AWS 身份与访问管理 (IAM) 的授权单元需要与单独检索每个秘密时保持一致。若使用过滤器检索秘密,则所需的权限包括 listsecrets 和 getsecretvalue,以保护秘密元数据不被意外暴露。
对于来自不同 AWS 账户的秘密访问,需要针对每个秘密显式授予权限。后续我们将展示如何通过 IAM 策略或资源策略来限制此 API 的访问权限。
在接下来的部分中,您将配置一个 AWS Lambda 函数,使用 BatchGetSecretValue API 一次性检索多个秘密。此外,您将实现基于属性的访问控制 (ABAC),展示 Secrets Manager 的访问控制机制。请注意,在跟随此示例时,您需为创建的 Secrets Manager 秘密和 Lambda 函数的调用支付费用。有关详细信息,请参阅 Secrets Manager 定价 和 Lambda 定价 页面。
要参与本次演示,您需要:
五个需要应用秘密以交互的资源,例如数据库或第三方 API 密钥。访问一个 IAM 授权单元,该单位可以:通过 AWS 命令行界面 (AWS CLI) 或 AWS 管理控制台创建 Secrets Manager 秘密。创建一个用于 Lambda 执行的 IAM 角色。创建 Lambda 函数。将 Lambda 层附加到函数。一层 Lambda,其包含版本 1297 或更高版本的 boto3 库。有关如何创建包含最新版本 boto3 的 Lambda 层的示例,请参阅 AWS rePost 知识中心。首先,使用 AWS CLI 创建多个具有相同资源标签键值对的秘密。资源标签将用于 ABAC。这些秘密可能根据您选择在环境中使用的资源而有所不同。如果您更愿意,也可以手动 在 Secrets Manager 控制台 中创建这些秘密。
在 AWS CLI 中运行以下命令,将 secretstring 值替换为您需要访问的资源凭证:
命令aws secretsmanager createsecret name MyTestSecret1 description My first test secret created with the CLI for resource 1 secretstring {userusernamepasswordEXAMPLEPASSWORD1} tags [{KeyappValueapp1}{KeyenvironmentValueproduction}]aws secretsmanager createsecret name MyTestSecret2 description My second test secret created with the CLI for resource 2 secretstring {userusernamepasswordEXAMPLEPASSWORD2} tags [{KeyappValueapp1}{KeyenvironmentValueproduction}]aws secretsmanager createsecret name MyTestSecret3 description My third test secret created with the CLI for resource 3 secretstring {userusernamepasswordEXAMPLEPASSWORD3} tags [{KeyappValueapp1}{KeyenvironmentValueproduction}]aws secretsmanager createsecret name MyTestSecret4 description My fourth test secret created with the CLI for resource 4 secretstring {userusernamepasswordEXAMPLEPASSWORD4 } tags [{KeyappValueapp1}{KeyenvironmentValueproduction}]aws secretsmanager createsecret name MyTestSecret5 description My fifth test secret created with the CLI for resource 5 secretstring {userusernamepasswordEXAMPLEPASSWORD5} tags [{KeyappValueapp1}{KeyenvironmentValueproduction}]接下来,创建一个具有不同资源标签值的秘密,但环境标签键值对保持不变。这将使您能够验证当 IAM 授权单元没有权限检索和列出给定过滤条件下的秘密时,BatchGetSecretValue 调用将失败。
创建如下的秘密,并修改 secretstring 值:
命令aws secretsmanager createsecret name MyTestSecret6 description My test secret created with the CLI secretstring {userusernamepasswordEXAMPLEPASSWORD6} tags [{KeyappValueapp2}{KeyenvironmentValueproduction}]在本示例中,创建一个仅有权限检索带有 appapp1 资源标签的秘密的 Lambda 执行角色。
json{ Version 20121017 Statement [ { Sid Statement1 Effect Allow Action [ secretsmanagerListSecretVersionIds secretsmanagerGetSecretValue secretsmanagerGetResourcePolicy secretsmanagerDescribeSecret ] Resource [ ] Condition { StringNotEquals { awsResourceTag/app [ {awsPrincipalTag/app} ] } } } { Sid Statement2 Effect Allow Action [ secretsmanagerListSecrets secretsmanagerBatchGetSecretValue ] Resource [] } ]}
选择 下一步。输入策略名称 LambdaABACPolicy。点击 创建策略。图 1:创建访问秘密的 Lambda 函数
在 层 下选择添加层。选择自定义层,并选择您 Lambda 层中的 boto3 库版本 1297 或更高。点击添加。在 代码 标签中,复制并粘贴以下代码:pythonimport jsonimport boto3from botocoreexceptions import ClientError
session = boto3sessionSession()
client = sessionclient( servicename=secretsmanager)
def lambdahandler(event context) applicationsecrets = clientbatchgetsecretvalue(Filters=[ { Key tagkey Values [event[TagKey]] } { Key tagvalue Values [event[TagValue]] } ])
print(applicationsecrets[Errors])## 资源 1 连接 ##try print(测试连接到资源 1) resource1secret = applicationsecrets[SecretValues][0] ## 在这里实现资源连接 print(成功连接到资源 1)except Exception as e print(连接资源 1 失败) return e## 资源 2 连接 ##try print(测试连接到资源 2) resource2secret = applicationsecrets[SecretValues][1] ## 在这里实现资源连接 print(成功连接到资源 2)except Exception as e print(连接资源 2 失败) return e## 资源 3 连接 ##try print(测试连接到资源 3) resource3secret = applicationsecrets[SecretValues][2] ## 在这里实现资源连接 print(成功连接到资源 3)except Exception as e print(连接资源 3 失败) return e## 资源 4 连接 ##try print(测试连接到资源 4) resource4secret = applicationsecrets[SecretValues][3] ## 在这里实现资源连接 print(成功连接到资源 4)except Exception as e print(连接资源 4 失败) return e## 资源 5 连接 ##try print(测试访问资源 5) resource5secret = applicationsecrets[SecretValues][4] ## 在这里实现资源连接 print(成功连接到资源 5)except Exception as e print(连接资源 5 失败) return ereturn { statusCode 200 body jsondumps(所有连接成功完成!)}需要根据您正在使用的资源配置连接。该示例中的代码并未创建数据库或资源连接,以优先考虑读者的灵活性。在“## 在这里实现资源连接”注释后添加连接资源的代码。点击 部署。json{ TagKey app TagValue app1}
魔戒梯子使用教程输入测试事件的 名称。点击 保存。图 2:查看函数输出

json{ TagKey environment TagValue production}
您应该会在日志中看到来自 Secrets Manager 的错误消息,类似如下:[{SecretId arnawssecretsmanagerltregiongtltaccountnumbergtsecretltsecretnamegt ErrorCode AccessDeniedException Message User arnawsstsltaccountnumbergtassumedrole/ltrolenamegt/ltfunctionnamegt is not authorized to perform secretsmanagerGetSecretValue on resource arnawssecretsmanagerltregiongtltaccountnumbergtsecretMyTestSecret61111 because no identitybased policy allows the secretsmanagerGetSecretValue action}]
如您所见,您能够依据资源标签检索适当的秘密。当 Lambda 函数尝试检索没有权限的资源标签时,Secrets Manager 拒绝了请求。
处理敏感资源时,例如秘密,建议遵循最小权限原则。服务控制策略、IAM 策略和资源策略可以帮助您实现这一目标。下面我们讨论三种策略示例:
该策略拒绝访问秘密的请求,若授权单元与尝试访问的秘密没有共享相同的项目标签。请注意,该策略的有效性取决于资源标签和授权单元标签的正确应用。如果您想深入了解 Secrets Manager 的 ABAC,可以查看 利用 IAM 身份中心扩展 Secrets Manager 的授权需求。
json{ Version 20121017 Statement [ { Sid Statement1 Effect Deny Action [ secretsmanagerGetSecretValue ] Resource [ ] Condition { StringNotEquals { awsResourceTag/project [ {awsPrincipalTag/project} ] } } } ]}
此策略示例拒绝使用 BatchGetSecretValue 的权限,除非由特权工作负载角色运行。
json{ Version 20121017 Statement [ { Sid Statement1 Effect Deny Action [ secretsmanagerBatchGetSecretValue ] Resource [ arnawssecretsmanageruswest212345678910secrettestsecret ] Condition { StringNotLike { awsPrincipalArn [ arnawsiam123456789011role/prodworkloadrole ] } } } ]}
最后,我们来看一个来自我们 数据周界策略示例 的资源策略示例。该资源策略限制 Secrets Manager 操作为此秘密所属组织中的授权单元,AWS 服务账户除外。
json{ Version 20121017 Statement [ { Sid EnforceIdentityPerimeter Effect Deny Principal { AWS } Action secretsmanager Resource Condition { StringNotEqualsIfExists { awsPrincipalOrgID ltmyorgidgt } BoolIfExists { awsPrincipalIsAWSService false } } } ]}
在这篇博客中,我们介绍了 BatchGetSecretValue API,您可以利用它来提升操作卓越性、性能效率,并在使用 Secrets Manager 时降低成本。我们还展示了如何在 Lambda 函数中使用该 API 调用检索具有相同资源标签的多个秘密,并提供了限制访问此 API 的 IAM 策略示例。
欲了解更多有关 Secrets Manager 的信息,请查看 AWS Secrets Manager 文档 或 [AWS 安