

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 从中获取秘密 AWS Secrets Manager
<a name="retrieving-secrets"></a>

当你检索密钥时，Secrets Manager 会生成一个 CloudTrail 日志条目。有关更多信息，请参阅 [使用记录 AWS Secrets Manager 事件 AWS CloudTrail](monitoring-cloudtrail.md)。

**Topics**
+ [Java](retrieving-secrets-java.md)
+ [Python](retrieving-secrets-python.md)
+ [.NET](retrieving-secrets-net.md)
+ [Go](retrieving-secrets-go.md)
+ [Rust](retrieving-secrets-rust.md)
+ [Amazon EKS](integrate_eks.md)
+ [AWS Lambda](retrieving-secrets_lambda.md)
+ [Secrets Manager 代理](secrets-manager-agent.md)
+ [C\$1\$1](retrieving-secrets-cpp.md)
+ [JavaScript](retrieving-secrets-javascript.md)
+ [Kotlin](retrieving-secrets-kotlin.md)
+ [PHP](retrieving-secrets-php.md)
+ [Ruby](retrieving-secrets-ruby.md)
+ [AWS CLI](retrieving-secrets_cli.md)
+ [AWS 控制台](retrieving-secrets-console.md)
+ [AWS Batch](integrating_BATCH.md)
+ [CloudFormation](cfn-example_reference-secret.md)
+ [GitHub 工作](retrieving-secrets_github.md)
+ [GitLab](integrating_gitlab.md)
+ [AWS IoT Greengrass](integrating-greengrass.md)
+ [Parameter Store](integrating_parameterstore.md)

# 使用 Java 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-java"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

要使用密钥中的凭证连接到数据库，您可以使用 Secrets Manager SQL 连接驱动程序，它封装了基本 JDBC 驱动程序。它还使用客户端缓存，因此可以降低调用 Secrets Manager APIs 的成本。

**Topics**
+ [使用 Java 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-java.md)
+ [使用密钥中的凭据使用 JDBC 连接到 SQL 数据库 AWS Secrets Manager](retrieving-secrets_jdbc.md)
+ [使用 Java AWS SDK 获取 Secrets Manager 密钥值](retrieving-secrets-java-sdk.md)

# 使用 Java 和客户端缓存获取 Secrets Manager 密钥值
<a name="retrieving-secrets_cache-java"></a>

在检索密钥时，您可以使用 Secrets Manager 基于 Java 的缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。由于调用 Secrets Manager 需要付费 APIs，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [获取密钥](retrieving-secrets.md)。

缓存策略为“最近最少使用 (LRU)”，因此当缓存必须丢弃某个密钥时，它会丢弃最近使用最少的密钥。原定设置下，缓存会每小时刷新一次秘密。您可以配置在缓存中[刷新密钥的频率](retrieving-secrets_cache-java-ref_SecretCacheConfiguration.md#retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getCacheItemTTL)，也可以[挂钩到密钥检索中](retrieving-secrets_cache-java-ref_SecretCacheHook.md)以添加更多功能。

一旦释放缓存引用，缓存便不会进行强制垃圾回收。缓存实施不包括缓存失效。缓存实现侧重于缓存本身，而不是侧重加强安全性或以安全性为重点。如果您需要额外的安全性（例如加密缓存中的项目），请使用提供的接口和抽象方法。

要使用该组件，您必须满足以下条件：
+ Java 8 或更高版本的开发环境。请参阅 Oracle 网站上的 [Java SE 下载](https://www.oracle.com/technetwork/java/javase/downloads/index.html)。

要下载源代码，请参阅上的 S [ecrets Manager 基于 Java 的缓存客户端组件](https://github.com/aws/aws-secretsmanager-caching-java)。 GitHub

要将该组件添加到您的项目中，请在 Maven pom.xml 文件中包括以下依赖项。有关 Maven 的更多信息，请参阅 Apache Maven Project 网站上的[《入门指南》](https://maven.apache.org/guides/getting-started/index.html)。

```
<dependency>
  <groupId>com.amazonaws.secretsmanager</groupId>
  <artifactId>aws-secretsmanager-caching-java</artifactId>
  <version>1.0.2</version>
</dependency>
```

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Topics**
+ [SecretCache](retrieving-secrets_cache-java-ref_SecretCache.md)
+ [SecretCacheConfiguration](retrieving-secrets_cache-java-ref_SecretCacheConfiguration.md)
+ [SecretCacheHook](retrieving-secrets_cache-java-ref_SecretCacheHook.md)

**Example 检索密钥**  
以下代码示例显示了检索密钥字符串的 Lambda 函数。它遵循在函数处理程序之外实例化缓存的[最佳实践](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html)，因此如果您再次调用该 Lambda 函数，它不会继续调用该 API。  

```
package com.amazonaws.secretsmanager.caching.examples;
    
    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import com.amazonaws.services.lambda.runtime.LambdaLogger;
    
    import com.amazonaws.secretsmanager.caching.SecretCache;
    
    public class SampleClass implements RequestHandler<String, String> {
    
         private final SecretCache cache  = new SecretCache();
    
         @Override public String handleRequest(String secretId,  Context context) {
             final String secret  = cache.getSecretString(secretId);
    
            // Use the secret, return success;
    
        }
    }
```

# SecretCache
<a name="retrieving-secrets_cache-java-ref_SecretCache"></a>

适用于从 Secrets Manager 请求的密钥的内存中缓存。您使用 [getSecretString](#retrieving-secrets_cache-java-ref_SecretCache-methods-getSecretString) 或 [getSecretBinary](#retrieving-secrets_cache-java-ref_SecretCache-methods-getSecretBinary) 从缓存中检索密钥。您可以通过传入构造函数中的 [SecretCacheConfiguration](retrieving-secrets_cache-java-ref_SecretCacheConfiguration.md) 对象来配置缓存设置。

有关包括示例在内的更多信息，请参阅 [使用 Java 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-java.md)。

## 构造函数
<a name="retrieving-secrets_cache-java-ref_SecretCache-constructors"></a>

`public SecretCache()`  
适用于 `SecretCache` 对象的默认构造函数。

`public SecretCache(AWSSecretsManagerClientBuilder builder)`  
使用 Secrets Manager 客户端（使用提供的 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClientBuilder.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClientBuilder.html) 创建）构造新缓存。使用此构造函数自定义 Secrets Manager 客户端，例如使用某一特定区域或端点。

`public SecretCache(AWSSecretsManager client)`  
请使用提供的 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 构造新密钥缓存。使用此构造函数自定义 Secrets Manager 客户端，例如使用某一特定区域或端点。

`public SecretCache(SecretCacheConfiguration config)`  
请使用提供的 `SecretCacheConfiguration` 构造新密钥缓存。

## 方法
<a name="retrieving-secrets_cache-java-ref_SecretCache-methods"></a>

### getSecretString
<a name="retrieving-secrets_cache-java-ref_SecretCache-methods-getSecretString"></a>

`public String getSecretString(final String secretId)`

从 Secrets Manager 中检索字符串密钥。返回 [https://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true)。

### getSecretBinary
<a name="retrieving-secrets_cache-java-ref_SecretCache-methods-getSecretBinary"></a>

`public ByteBuffer getSecretBinary(final String secretId)`

从 Secrets Manager 中检索二进制密钥。返回 [https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html](https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html)。

### refreshNow
<a name="retrieving-secrets_cache-java-ref_SecretCache-methods-refreshNow"></a>

`public boolean refreshNow(final String secretId) throws InterruptedException`

强制刷新缓存。如果刷新完成没有错误，将返回 `true`，否则将返回 `false`。

### close
<a name="retrieving-secrets_cache-java-ref_SecretCache-methods-close"></a>

`public void close()`

关闭缓存。

# SecretCacheConfiguration
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration"></a>

适用于 [SecretCache](retrieving-secrets_cache-java-ref_SecretCache.md) 的缓存配置选项，例如最大缓存大小和已缓存密钥的生存时间 (TTL)。

## 构造函数
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_constructor"></a>

`public SecretCacheConfiguration`

适用于 `SecretCacheConfiguration` 对象的默认构造函数。

## 方法
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods"></a>

### getClient
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getClient"></a>

`public AWSSecretsManager getClient()`

返回缓存从中检索密钥的 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html)。

### setClient
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-setClient"></a>

`public void setClient(AWSSecretsManager client)`

设置缓存从中检索密钥的 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 客户端。

### getCacheHook
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getCacheHook"></a>

`public SecretCacheHook getCacheHook()`

返回用于挂钩缓存更新的 [SecretCacheHook](retrieving-secrets_cache-java-ref_SecretCacheHook.md) 接口。

### setCacheHook
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-setCacheHook"></a>

`public void setCacheHook(SecretCacheHook cacheHook)`

设置用于挂钩缓存更新的 [SecretCacheHook](retrieving-secrets_cache-java-ref_SecretCacheHook.md) 接口。

### getMaxCache大小
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getMaxCacheSize"></a>

`public int getMaxCacheSize()`

返回最大缓存大小。默认值为 1024 个密钥。

### setMaxCache大小
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-setMaxCacheSize"></a>

`public void setMaxCacheSize(int maxCacheSize)`

设置最大缓存大小。默认值为 1024 个密钥。

### getCacheItemTTL
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getCacheItemTTL"></a>

`public long getCacheItemTTL()`

返回已缓存项目的 TTL（以毫秒为单位）。当已缓存密钥超过此 TTL 时，缓存将从 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 中检索该密钥的新副本。默认值为 1 小时（以毫秒为单位）。

在 TTL 之后请求密钥时，缓存将同步刷新密钥。如果同步刷新失败，缓存将返回过时密钥。

### setCacheItemTTL
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-setCacheItemTTL"></a>

`public void setCacheItemTTL(long cacheItemTTL)`

为已缓存项目设置 TTL（以毫秒为单位）。当已缓存密钥超过此 TTL 时，缓存将从 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 中检索该密钥的新副本。默认值为 1 小时（以毫秒为单位）。

### getVersionStage
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-getVersionStage"></a>

`public String getVersionStage()`

返回您要缓存的密钥的版本。有关更多信息，请参阅[密钥版本](whats-in-a-secret.md#term_version)。默认值为 ` "AWSCURRENT"`。

### setVersionStage
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-setVersionStage"></a>

`public void setVersionStage(String versionStage)`

设置您要缓存的密钥的版本。有关更多信息，请参阅[密钥版本](whats-in-a-secret.md#term_version)。默认值为 `"AWSCURRENT"`。

### SecretCacheConfiguration 与客户一起
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-withClient"></a>

`public SecretCacheConfiguration withClient(AWSSecretsManager client)`

设置 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 以从中检索密钥。返回具有新设置的更新后的 `SecretCacheConfiguration` 对象。

### SecretCacheConfiguration withCacheHook
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-withCacheHook"></a>

`public SecretCacheConfiguration withCacheHook(SecretCacheHook cacheHook)`

设置用于挂钩内存中缓存的接口。返回具有新设置的更新后的 `SecretCacheConfiguration` 对象。

### SecretCacheConfiguration withMaxCache大小
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-withMaxCacheSize"></a>

`public SecretCacheConfiguration withMaxCacheSize(int maxCacheSize)`

设置最大缓存大小。返回具有新设置的更新后的 `SecretCacheConfiguration` 对象。

### SecretCacheConfiguration withCacheItemTTL
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-withCacheItemTTL"></a>

`public SecretCacheConfiguration withCacheItemTTL(long cacheItemTTL)`

为已缓存项目设置 TTL（以毫秒为单位）。当已缓存密钥超过此 TTL 时，缓存将从 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/AWSSecretsManagerClient.html) 中检索该密钥的新副本。默认值为 1 小时（以毫秒为单位）。返回具有新设置的更新后的 `SecretCacheConfiguration` 对象。

### SecretCacheConfiguration withVersionStage
<a name="retrieving-secrets_cache-java-ref_SecretCacheConfiguration_methods-withVersionStage"></a>

`public SecretCacheConfiguration withVersionStage(String versionStage)`

设置您要缓存的密钥的版本。有关更多信息，请参阅[密钥版本](whats-in-a-secret.md#term_version)。返回具有新设置的更新后的 `SecretCacheConfiguration` 对象。

# SecretCacheHook
<a name="retrieving-secrets_cache-java-ref_SecretCacheHook"></a>

用于挂钩到 [SecretCache](retrieving-secrets_cache-java-ref_SecretCache.md) 中以便对存储于缓存中的密钥执行操作的接口。

## put
<a name="retrieving-secrets_cache-java-ref_SecretCacheHook-put"></a>

`Object put(final Object o)`

准备对象以存储到缓存中。

返回要存储在缓存中的对象。

## 入
<a name="retrieving-secrets_cache-java-ref_SecretCacheHook-get"></a>

`Object get(final Object cachedObject)`

从已缓存对象派生对象。

返回要从缓存中返回的对象

# 使用密钥中的凭据使用 JDBC 连接到 SQL 数据库 AWS Secrets Manager
<a name="retrieving-secrets_jdbc"></a>

在 Java 应用程序中，你可以使用 Secrets Manager SQL Connection 驱动程序使用存储在 Secrets Manager 中的凭据连接到 MySQL、PostgreSQL MSSQLServer、Oracle、Db2 和 Redshift 数据库。每个驱动程序都会包装基本 JDBC 驱动程序，因此您可以使用 JDBC 调用来访问数据库。但是，您不必为连接传递用户名和密码，而是提供密钥的 ID。驱动程序将调用 Secrets Manager 来检索密钥值，然后使用密钥中的凭证连接到数据库。驱动程序还将使用 [Java 客户端缓存库](retrieving-secrets_cache-java.md)来缓存凭证，这样未来的连接就不需要调用 Secrets Manager。默认情况下，缓存会每小时刷新一次，此外在轮换密钥时也会刷新。要配置缓存，请参阅[SecretCacheConfiguration](retrieving-secrets_cache-java-ref_SecretCacheConfiguration.md)。

您可以从 [GitHub](https://github.com/aws/aws-secretsmanager-jdbc )中下载源代码。

要使用 Secrets Manager SQL 连接驱动程序：
+ 您的应用程序必须处于 Java 8 或更高版本中。
+ 您的密钥必须为以下之一：
  + [预期 JSON 结构中的数据库密钥](reference_secret_json_structure.md)。要检查格式，请在 Secrets Manager 控制台中查看密钥并选择 **Retrieve secret value**（检索密钥值）。或者，在通话 AWS CLI中[get-secret-value](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/get-secret-value.html)。
  + Amazon RDS [托管密钥](integrating_how-services-use-secrets_RDS.md)。对于此类密钥，必须在建立连接时指定端点和端口。
  + Amazon Redshift [托管密钥](integrating_how-services-use-secrets_RS.md)。对于此类密钥，必须在建立连接时指定端点和端口。

如果您的数据库复制到其他区域，要连接到另一个区域中的副本数据库，请在创建连接时指定区域端点和端口。您可以将区域连接信息作为额外 key/value 对存储在密钥中、SSM Parameter Store 参数中或您的代码配置中。

要将驱动程序添加到项目中，请在 Maven 构建文件 `pom.xml` 中为该驱动程序添加以下依赖项。有关更多信息，请参阅 Maven Central 存储库网站上的 [Secrets Manager SQL 连接库](https://search.maven.org/artifact/com.amazonaws.secretsmanager/aws-secretsmanager-jdbc)。

```
<dependency>
    <groupId>com.amazonaws.secretsmanager</groupId>
    <artifactId>aws-secretsmanager-jdbc</artifactId>
    <version>1.0.12</version>
</dependency>
```

驱动程序使用[https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html)。如果您在 Amazon EKS 上运行驱动程序，它可能会获取正在运行的节点的凭证，而不会获取服务账户角色。要解决此问题，请将 `com.amazonaws:aws-java-sdk-sts` 的版本 1 作为依赖项添加到 Gradle 或 Maven 项目文件。

要在`secretsmanager.properties`文件中设置 AWS PrivateLink DNS 终端节点 URL 和区域，请执行以下操作：

```
drivers.vpcEndpointUrl = endpoint URL
drivers.vpcEndpointRegion = endpoint region
```

要覆盖主区域，请设置 `AWS_SECRET_JDBC_REGION` 环境变量或对 `secretsmanager.properties` 文件进行以下更改：

```
drivers.region = region
```

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Topics**
+ [建立与数据库的连接](#retrieving-secrets_jdbc_example)
+ [通过指定端点和端口建立连接](#retrieving-secrets_jdbc_example_replica)
+ [使用 c3p0 连接池建立连接](#retrieving-secrets_jdbc_example_c3po)
+ [使用 c3p0 连接池通过指定端点和端口来建立连接](#retrieving-secrets_jdbc_example_c3p0_replica)

## 建立与数据库的连接
<a name="retrieving-secrets_jdbc_example"></a>

下面的示例演示了如何使用密钥中的凭证和连接信息建立与数据库的连接。建立连接后，您可使用 JDBC 调用来访问数据库。有关更多信息，请参阅 Java 文档网站上的 [JDBC 基础知识](https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html)。

------
#### [ MySQL ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ PostgreSQL ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Oracle ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ MSSQLServer ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Db2 ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Redshift ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver" ).newInstance();

// Retrieve the connection info from the secret using the secret ARN
String URL = "secretId";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------

## 通过指定端点和端口建立连接
<a name="retrieving-secrets_jdbc_example_replica"></a>

以下示例演示了如何使用密钥中的凭证以及指定的端点和端口建立与数据库的连接。

[Amazon RDS 托管密钥](integrating_how-services-use-secrets_RDS.md)不包括数据库的端点和端口。要使用由 Amazon RDS 管理的密钥中的主凭证连接到数据库，请在代码中指定这些凭证。

[复制到其他区域的密钥](replicate-secrets.md)可以降低连接到区域数据库的延迟，但复制的密钥将不包含与源密钥不同的连接信息。每个副本都与源密钥相同。要在密钥中存储区域连接信息，请为终端节点和区域的端口信息添加更多 key/value 对。

建立连接后，您可使用 JDBC 调用来访问数据库。有关更多信息，请参阅 Java 文档网站上的 [JDBC 基础知识](https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html)。

------
#### [ MySQL ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:mysql://example.com:3306";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ PostgreSQL ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:postgresql://example.com:5432/database";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Oracle ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:oracle:thin:@example.com:1521/ORCL";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ MSSQLServer ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:sqlserver://example.com:1433";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Db2 ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.com.rproxy.govskope.ca.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:db2://example.com:50000";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------
#### [ Redshift ]

```
// Load the JDBC driver
Class.forName( "com.amazonaws.com.rproxy.govskope.ca.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver" ).newInstance();

// Set the endpoint and port. You can also retrieve it from a key/value pair in the secret.
String URL = "jdbc-secretsmanager:redshift://example.com:5439";

// Populate the user property with the secret ARN to retrieve user and password from the secret
Properties info = new Properties( );
info.put( "user", "secretId" );

// Establish the connection
conn = DriverManager.getConnection(URL, info);
```

------

## 使用 c3p0 连接池建立连接
<a name="retrieving-secrets_jdbc_example_c3po"></a>

以下示例演示了如何使用 `c3p0.properties` 文件建立连接池，该文件使用驱动程序从密钥中检索凭证和连接信息。对于 `user` 和 `jdbcUrl`，请输入密钥 ID 以配置连接池。然后，您可以从该池中检索连接，并将这些连接用作任何其他数据库连接。有关更多信息，请参阅 Java 文档网站上的 [JDBC 基础知识](https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html)。

有关 c3p0 的更多信息，请参阅 Machinery For Change 网站上的 [c3p0](https://www.mchange.com/projects/c3p0/)。

------
#### [ MySQL ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
c3p0.jdbcUrl=secretId
```

------
#### [ PostgreSQL ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver
c3p0.jdbcUrl=secretId
```

------
#### [ Oracle ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver
c3p0.jdbcUrl=secretId
```

------
#### [ MSSQLServer ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver
c3p0.jdbcUrl=secretId
```

------
#### [ Db2 ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver
c3p0.jdbcUrl=secretId
```

------
#### [ Redshift ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver
c3p0.jdbcUrl=secretId
```

------

## 使用 c3p0 连接池通过指定端点和端口来建立连接
<a name="retrieving-secrets_jdbc_example_c3p0_replica"></a>

以下示例演示了如何使用 `c3p0.properties` 文件建立连接池，该文件使用驱动程序通过指定的端点和端口检索密钥中的凭证。然后，您可以从该池中检索连接，并将这些连接用作任何其他数据库连接。有关更多信息，请参阅 Java 文档网站上的 [JDBC 基础知识](https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html)。

[Amazon RDS 托管密钥](integrating_how-services-use-secrets_RDS.md)不包括数据库的端点和端口。要使用由 Amazon RDS 管理的密钥中的主凭证连接到数据库，请在代码中指定这些凭证。

[复制到其他区域的密钥](replicate-secrets.md)可以降低连接到区域数据库的延迟，但复制的密钥将不包含与源密钥不同的连接信息。每个副本都与源密钥相同。要在密钥中存储区域连接信息，请为终端节点和区域的端口信息添加更多 key/value 对。

------
#### [ MySQL ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
c3p0.jdbcUrl=jdbc-secretsmanager:mysql://example.com:3306
```

------
#### [ PostgreSQL ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver
c3p0.jdbcUrl=jdbc-secretsmanager:postgresql://example.com:5432/database
```

------
#### [ Oracle ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver
c3p0.jdbcUrl=jdbc-secretsmanager:oracle:thin:@example.com:1521/ORCL
```

------
#### [ MSSQLServer ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver
c3p0.jdbcUrl=jdbc-secretsmanager:sqlserver://example.com:1433
```

------
#### [ Db2 ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver
c3p0.jdbcUrl=jdbc-secretsmanager:db2://example.com:50000
```

------
#### [ Redshift ]

```
c3p0.user=secretId
c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver
c3p0.jdbcUrl=jdbc-secretsmanager:redshift://example.com:5439
```

------

# 使用 Java AWS SDK 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-java-sdk"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。
+ 如果您将数据库凭证存储在密钥中，请使用 [Secrets Manager SQL 连接驱动程序](retrieving-secrets_jdbc.md)借助密钥中的凭证连接到数据库。
+ 对于其他类型的密钥，使用 [Secrets Manager 基于 Java 的缓存组件](retrieving-secrets_cache-java.md)，或直接使用 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/model/GetSecretValueResult.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/model/GetSecretValueResult.html) 或 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/model/BatchGetSecretValueResult.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/secretsmanager/model/BatchGetSecretValueResult.html) 调用 SDK。

以下代码示例演示如何使用 `GetSecretValue`。

**所需权限：**`secretsmanager:GetSecretValue`

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
import software.amazon.awssdk.services.secretsmanager.model.SecretsManagerException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * We recommend that you cache your secret values by using client-side caching.
 *
 * Caching secrets improves speed and reduces your costs. For more information,
 * see the following documentation topic:
 *
 * https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html
 */
public class GetSecretValue {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <secretName>\s

                Where:
                    secretName - The name of the secret (for example, tutorials/MyFirstSecret).\s
                """;

        if (args.length != 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String secretName = args[0];
        Region region = Region.US_EAST_1;
        SecretsManagerClient secretsClient = SecretsManagerClient.builder()
                .region(region)
                .build();

        getValue(secretsClient, secretName);
        secretsClient.close();
    }

    public static void getValue(SecretsManagerClient secretsClient, String secretName) {
        try {
            GetSecretValueRequest valueRequest = GetSecretValueRequest.builder()
                    .secretId(secretName)
                    .build();

            GetSecretValueResponse valueResponse = secretsClient.getSecretValue(valueRequest);
            String secret = valueResponse.secretString();
            System.out.println(secret);

        } catch (SecretsManagerException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```

# 使用 Python 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-python"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

**Topics**
+ [使用 Python 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-python.md)
+ [使用 Python AWS SDK 获取 Secrets Manager 密钥值](retrieving-secrets-python-sdk.md)
+ [使用 Python AWS SDK 获取一批 Secrets Manager 密钥值](retrieving-secrets-python-batch.md)

# 使用 Python 和客户端缓存获取 Secrets Manager 密钥值
<a name="retrieving-secrets_cache-python"></a>

在检索密钥时，您可以使用 Secrets Manager 基于 Python 的缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。由于调用 Secrets Manager 需要付费 APIs，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [获取密钥](retrieving-secrets.md)。

缓存策略为“最近最少使用 (LRU)”，因此当缓存必须丢弃某个密钥时，它会丢弃最近使用最少的密钥。原定设置下，缓存会每小时刷新一次秘密。您可以配置在缓存中[刷新密钥的频率](retrieving-secrets_cache-ref-secretcacheconfig.md)，也可以[挂钩到密钥检索中](retrieving-secrets_cache-ref-secretcachehook.md)以添加更多功能。

一旦释放缓存引用，缓存便不会进行强制垃圾回收。缓存实施不包括缓存失效。缓存实现侧重于缓存本身，而不是侧重加强安全性或以安全性为重点。如果您需要额外的安全性（例如加密缓存中的项目），请使用提供的接口和抽象方法。

要使用该组件，您必须满足以下条件：
+ Python 3.6 或更高版本。
+ botocore 1.12 或更高版本。请参阅[适用于 Python](https://aws.amazon.com/sdk-for-python/) 和 [Botocore 的AWS SDK](https://botocore.amazonaws.com/v1/documentation/api/latest/index.html)。
+ setuptools\$1scm 3.2 或更高版本。见 [https://pypi。 org/project/setuptools-scm/](https://pypi.org/project/setuptools-scm/)。

要下载源代码，请参阅上的 S [ecrets Manager 基于 Python 的缓存客户端组件](https://github.com/aws/aws-secretsmanager-caching-python )。 GitHub

要安装组件，请使用以下命令。

```
$ pip install aws-secretsmanager-caching
```

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Topics**
+ [SecretCache](retrieving-secrets_cache-ref-secretcache.md)
+ [SecretCacheConfig](retrieving-secrets_cache-ref-secretcacheconfig.md)
+ [SecretCacheHook](retrieving-secrets_cache-ref-secretcachehook.md)
+ [@InjectSecretString](retrieving-secrets_cache-decor-string.md)
+ [@InjectKeywordedSecretString](retrieving-secrets_cache-decor-keyword.md)

**Example 检索密钥**  
以下示例说明如何获取名为的密钥的机密值*mysecret*。  

```
import botocore 
import botocore.session 
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig 

client = botocore.session.get_session().create_client('secretsmanager')
cache_config = SecretCacheConfig()
cache = SecretCache( config = cache_config, client = client)

secret = cache.get_secret_string('mysecret')
```

# SecretCache
<a name="retrieving-secrets_cache-ref-secretcache"></a>

适用于从 Secrets Manager 检索的密钥的内存缓存。您使用 [get\$1secret\$1string](#retrieving-secrets_cache-ref-secretcache_get_secret_string) 或 [get\$1secret\$1binary](#retrieving-secrets_cache-ref-secretcache_get_secret_binary) 从缓存中检索密钥。您可以通过传入构造函数中的 [SecretCacheConfig](retrieving-secrets_cache-ref-secretcacheconfig.md) 对象来配置缓存设置。

有关包括示例在内的更多信息，请参阅 [使用 Python 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-python.md)。

```
cache = SecretCache(
    config = SecretCacheConfig,
    client = [client](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html)
)
```

**Topics**
+ [get\$1secret\$1string](#retrieving-secrets_cache-ref-secretcache_get_secret_string)
+ [get\$1secret\$1binary](#retrieving-secrets_cache-ref-secretcache_get_secret_binary)

## get\$1secret\$1string
<a name="retrieving-secrets_cache-ref-secretcache_get_secret_string"></a>

检索密钥字符串值。

请求语法  

```
response = cache.get_secret_string(
    secret_id='string',
    version_stage='string' )
```

参数  
+ `secret_id`（*字符串*）：[必需] 密钥的名称或 ARN。
+ `version_stage`（*字符串*）：您要检索的密钥的版本。有关更多信息，请参阅 [secret versions](whats-in-a-secret.md)。默认值为“AWSCURRENT”。

返回类型  
字符串

## get\$1secret\$1binary
<a name="retrieving-secrets_cache-ref-secretcache_get_secret_binary"></a>

检索密钥二进制值。

请求语法  

```
response = cache.get_secret_binary(
    secret_id='string',
    version_stage='string'
)
```

参数  
+ `secret_id`（*字符串*）：[必需] 密钥的名称或 ARN。
+ `version_stage`（*字符串*）：您要检索的密钥的版本。有关更多信息，请参阅 [secret versions](whats-in-a-secret.md)。默认值为“AWSCURRENT”。

返回类型  
[base64 编码的](https://tools.ietf.org/html/rfc4648#section-4)字符串

# SecretCacheConfig
<a name="retrieving-secrets_cache-ref-secretcacheconfig"></a>

适用于 [SecretCache](retrieving-secrets_cache-ref-secretcache.md) 的缓存配置选项，例如最大缓存大小和已缓存密钥的存活时间 (TTL)。参数

`max_cache_size` (*int*)  
最大缓存大小。默认值为 `1024` 个密钥。

`exception_retry_delay_base` (*int*)  
遇到异常后重试请求之前需要等待的秒数。默认值为 `1`。

`exception_retry_growth_factor` (*int*)pur  
用于计算重试失败请求之间等待时间的增长系数。默认值为 `2`。

`exception_retry_delay_max` (*int*)  
在失败请求之间需要等待的最长时间（以秒为单位）。默认值为 `3600`。

`default_version_stage` (*str*)  
您要缓存的密钥的版本。有关更多信息，请参阅[密钥版本](whats-in-a-secret.md#term_version)。默认值为 `'AWSCURRENT'`。

`secret_refresh_interval` (*int*)  
刷新已缓存密钥信息之间需要等待的秒数。默认值为 `3600`。

`secret_cache_hook` (*SecretCacheHook*)  
`SecretCacheHook` 抽象类的实施。默认值为 `None`。

# SecretCacheHook
<a name="retrieving-secrets_cache-ref-secretcachehook"></a>

用于挂钩到 [SecretCache](retrieving-secrets_cache-ref-secretcache.md) 中以便对存储于缓存中的密钥执行操作的接口。

**Topics**
+ [put](#retrieving-secrets_cache-ref-secretcachehook_put)
+ [入](#retrieving-secrets_cache-ref-secretcachehook_get)

## put
<a name="retrieving-secrets_cache-ref-secretcachehook_put"></a>

使对象为存储在缓存中做好准备。

请求语法  

```
response = hook.put(
    obj='secret_object'
)
```

参数  
+ `obj` (*对象*) -- [必需] 密钥或包含密钥的对象。

返回类型  
object

## 入
<a name="retrieving-secrets_cache-ref-secretcachehook_get"></a>

从已缓存对象派生对象。

请求语法  

```
response = hook.get(
    obj='secret_object'
)
```

参数  
+ `obj`（*对象*）：[必需] 密钥或包含密钥的对象。

返回类型  
object

# @InjectSecretString
<a name="retrieving-secrets_cache-decor-string"></a>

此装饰器需要一个密钥 ID 字符串和 [SecretCache](retrieving-secrets_cache-ref-secretcache.md) 作为前两个参数。该装饰器将返回密钥字符串值。密钥必须包含一个字符串。

```
from aws_secretsmanager_caching import SecretCache 
from aws_secretsmanager_caching import InjectKeywordedSecretString,  InjectSecretString 

cache = SecretCache()

@InjectSecretString ( 'mysecret' ,  cache ) 
def function_to_be_decorated( arg1,  arg2,  arg3):
```

# @InjectKeywordedSecretString
<a name="retrieving-secrets_cache-decor-keyword"></a>

此装饰器需要一个密钥 ID 字符串和 [SecretCache](retrieving-secrets_cache-ref-secretcache.md) 作为前两个参数。其余自变量将已包装函数中的参数映射到密钥中的 JSON 键。密钥必须包含一个 JSON 结构的字符串。

对于包含此 JSON 的密钥：

```
{
  "username": "saanvi",
  "password": "EXAMPLE-PASSWORD"
}
```

下面的示例演示了如何从密钥中提取 `username` 和 `password` 的 JSON 值。

```
from aws_secretsmanager_caching import SecretCache 
  from aws_secretsmanager_caching import InjectKeywordedSecretString,  InjectSecretString 
  
  cache = SecretCache()
  
  @InjectKeywordedSecretString ( secret_id = 'mysecret' ,  cache = cache ,  func_username = 'username' ,  func_password = 'password' ) 
  def function_to_be_decorated( func_username,  func_password):
       print( 'Do something with the func_username and func_password parameters')
```

# 使用 Python AWS SDK 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-python-sdk"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

对于 Python 应用程序，请使用 [Secrets Manager 基于 Python 的缓存组件](retrieving-secrets_cache-python.md)或直接使用 [https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager/client/get_secret_value.html](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager/client/get_secret_value.html) 或 [https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager/client/batch_get_secret_value.html](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager/client/batch_get_secret_value.html) 调用 SDK。

以下代码示例演示如何使用 `GetSecretValue`。

**所需权限：**`secretsmanager:GetSecretValue`

```
"""
Purpose

Shows how to use the AWS SDK for Python (Boto3) with AWS
Secrets Manager to get a specific of secrets that match a
specified name
"""
import boto3
import logging

from get_secret_value import GetSecretWrapper

# Configure logging
logging.basicConfig(level=logging.INFO)


def run_scenario(secret_name):
    """
    Retrieve a secret from AWS Secrets Manager.

    :param secret_name: Name of the secret to retrieve.
    :type secret_name: str
    """
    try:
        # Validate secret_name
        if not secret_name:
            raise ValueError("Secret name must be provided.")
        # Retrieve the secret by name
        client = boto3.client("secretsmanager")
        wrapper = GetSecretWrapper(client)
        secret = wrapper.get_secret(secret_name)
        # Note: Secrets should not be logged.
        return secret
    except Exception as e:
        logging.error(f"Error retrieving secret: {e}")
        raise

class GetSecretWrapper:
    def __init__(self, secretsmanager_client):
        self.client = secretsmanager_client


    def get_secret(self, secret_name):
        """
        Retrieve individual secrets from AWS Secrets Manager using the get_secret_value API.
        This function assumes the stack mentioned in the source code README has been successfully deployed.
        This stack includes 7 secrets, all of which have names beginning with "mySecret".

        :param secret_name: The name of the secret fetched.
        :type secret_name: str
        """
        try:
            get_secret_value_response = self.client.get_secret_value(
                SecretId=secret_name
            )
            logging.info("Secret retrieved successfully.")
            return get_secret_value_response["SecretString"]
        except self.client.exceptions.ResourceNotFoundException:
            msg = f"The requested secret {secret_name} was not found."
            logger.info(msg)
            return msg
        except Exception as e:
            logger.error(f"An unknown error occurred: {str(e)}.")
            raise
```

# 使用 Python AWS SDK 获取一批 Secrets Manager 密钥值
<a name="retrieving-secrets-python-batch"></a>

以下代码示例演示了如何获取批量 Secrets Manager 密钥值。

**所需权限：**
+ `secretsmanager:BatchGetSecretValue` 
+ 对要检索的每个密钥拥有 `secretsmanager:GetSecretValue` 权限。
+ 如果您使用筛选器，则还必须拥有 `secretsmanager:ListSecrets`。

有关权限策略的示例，请参阅 [示例：批量检索一组密钥值的权限](auth-and-access_iam-policies.md#auth-and-access_examples_batch)。

**重要**  
如果您的 VPCE 策略拒绝在您正在检索的群组中检索单个秘密的权限，则 `BatchGetSecretValue` 不会返回任何秘密值，并且会返回错误。

```
class BatchGetSecretsWrapper:
    def __init__(self, secretsmanager_client):
        self.client = secretsmanager_client


    def batch_get_secrets(self, filter_name):
        """
        Retrieve multiple secrets from AWS Secrets Manager using the batch_get_secret_value API.
        This function assumes the stack mentioned in the source code README has been successfully deployed.
        This stack includes 7 secrets, all of which have names beginning with "mySecret".

        :param filter_name: The full or partial name of secrets to be fetched.
        :type filter_name: str
        """
        try:
            secrets = []
            response = self.client.batch_get_secret_value(
                Filters=[{"Key": "name", "Values": [f"{filter_name}"]}]
            )
            for secret in response["SecretValues"]:
                secrets.append(json.loads(secret["SecretString"]))
            if secrets:
                logger.info("Secrets retrieved successfully.")
            else:
                logger.info("Zero secrets returned without error.")
            return secrets
        except self.client.exceptions.ResourceNotFoundException:
            msg = f"One or more requested secrets were not found with filter: {filter_name}"
            logger.info(msg)
            return msg
        except Exception as e:
            logger.error(f"An unknown error occurred:\n{str(e)}.")
            raise
```

# 使用 .NET 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-net"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

**Topics**
+ [使用 .NET 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-net.md)
+ [使用获取 Secrets Manager 的密钥值 适用于 .NET 的 SDK](retrieving-secrets-net-sdk.md)

# 使用 .NET 和客户端缓存获取 Secrets Manager 密钥值
<a name="retrieving-secrets_cache-net"></a>

在检索密钥时，您可以使用 Secrets Manager 基于 .NET 的缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。由于调用 Secrets Manager 需要付费 APIs，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [获取密钥](retrieving-secrets.md)。

缓存策略为“最近最少使用 (LRU)”，因此当缓存必须丢弃某个密钥时，它会丢弃最近使用最少的密钥。原定设置下，缓存会每小时刷新一次秘密。您可以配置在缓存中[刷新密钥的频率](retrieving-secrets_cache-net-SecretCacheConfiguration.md#retrieving-secrets_cache-net-SecretCacheConfiguration-properties_CacheItemTTL)，也可以[挂钩到密钥检索中](retrieving-secrets_cache-net-ISecretCacheHook.md)以添加更多功能。

一旦释放缓存引用，缓存便不会进行强制垃圾回收。缓存实施不包括缓存失效。缓存实现侧重于缓存本身，而不是侧重加强安全性或以安全性为重点。如果您需要额外的安全性（例如加密缓存中的项目），请使用提供的接口和抽象方法。

要使用该组件，您必须满足以下条件：
+ .NET Framework 4.6.2 或更高版本，或者 .NET Standard 2.0 或更高版本。请参阅 Microsoft .NET 网站上的[下载 .NET](https://dotnet.microsoft.com/en-us/download)。
+ 适用于.NET 的 AWS SDK。请参阅[AWS SDKs](asm_access.md#asm-sdks)。

要下载源代码，请参阅上的 “[.NET 缓存客户端](https://github.com/aws/aws-secretsmanager-caching-net )” GitHub。

要使用缓存，请先对其进行实例化，然后使用 `GetSecretString` 或 `GetSecretBinary` 检索密钥。在连续检索时，缓存将返回密钥的已缓存副本。

**获取缓存包**
+ 请执行以下操作之一：
  + 在您的项目目录中运行下列 .NET CLI 命令。

    ```
    dotnet add package AWSSDK.SecretsManager.Caching --version 1.0.6
    ```
  + 将下列软件包引用添加到您的 `.csproj` 文件中。

    ```
    <ItemGroup>
        <PackageReference Include="AWSSDK.SecretsManager.Caching" Version="1.0.6" />
    </ItemGroup>
    ```

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Topics**
+ [SecretsManagerCache](retrieving-secrets_cache-net-SecretsManagerCache.md)
+ [SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md)
+ [ISecretCacheHook](retrieving-secrets_cache-net-ISecretCacheHook.md)

**Example 检索密钥**  
以下代码示例显示了一种检索名为*MySecret*的密钥的方法。  

```
using Amazon.SecretsManager.Extensions.Caching;

namespace LambdaExample 
{
    public class CachingExample 
    {
        private const string MySecretName ="MySecret";

        private SecretsManagerCache cache = new SecretsManagerCache();

        public async Task<Response>  FunctionHandlerAsync(string input, ILambdaContext context)
        {
            string MySecret = await cache.GetSecretString(MySecretName);
            
            // Use the secret, return success
            
        }
    }
}
```

**Example 配置生存时间 (TTL) 缓存刷新持续时间**  
以下代码示例显示了一种检索名为的密钥*MySecret*并将 TTL 缓存刷新持续时间设置为 24 小时的方法。  

```
using Amazon.SecretsManager.Extensions.Caching;

namespace LambdaExample
{
    public class CachingExample
    {
        private const string MySecretName = "MySecret";
        
        private static SecretCacheConfiguration cacheConfiguration = new SecretCacheConfiguration
        {
            CacheItemTTL = 86400000
        };
        private SecretsManagerCache cache = new SecretsManagerCache(cacheConfiguration);
        public async Task<Response> FunctionHandlerAsync(string input, ILambdaContext context)
        {
            string mySecret = await cache.GetSecretString(MySecretName);

            // Use the secret, return success
        }
    }
}
```

# SecretsManagerCache
<a name="retrieving-secrets_cache-net-SecretsManagerCache"></a>

适用于从 Secrets Manager 请求的密钥的内存中缓存。您使用 [GetSecretString](#retrieving-secrets_cache-net-SecretsManagerCache-methods-GetSecretString) 或 [GetSecretBinary](#retrieving-secrets_cache-net-SecretsManagerCache-methods-GetSecretBinary) 从缓存中检索密钥。您可以通过传入构造函数中的 [SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md) 对象来配置缓存设置。

有关包括示例在内的更多信息，请参阅 [使用 .NET 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-net.md)。

## 构造函数
<a name="retrieving-secrets_cache-net-SecretsManagerCache-constructors"></a>

`public SecretsManagerCache()`  
适用于 `SecretsManagerCache` 对象的默认构造函数。

`public SecretsManagerCache(IAmazonSecretsManager secretsManager)`  
使用 Secrets Manager 客户端（使用提供的 [AmazonSecretsManagerClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TSecretsManagerClient.html) 创建）构造新缓存。使用此构造函数可自定义 Secrets Manager 客户端，例如使用某一特定区域或终端节点。  
**参数**    
secretsManager  
[AmazonSecretsManagerClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TSecretsManagerClient.html)要从中检索机密。

`public SecretsManagerCache(SecretCacheConfiguration config)`  
使用提供的 [SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md) 构造新密钥缓存。使用此构造函数来配置缓存，例如要缓存的密钥数量及其刷新频率。  
**参数**    
config  
一个 [SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md)，其中包含缓存的配置信息。

`public SecretsManagerCache(IAmazonSecretsManager secretsManager, SecretCacheConfiguration config)`  
使用使用提供的[AmazonSecretsManagerClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TSecretsManagerClient.html)和创建的 Secrets Manager 客户端构造新的缓存。[SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md)使用此构造函数可自定义 Secrets Manager 客户端，例如使用某一特定区域或终端节点以及配置缓存，例如要缓存的密钥数量及其刷新频率。  
**参数**    
secretsManager  
[AmazonSecretsManagerClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TSecretsManagerClient.html)要从中检索机密。  
config  
一个 [SecretCacheConfiguration](retrieving-secrets_cache-net-SecretCacheConfiguration.md)，其中包含缓存的配置信息。

## 方法
<a name="retrieving-secrets_cache-net-SecretsManagerCache-methods"></a>

### GetSecretString
<a name="retrieving-secrets_cache-net-SecretsManagerCache-methods-GetSecretString"></a>

 `public async Task<String> GetSecretString(String secretId)`

从 Secrets Manager 中检索字符串密钥。参数

secretId  
要检索的密钥的 ARN 或名称。

### GetSecretBinary
<a name="retrieving-secrets_cache-net-SecretsManagerCache-methods-GetSecretBinary"></a>

`public async Task<byte[]> GetSecretBinary(String secretId)`

从 Secrets Manager 中检索二进制密钥。参数

secretId  
要检索的密钥的 ARN 或名称。

### RefreshNowAsync
<a name="retrieving-secrets_cache-net-SecretsManagerCache-methods-RefreshNowAsync"></a>

`public async Task<bool> RefreshNowAsync(String secretId)`

请从 Secrets Manager 请求密钥值，并使用任何更改更新缓存。如果没有现有的缓存条目，请创建一个新缓存条目。如果刷新成功，则返回 `true`。参数

secretId  
要检索的密钥的 ARN 或名称。

### GetCachedSecret
<a name="retrieving-secrets_cache-net-SecretsManagerCache-methods-GetCachedSecret"></a>

`public SecretCacheItem GetCachedSecret(string secretId)`

返回指定密钥的缓存条目（如果缓存中存在该密钥）。否则，从 Secret Manager 中该检索密钥，并创建一个新缓存条目。参数

secretId  
要检索的密钥的 ARN 或名称。

# SecretCacheConfiguration
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration"></a>

适用于 [SecretsManagerCache](retrieving-secrets_cache-net-SecretsManagerCache.md) 的缓存配置选项，例如最大缓存大小和已缓存密钥的存活时间 (TTL)。

## Properties
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties"></a>

### CacheItemTTL
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties_CacheItemTTL"></a>

`public uint CacheItemTTL { get; set; }`

缓存项目的 TTL（以毫秒为单位）。默认值为 `3600000` 毫秒或 1 小时。最大值为 `4294967295` ms，约为 49.7 天。

### MaxCacheSize
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties_MaxCacheSize"></a>

`public ushort MaxCacheSize { get; set; }`

最大缓存大小。默认值为 1024 个密钥。最大值为 65535。

### VersionStage
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties_VersionStage"></a>

`public string VersionStage { get; set; }`

您要缓存的密钥的版本。有关更多信息，请参阅[密钥版本](whats-in-a-secret.md#term_version)。默认值为 `"AWSCURRENT"`。

### 客户端
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties_Client"></a>

`public IAmazonSecretsManager Client { get; set; }`

[AmazonSecretsManagerClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TSecretsManagerClient.html)要从中检索机密。如果是 `null`，缓存将实例化一个新客户端。默认值为 `null`。

### CacheHook
<a name="retrieving-secrets_cache-net-SecretCacheConfiguration-properties_CacheHook"></a>

`public ISecretCacheHook CacheHook { get; set; }`

一个 [ISecretCacheHook](retrieving-secrets_cache-net-ISecretCacheHook.md)。

# ISecretCacheHook
<a name="retrieving-secrets_cache-net-ISecretCacheHook"></a>

用于挂钩到 [SecretsManagerCache](retrieving-secrets_cache-net-SecretsManagerCache.md) 中以便对存储于缓存中的密钥执行操作的接口。

## 方法
<a name="retrieving-secrets_cache-net-ISecretCacheHook-methods"></a>

### Put
<a name="retrieving-secrets_cache-net-ISecretCacheHook-methods-Put"></a>

`object Put(object o);`

准备对象以存储到缓存中。

返回要存储在缓存中的对象。

### 获取
<a name="retrieving-secrets_cache-net-ISecretCacheHook-methods-Get"></a>

`object Get(object cachedObject);`

从已缓存对象派生对象。

返回要从缓存中返回的对象

# 使用获取 Secrets Manager 的密钥值 适用于 .NET 的 SDK
<a name="retrieving-secrets-net-sdk"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

对于 .NET 应用程序，请使用 [Secrets Manager 基于 .NET 的缓存组件](retrieving-secrets_cache-net.md)或直接使用 [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TGetSecretValueRequest.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TGetSecretValueRequest.html) 或 [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TBatchGetSecretValueRequest.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SecretsManager/TBatchGetSecretValueRequest.html) 调用 SDK。

以下代码示例演示如何使用 `GetSecretValue`。

**所需权限：**`secretsmanager:GetSecretValue`

```
    using System;
    using System.IO;
    using System.Threading.Tasks;
    using Amazon.SecretsManager;
    using Amazon.SecretsManager.Model;

    /// <summary>
    /// This example uses the Amazon Web Service Secrets Manager to retrieve
    /// the secret value for the provided secret name.
    /// </summary>
    public class GetSecretValue
    {
        /// <summary>
        /// The main method initializes the necessary values and then calls
        /// the GetSecretAsync and DecodeString methods to get the decoded
        /// secret value for the secret named in secretName.
        /// </summary>
        public static async Task Main()
        {
            string secretName = "<<{{MySecretName}}>>";
            string secret;

            IAmazonSecretsManager client = new AmazonSecretsManagerClient();

            var response = await GetSecretAsync(client, secretName);

            if (response is not null)
            {
                secret = DecodeString(response);

                if (!string.IsNullOrEmpty(secret))
                {
                    Console.WriteLine($"The decoded secret value is: {secret}.");
                }
                else
                {
                    Console.WriteLine("No secret value was returned.");
                }
            }
        }

        /// <summary>
        /// Retrieves the secret value given the name of the secret to
        /// retrieve.
        /// </summary>
        /// <param name="client">The client object used to retrieve the secret
        /// value for the given secret name.</param>
        /// <param name="secretName">The name of the secret value to retrieve.</param>
        /// <returns>The GetSecretValueReponse object returned by
        /// GetSecretValueAsync.</returns>
        public static async Task<GetSecretValueResponse> GetSecretAsync(
            IAmazonSecretsManager client,
            string secretName)
        {
            GetSecretValueRequest request = new GetSecretValueRequest()
            {
                SecretId = secretName,
                VersionStage = "AWSCURRENT", // VersionStage defaults to AWSCURRENT if unspecified.
            };

            GetSecretValueResponse response = null;

            // For the sake of simplicity, this example handles only the most
            // general SecretsManager exception.
            try
            {
                response = await client.GetSecretValueAsync(request);
            }
            catch (AmazonSecretsManagerException e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }

            return response;
        }

        /// <summary>
        /// Decodes the secret returned by the call to GetSecretValueAsync and
        /// returns it to the calling program.
        /// </summary>
        /// <param name="response">A GetSecretValueResponse object containing
        /// the requested secret value returned by GetSecretValueAsync.</param>
        /// <returns>A string representing the decoded secret value.</returns>
        public static string DecodeString(GetSecretValueResponse response)
        {
            // Decrypts secret using the associated AWS Key Management Service
            // Customer Master Key (CMK.) Depending on whether the secret is a
            // string or binary value, one of these fields will be populated.
            if (response.SecretString is not null)
            {
                var secret = response.SecretString;
                return secret;
            }
            else if (response.SecretBinary is not null)
            {
                var memoryStream = response.SecretBinary;
                StreamReader reader = new StreamReader(memoryStream);
                string decodedBinarySecret = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(reader.ReadToEnd()));
                return decodedBinarySecret;
            }
            else
            {
                return string.Empty;
            }
        }
    }
```

# 使用 Go 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-go"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

**Topics**
+ [使用 Go 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-go.md)
+ [使用 Go AWS SDK 获取 Secrets Manager 密钥值](retrieving-secrets-go-sdk.md)

# 使用 Go 和客户端缓存获取 Secrets Manager 密钥值
<a name="retrieving-secrets_cache-go"></a>

在检索密钥时，您可以使用 Secrets Manager 基于 Go 的缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。由于调用 Secrets Manager 需要付费 APIs，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [获取密钥](retrieving-secrets.md)。

缓存策略为“最近最少使用 (LRU)”，因此当缓存必须丢弃某个密钥时，它会丢弃最近使用最少的密钥。原定设置下，缓存会每小时刷新一次秘密。您可以配置在缓存中[刷新密钥的频率](retrieving-secrets_cache-go_CacheConfig.md)，也可以[挂钩到密钥检索中](retrieving-secrets_cache-go_CacheHook.md)以添加更多功能。

一旦释放缓存引用，缓存便不会进行强制垃圾回收。缓存实施不包括缓存失效。缓存实现侧重于缓存本身，而不是侧重加强安全性或以安全性为重点。如果您需要额外的安全性（例如加密缓存中的项目），请使用提供的接口和抽象方法。

要使用该组件，您必须满足以下条件：
+ AWS 适用于 Go 的 SDK。请参阅[AWS SDKs](asm_access.md#asm-sdks)。

要下载源代码，请参阅 S [ecrets Manager Go 缓存客户端](https://github.com/aws/aws-secretsmanager-caching-go ) GitHub。

要设置 Go 开发环境，请参阅 Go Programming Language 网站上的 [Golang 入门](https://golang.org/doc/install)。

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Topics**
+ [type Cache](retrieving-secrets_cache-go_cache.md)
+ [键入 CacheConfig](retrieving-secrets_cache-go_CacheConfig.md)
+ [键入 CacheHook](retrieving-secrets_cache-go_CacheHook.md)

**Example 检索密钥**  
以下代码示例显示了检索密钥的 Lambda 函数。  

```
package main

import (
	 "github.com/aws/aws-lambda-go/lambda"
	 "github.com/aws/aws-secretsmanager-caching-go/secretcache"
)

var (
	 secretCache, _ = secretcache.New()
)

func HandleRequest(secretId string) string {
	 result, _ := secretCache.GetSecretString(secretId)
	 
	 // Use the secret, return success
}

 func main() {
	 lambda. Start( HandleRequest)
}
```

# type Cache
<a name="retrieving-secrets_cache-go_cache"></a>

适用于从 Secrets Manager 请求的密钥的内存中缓存。您使用 [GetSecretString](#retrieving-secrets_cache-go_cache_operations_GetCachedSecret) 或 [GetSecretBinary](#retrieving-secrets_cache-go_cache_operations_GetSecretBinary) 从缓存中检索密钥。

下面的示例演示了如何配置缓存设置。

```
// Create a custom secretsmanager client
client := getCustomClient()

// Create a custom CacheConfig struct 
config := secretcache. CacheConfig{
    MaxCacheSize:  secretcache.DefaultMaxCacheSize + 10,
    VersionStage:  secretcache.DefaultVersionStage,
    CacheItemTTL:  secretcache.DefaultCacheItemTTL,
}
	
// Instantiate the cache 
cache, _ := secretcache.New(
    func( c *secretcache.Cache) {  c. CacheConfig = config },
    func( c *secretcache.Cache) {  c. Client = client },
)
```

有关包括示例在内的更多信息，请参阅 [使用 Go 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-go.md)。

## 方法
<a name="retrieving-secrets_cache-go_cache_operations"></a>

### New
<a name="retrieving-secrets_cache-go_cache_operations_New"></a>

`func New(optFns ...func(*Cache)) (*Cache, error)`

New 使用功能选项构造密钥缓存，否则将使用默认值。从新会话初始化 SecretsManager 客户端。初始化 CacheConfig 为默认值。使用默认最大大小初始化 LRU 缓存。

### GetSecretString
<a name="retrieving-secrets_cache-go_cache_operations_GetCachedSecret"></a>

`func (c *Cache) GetSecretString(secretId string) (string, error)`

GetSecretString 从缓存中获取给定密钥 ID 的秘密字符串值。返回密钥字符串，如果操作失败则返回错误。

### GetSecretStringWithStage
<a name="retrieving-secrets_cache-go_cache_operations_GetSecretStringWithStage"></a>

`func (c *Cache) GetSecretStringWithStage(secretId string, versionStage string) (string, error)`

GetSecretStringWithStage 从缓存中获取给定密钥 ID 和[版本阶段](whats-in-a-secret.md#term_version)的秘密字符串值。返回密钥字符串，如果操作失败则返回错误。

### GetSecretBinary
<a name="retrieving-secrets_cache-go_cache_operations_GetSecretBinary"></a>

`func (c *Cache) GetSecretBinary(secretId string) ([]byte, error) {`

GetSecretBinary 从缓存中获取给定密钥 ID 的秘密二进制值。返回密钥二进制值，如果操作失败则返回错误。

### GetSecretBinaryWithStage
<a name="retrieving-secrets_cache-go_cache_operations_GetSecretBinaryWithStage"></a>

`func (c *Cache) GetSecretBinaryWithStage(secretId string, versionStage string) ([]byte, error)`

GetSecretBinaryWithStage 从缓存中获取给定密钥 ID 和[版本阶段](whats-in-a-secret.md#term_version)的秘密二进制值。返回密钥二进制值，如果操作失败则返回错误。

# 键入 CacheConfig
<a name="retrieving-secrets_cache-go_CacheConfig"></a>

适用于[缓存](retrieving-secrets_cache-go_cache.md)的缓存配置选项，例如最大缓存大小、默认[版本阶段](whats-in-a-secret.md#term_version)，以及已缓存密钥的存活时间 (TTL)。

```
type CacheConfig struct {

    // The maximum cache size. The default is 1024 secrets.
    MaxCacheSize int
            
    // The TTL of a cache item in nanoseconds. The default is 
    // 3.6e10^12 ns or 1 hour.
    CacheItemTTL int64
            
    // The version of secrets that you want to cache. The default 
    // is "AWSCURRENT".
    VersionStage string
            
    // Used to hook in-memory cache updates.
    Hook CacheHook
}
```

# 键入 CacheHook
<a name="retrieving-secrets_cache-go_CacheHook"></a>

用于挂钩到[缓存](retrieving-secrets_cache-go_cache.md)中以便对存储于缓存中的密钥执行操作的接口。

## 方法
<a name="retrieving-secrets_cache-go_CacheHook_operations"></a>

### Put
<a name="retrieving-secrets_cache-go_CacheHook_operations_Put"></a>

`Put(data interface{}) interface{}`

使对象为存储在缓存中做好准备。

### 获取
<a name="retrieving-secrets_cache-go_CacheHook_operations_Get"></a>

`Get(data interface{}) interface{}`

从已缓存对象派生对象。

# 使用 Go AWS SDK 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-go-sdk"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

对于 Go 应用程序，请使用 [Secrets Manager 基于 Go 的缓存组件](retrieving-secrets_cache-go.md)或直接使用 [https://docs.aws.amazon.com/sdk-for-go/api/service/secretsmanager/#SecretsManager.GetSecretValue](https://docs.aws.amazon.com/sdk-for-go/api/service/secretsmanager/#SecretsManager.GetSecretValue) 或 [https://docs.aws.amazon.com/sdk-for-go/api/service/secretsmanager/#SecretsManager.BatchGetSecretValue](https://docs.aws.amazon.com/sdk-for-go/api/service/secretsmanager/#SecretsManager.BatchGetSecretValue) 调用 SDK。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
  // Use this code snippet in your app.
  // If you need more information about configurations or implementing the sample code, visit the AWS docs:   
  // https://aws.github.io/aws-sdk-go-v2/docs/getting-started/
  
  import (
    "context"
    "log"
  
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/secretsmanager"
  )
  
  func main() {
    secretName := "<<{{MySecretName}}>>"
    region := "<<{{MyRegionName}}>>"
  
    config, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
    if err != nil {
      log.Fatal(err)
    }
  
    // Create Secrets Manager client
    svc := secretsmanager.NewFromConfig(config)
  
    input := &secretsmanager.GetSecretValueInput{
      SecretId:     aws.String(secretName),
      VersionStage: aws.String("AWSCURRENT"), // VersionStage defaults to AWSCURRENT if unspecified
    }
  
    result, err := svc.GetSecretValue(context.TODO(), input)
    if err != nil {
      // For a list of exceptions thrown, see
      // https://<<{{DocsDomain}}>>/secretsmanager/latest/apireference/API_GetSecretValue.html
      log.Fatal(err.Error())
    }
  
    // Decrypts secret using the associated KMS key.
    var secretString string = *result.SecretString
  
    // Your code goes here.
  }
```

# 使用 Rust 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-rust"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

**Topics**
+ [使用 Rust 和客户端缓存获取 Secrets Manager 密钥值](retrieving-secrets_cache-rust.md)
+ [使用 Rust AWS SDK 获取 Secrets Manager 的密钥值](retrieving-secrets-rust-sdk.md)

# 使用 Rust 和客户端缓存获取 Secrets Manager 密钥值
<a name="retrieving-secrets_cache-rust"></a>

在检索密钥时，您可以使用 Secrets Manager 基于 Rust 的缓存组件来缓存密钥，以备将来使用。检索已缓存密钥比从 Secrets Manager 中检索密钥的速度要快。由于调用 Secrets Manager 需要付费 APIs，因此使用缓存可以降低成本。有关检索密钥的所有方法，请参阅 [获取密钥](retrieving-secrets.md)。

缓存策略是先进先出（FIFO），因此当缓存必须丢弃一个密钥时，它会丢弃最旧的密钥。原定设置下，缓存会每小时刷新一次秘密。您可以配置以下内容：
+ `max_size` – 在驱逐最近未访问的密钥之前要维护的最大缓存密钥数。
+ `ttl` – 在需要刷新密钥状态之前缓存的项目被视为有效的持续时间。

缓存实施不包括缓存失效。缓存实现侧重于缓存本身，而不是侧重加强安全性或以安全性为重点。如果需要额外安全性（例如加密缓存中的项目），请使用提供的特性来修改缓存。

要使用该组件，您必须拥有一个带有 `tokio` 的 Rust 2021 开发环境。有关更多信息，请参阅 Rust 编程语言网站上的[入门](https://www.rust-lang.org/learn/get-started)。

要下载源代码，请参阅上的 S [ecrets Manager 基于 Rust 的缓存客户端组件](https://github.com/aws/aws-secretsmanager-agent/tree/main/aws_secretsmanager_caching)。 GitHub

要安装缓存组件，请使用以下命令。

```
cargo add aws_secretsmanager_caching
```

**所需权限：**
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关更多信息，请参阅 [权限参考](auth-and-access.md#reference_iam-permissions)。

**Example 检索密钥**  
以下示例说明如何获取名为的密钥的机密值*MyTest*。  

```
use aws_secretsmanager_caching::SecretsManagerCachingClient;
use std::num::NonZeroUsize;
use std::time::Duration;

let client = match SecretsManagerCachingClient::default(
    NonZeroUsize::new(10).unwrap(),
    Duration::from_secs(60),
)
.await
{
    Ok(c) => c,
    Err(_) => panic!("Handle this error"),
};

let secret_string = match client.get_secret_value("MyTest", None, None).await {
    Ok(s) => s.secret_string.unwrap(),
    Err(_) => panic!("Handle this error"),
};

// Your code here
```

**Example 使用自定义配置和自定义客户端实例化缓存**  
以下示例说明如何配置缓存，然后获取名为的密钥的密钥值*MyTest*。  

```
let config = aws_config::load_defaults(BehaviorVersion::latest())
    .await
    .into_builder()
    .region(Region::from_static("us-west-2"))
    .build();

let asm_builder = aws_sdk_secretsmanager::config::Builder::from(&config);

let client = match SecretsManagerCachingClient::from_builder(
    asm_builder,
    NonZeroUsize::new(10).unwrap(),
    Duration::from_secs(60),
)
.await
{
    Ok(c) => c,
    Err(_) => panic!("Handle this error"),
};

let secret_string = client
    .get_secret_value("MyTest", None, None)
    .await 
    {
        Ok(c) => c.secret_string.unwrap(),
        Err(_) => panic!("Handle this error"),
    };

// Your code here
```
```

# 使用 Rust AWS SDK 获取 Secrets Manager 的密钥值
<a name="retrieving-secrets-rust-sdk"></a>

在应用程序中，您可以通过调用`GetSecretValue`或`BatchGetSecretValue`在任一应用程序中检索您的秘密 AWS SDKs。不过，我们建议您通过使用客户端缓存来缓存您的密钥值。缓存密钥可以提高速度并降低成本。

对于 Rust 应用程序，请使用[基于 Secrets Manager 的 Rust 缓存组件](retrieving-secrets_cache-rust.md)，或者使用或[直接调用 SDK](https://docs.rs/releases/search?query=aws-sdk-secretsmanager)。 GetSecretValue BatchGetSecretValue

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
async fn show_secret(client: &Client, name: &str) -> Result<(), Error> {
    let resp = client.get_secret_value().secret_id(name).send().await?;

    println!("Value: {}", resp.secret_string().unwrap_or("No value!"));

    Ok(())
}
```

# 在亚马逊 Elastic Kubernetes Service 中使用 AWS Secrets Manager 密钥
<a name="integrate_eks"></a>

要将来自 AWS Secrets Manager (ASCP) 的密钥显示为挂载在 Amazon EKS Pod 中的文件，你可以使用 Kubernetes S AWS ecrets Store CSI 驱动程序的密钥和配置提供程序。ASCP 可与运行亚马逊 EC2 节点组的亚马逊 Elastic Kubernetes Service 1.17\$1 配合使用。 AWS Fargate 不支持节点组。使用 ASCP，您可以在 Secrets Manager 中存储并管理密钥，然后通过 Amazon EKS 上运行的工作负载检索。如果密钥包含多个 JSON 格式的键-值对，您可以选择要在 Amazon EKS 中挂载的密钥/值对。ASCP 可使用 JMESPath 语法来查询密钥中的键/值对。ASCP 还适用于 Parameter Store 参数。ASCP 提供两种通过 Amazon EKS 进行身份验证的方法。第一种方法是使用服务账户的 IAM 角色（IRSA），第二种方法是使用容器组身份。每种方法都有其优势和用例。

## 基于服务账户的 IAM 角色（IRSA）的 ASCP
<a name="csi_driver_overview"></a>

具有 IAM 服务账户角色的 ASCP (IRSA) 允许您将密钥 AWS Secrets Manager 作为文件挂载到 Amazon EKS Pod 中。这种方法适用于以下情况：
+ 需要将密钥作为文件挂载到容器组（pod）中时。
+ 将 Amazon EKS 版本 1.17 或更高版本与 Amazon EC2 节点组结合使用时。
+ 希望从 JSON 格式的密钥中检索特定的键-值对时。

有关更多信息，请参阅 [将 AWS 密钥和配置提供商 CSI 与服务账户 IAM 角色配合使用 (IRSA)](integrating_ascp_irsa.md)。

## 基于容器组身份的 ASCP
<a name="pod_identity_overview"></a>

基于容器组身份的 ASCP 方法增强了安全性，简化了访问 Amazon EKS 中密钥的配置。这种方法在以下情况下非常有用：
+ 需要在容器组（pod）级别进行更精细的权限管理时。
+ 使用的是 Amazon EKS 版本 1.24 或更高版本时。
+ 需要提高性能和可扩展性时。

有关更多信息，请参阅 [在 Amazon EKS 中使用带有 Pod 身份的 AWS 密钥和配置提供商 CSI](ascp-pod-identity-integration.md)。

## 选择正确的方法
<a name="comparison"></a>

在基于 IRSA 的 ASCP 和基于容器组身份的 ASCP 之间做选择时，需考虑以下因素：
+ 亚马逊 EKSversion：Pod Identity 需要亚马逊 EKS 1.24\$1，而 CSI 驱动程序适用于亚马逊 EKS 1.17\$1。
+ 安全要求：容器组身份可在容器组（pod）级别提供更精细的控制。
+ 性能：容器组身份通常会在大规模环境中展现更出色的性能。
+ 复杂性：容器组身份无需单独的服务账户，可以简化设置。

选择最符合您的具体要求和 Amazon EKS 环境的方法。

# 安装适用于 Amazon EKS 的 ASCP
<a name="ascp-eks-installation"></a>

本节介绍如何安装适用于 Amazon EKS 的 AWS 密钥和配置提供程序。使用 ASCP，您可以将 Secrets Manager 中的密钥和来自的参数 AWS Systems Manager 作为文件挂载到 Amazon EKS Pods 中。

## 先决条件
<a name="prerequisites"></a>
+ Amazon EKS 集群
  + 容器组身份版本 1.24 或更高版本
  + IRSA 版本 1.17 或更高版本
+ 已 AWS CLI 安装并配置的
+ 已为 Amazon EKS 集群安装并配置 kubectl
+ Helm（版本 3.0 或更高版本）

## 安装和配置 ASCP
<a name="integrating_csi_driver_install"></a>

ASCP 可在 [secrets-store-csi-provider-aws 存储 GitHub 库中找到](https://github.com/aws/secrets-store-csi-driver-provider-aws)。回购还包含用于创建和装载密钥的 YAML 文件示例。

安装过程中，您可以将 ASCP 配置为使用 FIPS 端点。有关 终端节点的列表，请参阅[AWS Secrets Manager 端点](asm_access.md#endpoints)。

**将 ASCP 作为 EKS 附加组件安装**

1. 安装`eksctl`（[安装说明](https://docs.aws.amazon.com/eks/latest/eksctl/installation.html)）

1. 运行以下命令以使用[默认配置](https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/charts/secrets-store-csi-driver-provider-aws/values.yaml)安装插件：

   ```
   eksctl create addon --cluster <your_cluster> --name aws-secrets-store-csi-driver-provider
   ```

   如果您想配置插件，请改为运行以下安装命令：

   ```
   aws eks create-addon --cluster-name <your_cluster> --addon-name aws-secrets-store-csi-driver-provider --configuration-values 'file://path/to/config.yaml'
   ```

   配置文件可以是 YAML 或 JSON 文件。要查看插件的配置架构，请执行以下操作：

   1. 运行以下命令并记下插件的最新版本：

      ```
      aws eks describe-addon-versions --addon-name aws-secrets-store-csi-driver-provider
      ```

   1. 运行以下命令以查看插件的配置架构，`<version>`替换为上一步中的版本：

      ```
      aws eks describe-addon-configuration --addon-name aws-secrets-store-csi-driver-provider --addon-version <version>
      ```

**使用 Helm 安装 ASCP**

1. 为确保存储库指向最新图表，请使用 `helm repo update.`

1. 安装图表。以下是 `helm install` 命令的示例：

   ```
   helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
   ```

   1. 要使用 FIPS 端点，请添加以下标志：`--set useFipsEndpoint=true`

   1. 要配置节流，请添加以下标志：`--set-json 'k8sThrottlingParams={"qps": "number of queries per second", "burst": "number of queries per second"}'`

   1. 如果您的集群上已经安装 Secrets Store CSI 驱动程序，请添加以下标志：`--set secrets-store-csi-driver.install=false`。这会跳过将 Secrets Store CSI 驱动程序作为依赖项进行安装。

**在存储库中使用 YAML 进行安装**
+ 使用以下命令。

  ```
  helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
  helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
  kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/deployment/aws-provider-installer.yaml
  ```

## 验证安装情况
<a name="verify-ascp-installations"></a>

要验证 EKS 集群、Secrets Store CSI 驱动程序和 ASCP 插件的安装情况，请按照以下步骤操作：

1. 验证 EKS 集群的安装情况：

   ```
   eksctl get cluster --name clusterName
   ```

   该命令应返回有关集群的信息。

1. 验证 Secrets Store CSI 驱动程序的安装情况：

   ```
   kubectl get pods -n kube-system -l app=secrets-store-csi-driver
   ```

   您应该看到正在运行的容器组（pod），其名称如下：`csi-secrets-store-secrets-store-csi-driver-xxx`。

1. 验证 ASCP 插件的安装情况：

------
#### [ YAML installation ]

   ```
   $ kubectl get pods -n kube-system -l app=csi-secrets-store-provider-aws
   ```

   输出示例：

   ```
   NAME                                     READY   STATUS    RESTARTS   AGE
   csi-secrets-store-provider-aws-12345      1/1     Running   0          2m
   ```

------
#### [ Helm installation ]

   ```
   $  kubectl get pods -n kube-system -l app=secrets-store-csi-driver-provider-aws
   ```

   输出示例：

   ```
   NAME                                              READY   STATUS    RESTARTS   AGE
   secrets-provider-aws-secrets-store-csi-driver-provider-67890       1/1     Running   0          2m
   ```

------

   您应该看到处于 `Running` 状态的容器组（pod）。

运行这些命令后，如果一切设置正确，您应该会看到所有组件都在运行，且没有任何错误。如果遇到任何问题，可能需要通过查看出现问题的特定容器组（pod）的日志来进行故障排除。

## 问题排查
<a name="troubleshooting"></a>

1. 要查看 ASCP 提供者的日志，请运行：

   ```
   kubectl logs -n kube-system -l app=csi-secrets-store-provider-aws
   ```

1. 检查 `kube-system` 命名空间中所有容器组（pod）的状态：

   ```
   kubectl -n kube-system get pods
   ```

   ```
   kubectl -n kube-system logs pod/PODID
   ```

   所有与 CSI 驱动程序和 ASCP 相关的容器组（pod）都应处于“正在运行”状态。

1. 检查 CSI 驱动程序版本：

   ```
   kubectl get csidriver secrets-store.csi.k8s.io -o yaml
   ```

   该命令应返回有关已安装的 CSI 驱动程序的信息。

## 其他资源
<a name="additional-resources"></a>

有关将 ASCP 与 Amazon EKS 结合使用的更多信息，请参阅以下资源：
+ [将容器组身份与 Amazon EKS 结合使用](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html)
+ [AWS 秘密商店 CSI 驱动程序开启 GitHub](https://github.com/aws/secrets-store-csi-driver-provider-aws)

# 在 Amazon EKS 中使用带有 Pod 身份的 AWS 密钥和配置提供商 CSI
<a name="ascp-pod-identity-integration"></a>

 AWS 机密和配置提供程序与适用于 Amazon Elastic Kubernetes Service 的 Pod 身份代理集成，为在 Amazon EKS 上运行的应用程序提供了增强的安全性、简化的配置和更高的性能。Pod Identity 在从 Secrets Manager 检索密钥或从 Parameter Stor AWS Systems Manager e 检索参数时简化了 Amazon EKS 的

Amazon EKS 容器组身份通过直接在 Amazon EKS 接口设置权限，减少了操作步骤，且无需在 Amazon EKS 和 IAM 服务之间切换，从而简化了为 Kubernetes 应用程序配置 IAM 权限的过程。容器组身份允许在多个集群中共用一个 IAM 角色而无需更新信任策略，并支持[角色会话标签](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html#pod-id-abac-tags)以实现更精细的访问控制。这种方法不仅允许跨角色重复使用权限策略，从而简化了策略管理，而且还通过允许基于匹配标签访问 AWS 资源来增强安全性。

## 工作原理
<a name="how-it-works"></a>

1. 容器组身份会为容器组（pod）分配 IAM 角色。

1. ASCP 使用此角色进行身份验证。 AWS 服务

1. 如果获得授权，ASCP 会检索请求的密钥并将其提供给容器组（pod）。

有关更多信息，请参阅《Amazon EKS 用户指南**》中的[了解 Amazon EKS 容器组身份的工作原理](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html)。

## 先决条件
<a name="prerequisites"></a>

**重要**  
仅云中的 Amazon EKS 支持容器组身份。[Amazon EKS Anywhere](https://aws.amazon.com/eks/eks-anywhere/)、[AWS 云端 Red Hat OpenShift 服务](https://aws.amazon.com/rosa/) 或 Amazon EC2 实例上自行管理的 Kubernetes 集群不支持容器组身份。
+ Amazon EKS 集群（版本 1.24 或更高版本）
+ 通过以下方式访问 AWS CLI 和 Amazon EKS 集群 `kubectl`
+ 访问两个 AWS 账户 （用于跨账户访问）

## 安装 Amazon EKS 容器组身份代理
<a name="install-pod-identity-agent"></a>

要将容器组身份与集群结合使用，必须安装 Amazon EKS 容器组身份代理附加组件。

**安装容器组身份代理**
+ 在集群上安装容器组身份代理附加组件：

  ```
  eksctl create addon \
    --name eks-pod-identity-agent \
    --cluster clusterName \
    --region region
  ```

## 通过容器组身份设置 ASCP
<a name="pod-identity-setup"></a>

1. 创建一个权限策略，授予对容器组（pod）需要访问的密钥的 `secretsmanager:GetSecretValue` 和 `secretsmanager:DescribeSecret` 权限。有关策略示例，请参阅 [示例：读取和描述个人密钥的权限](auth-and-access_iam-policies.md#auth-and-access_examples-read-and-describe)。

1. 创建可由容器组身份的 Amazon EKS 服务主体担任的 IAM 角色：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
         {
           "Effect": "Allow",
           "Principal": {
             "Service": "pods.eks.amazonaws.com"
           },
           "Action": [
             "sts:AssumeRole",
             "sts:TagSession"
           ]
         }
       ]
     }
   ```

------

   向角色附加 IAM 策略：

   ```
   aws iam attach-role-policy \
     --role-name MY_ROLE \
     --policy-arn POLICY_ARN
   ```

1. 创建容器组身份关联。有关示例，请参阅《Amazon EKS 用户指南**》中的[创建容器组身份关联](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-association.html#pod-id-association-create)

1. 创建 `SecretProviderClass`，用于指定要挂载到容器组（pod）中的密钥：

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/examples/ExampleSecretProviderClass-PodIdentity.yaml
   ```

   IRSA 和容器组身份在 `SecretProviderClass` 中的关键区别在于可选参数 `usePodIdentity`。这是一个可选字段，用于确定身份验证方法。如果未指定，则默认对服务账户（IRSA）使用 IAM 角色。
   + 要使用 EKS 容器组身份，请使用以下任意值：`"true", "True", "TRUE", "t", "T"`。
   + 要明确使用 IRSA，请将其设置为以下任意值：`"false", "False", "FALSE", "f", or "F"`。

1. 部署挂载 `/mnt/secrets-store` 下的密钥的容器组（pod）：

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/examples/ExampleDeployment-PodIdentity.yaml
   ```

1. 如果您使用私有 Amazon EKS 集群，请确保集群所在的 VPC 具有 AWS STS 终端节点。有关创建端点的信息，请参阅《*AWS Identity and Access Management 用户指南*》中的[接口 VPC 端点](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_interface_vpc_endpoints.html)。

### 验证密钥的挂载情况
<a name="verify-secret-mount"></a>

要验证密钥是否正确挂载，请运行以下命令：

```
kubectl exec -it $(kubectl get pods | awk '/pod-identity-deployment/{print $1}' | head -1) -- cat /mnt/secrets-store/MySecret
```

**设置 Amazon EKS 容器组身份以访问 Secrets Manager 中的密钥**

1. 创建一个权限策略，授予对容器组（pod）需要访问的密钥的 `secretsmanager:GetSecretValue` 和 `secretsmanager:DescribeSecret` 权限。有关策略示例，请参阅 [示例：读取和描述个人密钥的权限](auth-and-access_iam-policies.md#auth-and-access_examples-read-and-describe)。

1. 在 Secrets Manager 中创建密钥（如果您还没有一个密钥）。

## 故障排除
<a name="integrating_aspc_pod_trouble"></a>

您可以通过描述容器组（pod）部署来查看大多数错误。

**查看容器的错误消息**

1. 使用以下命令获取容器组（pod）名称列表。如果您没有使用默认命名空间，请使用 `-n NAMESPACE`。

   ```
   kubectl get pods
   ```

1. 要描述 Pod，请在以下命令中*PODID*使用您在上一步中找到的 Pod 中的 Pod ID。如果没有使用默认命名空间，请使用 `-n NAMESPACE`。

   ```
   kubectl describe pod/PODID
   ```

**查看 ASCP 的错误**
+ 要在提供者日志中查找更多信息，请在以下命令中*PODID*使用 *csi-secrets-store-provider-aws Pod 的* ID。

  ```
  kubectl -n kube-system get pods
  kubectl -n kube-system logs pod/PODID
  ```

# 将 AWS 密钥和配置提供商 CSI 与服务账户 IAM 角色配合使用 (IRSA)
<a name="integrating_ascp_irsa"></a>

**Topics**
+ [先决条件](#prerequisites)
+ [设置访问控制](#integrating_ascp_irsa_access)
+ [确定要挂载的密钥](#integrating_ascp_irsa_mount)
+ [故障排除](#integrating_ascp_irsa_trouble)

## 先决条件
<a name="prerequisites"></a>
+ Amazon EKS 集群（版本 1.17 或更高版本）
+ 通过以下方式访问 AWS CLI 和 Amazon EKS 集群 `kubectl`

## 设置访问控制
<a name="integrating_ascp_irsa_access"></a>

ASCP 会检索 Amazon EKS 容器组身份并将其交换为 IAM 角色。您可以在 IAM 策略中为该 IAM 角色设置权限。当 ASCP 代入 IAM 角色时，它可以访问您授权的密钥。除非将其与 IAM 角色关联，否则其他容器无法访问密钥。

**授予 Amazon EKS 容器组（pod）对 Secrets Manager 中密钥的访问权限**

1. 创建一个权限策略，授予对容器组（pod）需要访问的密钥的 `secretsmanager:GetSecretValue` 和 `secretsmanager:DescribeSecret` 权限。有关策略示例，请参阅 [示例：读取和描述个人密钥的权限](auth-and-access_iam-policies.md#auth-and-access_examples-read-and-describe)。

1. 为集群创建 IAM OpenID Connect (OIDC) 提供商（如果还没有）。有关更多信息，请参阅《*Amazon EKS 用户指南*》中的[为集群创建 IAM OIDC 提供商](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)。

1. [为服务账户创建一个 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)并将策略附加到该角色。有关更多信息，请参阅《*Amazon EKS 用户指南*》中的[为服务账户创建 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)。

1. 如果您使用私有 Amazon EKS 集群，请确保集群所在的 VPC 具有 AWS STS 终端节点。有关创建端点的信息，请参阅《*AWS Identity and Access Management 用户指南*》中的[接口 VPC 端点](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_interface_vpc_endpoints.html)。

## 确定要挂载的密钥
<a name="integrating_ascp_irsa_mount"></a>

要确定 ASCP 将哪些密钥作为文件系统上的文件挂载在 Amazon EKS 中，您需要创建一个 [SecretProviderClass](ascp-examples.md#ascp-examples-secretproviderclass) YAML 文件。`SecretProviderClass` 列出了要挂载的密钥以及要挂载这些密钥的文件名。`SecretProviderClass` 必须与该文件引用的 Amazon EKS 容器组（pod）位于同一命名空间。

### 将密钥作为文件进行挂载
<a name="mount-secrets"></a>

[以下说明说明如何使用示例 YAML 文件.yaml 和 [ExampleSecretProviderClass.yaml 将密钥挂载为文件。](https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/examples/ExampleSecretProviderClass-IRSA.yaml) ExampleDeployment](https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/examples/ExampleDeployment-IRSA.yaml)

**在 Amazon EKS 中挂载密钥**

1. 将 `SecretProviderClass` 应用于容器组（pod）：

   ```
   kubectl apply -f ExampleSecretProviderClass.yaml
   ```

1. 部署容器组（pod）：

   ```
   kubectl apply -f ExampleDeployment.yaml
   ```

1. ASCP 会挂载文件。

## 故障排除
<a name="integrating_ascp_irsa_trouble"></a>

您可以通过描述容器组（pod）部署来查看大多数错误。

**查看容器的错误消息**

1. 使用以下命令获取容器组（pod）名称列表。如果您没有使用默认命名空间，请使用 `-n nameSpace`。

   ```
   kubectl get pods
   ```

1. 要描述 Pod，请在以下命令中*podId*使用您在上一步中找到的 Pod 中的 Pod ID。如果没有使用默认命名空间，请使用 `-n nameSpace`。

   ```
   kubectl describe pod/podId
   ```

**查看 ASCP 的错误**
+ 要在提供者日志中查找更多信息，请在以下命令中*podId*使用 *csi-secrets-store-provider-aws Pod 的* ID。

  ```
  kubectl -n kube-system get pods
  kubectl -n kube-system logs Pod/podId
  ```
+ 

**验证是否已安装 `SecretProviderClass` CRD：**

  ```
  kubectl get crd secretproviderclasses.secrets-store.csi.x-k8s.io
  ```

  该命令应返回有关 `SecretProviderClass` 自定义资源定义的信息。
+ 

**验证 SecretProviderClass 对象是否已创建。**

  ```
  kubectl get secretproviderclass SecretProviderClassName -o yaml
  ```

# AWS 机密和配置提供程序代码示例
<a name="ascp-examples"></a>

## ASCP 身份验证和访问控制示例
<a name="ascp-auth-access-examples"></a>

### 示例：允许 Amazon EKS 容器组身份服务（pods.eks.amazonaws.com）担任角色并标记会话的 IAM 策略：
<a name="w2aac19c17c18b5b3"></a>

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "pods.eks.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole",
        "sts:TagSession"
      ]
    }
  ]
}
```

------

## SecretProviderClass
<a name="ascp-examples-secretproviderclass"></a>

您可以使用 YAML 描述要使用 ASCP 在 Amazon EKS 中挂载哪些密钥。有关示例，请参阅 [SecretProviderClass 用法](#ascp-scenarios-secretproviderclass)。

### SecretProviderClass YAML 结构
<a name="w2aac19c17c18c25b5"></a>

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
   name: name
spec:
  provider: aws
  parameters:
    region:
    failoverRegion:
    pathTranslation:
    usePodIdentity:
    preferredAddressType:
    objects:
```

参数字段包含挂载请求的详细信息：

**region**  
（可选）机密 AWS 区域 中的一个。如果不使用此字段，ASCP 将从节点上的注释中查找 “区域”。查找会增加挂载请求的开销，因此我们建议为使用大量容器组（pod）的集群提供区域。  
如果您还指定 `failoverRegion`，ASCP 会尝试从两个区域检索密钥。如果任一区域返回 4xx 错误（例如身份验证问题），ASCP 都不会挂载任何一个密钥。如果成功从 `region` 中检索到密钥，则 ASCP 会挂载该密钥值。如果未成功从 `region` 中检索到密钥，但已成功从 `failoverRegion` 中检索到密钥，则 ASCP 会挂载该密钥值。

**failoverRegion**  
（可选）如果您包含此字段，ASCP 会尝试从 `region` 中定义的区域和此字段检索密钥。如果任一区域返回 4xx 错误（例如身份验证问题），ASCP 都不会挂载任何一个密钥。如果成功从 `region` 中检索到密钥，则 ASCP 会挂载该密钥值。如果未成功从 `region` 中检索到密钥，但已成功从 `failoverRegion` 中检索到密钥，则 ASCP 会挂载该密钥值。有关如何使用此字段的示例，请参阅 [多区域密钥失效转移](#multi-region-failover)。

**pathTranslation**  
（可选）如果 Amazon EKS 中的文件名包含路径分隔符则要使用的单个替换字符，例如 Linux 上的斜杠 (/)。ASCP 无法创建包含路径分隔符的挂载文件。相反，ASCP 使用不同的字符替换路径分隔符。如果不使用此字段，替换字符为下划线 (\$1)，因此，例如 `My/Path/Secret` 挂载为 `My_Path_Secret`。  
要防止字符替换，请输入字符串 `False`。

**usePodIdentity**  
（可选）确定身份验证方法。如果未指定，则默认为服务账户（IRSA）的 IAM 角色。  
+ 要使用 EKS 容器组身份，请使用以下任意值：`"true"`、`"True"`、`"TRUE"`、`"t"` 或 `"T"`。
+ 要明确使用 IRSA，请设置为以下任意值：`"false"`、`"False"`、`"FALSE"`、`"f"` 或 `"F"`。

**preferredAddressType**  
（可选）指定容器组身份代理端点通信的首选 IP 地址类型。该字段仅在使用 EKS 容器组身份功能时适用，使用服务账户的 IAM 角色时将忽略。值不区分大小写。有效值为：  
+ `"ipv4"`、`"IPv4"` “或 `"IPV4"` — 强制使用 Pod Identity Agent IPv4 端点
+ `"ipv6"``"IPv6"`、或 `"IPV6"` — 强制使用 Pod Identity Agent IPv6 端点
+ 未指定 — 使用 auto 端点选择，先尝试 IPv4 端点，如果 IPv4 失败则回退到 IPv6 端点

**对象**  
包含要挂载密钥的 YAML 声明字符串。我们建议使用 YAML 多行字符串或竖线 (\$1) 字符。    
**objectName**  
必需。指定要获取的密钥或参数的名称。对于 Secrets Manager，这是 [https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html#API_GetSecretValue_RequestParameters](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html#API_GetSecretValue_RequestParameters) 参数，可以是密钥的友好名称，也可以是完整 ARN。对于 SSM Parameter Store，这是参数的 [https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html#API_GetParameter_RequestParameters](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html#API_GetParameter_RequestParameters)，可以是参数名称，也可以是完整 ARN。  
**objectType**  
如果不将 Secrets Manager ARN 用于 `objectName`，需要这个操作 可以是 `secretsmanager` 或 `ssmparameter`。  
**objectAlias**  
（可选）Amazon EKS 容器组（pod）中密钥的文件名。如果不指定此字段，则 `objectName` 作为文件名显示。  
**filePermission**  
（可选）4 位八进制字符串，指定用于挂载密钥的文件权限。如果您没有指定此字段，它将默认为 `"0644"`。  
**ObjectVersion**  
（可选）密钥的版本 ID。不推荐，因为每次更新密钥时都必须更新版本 ID。默认情况下，使用最新版本。如果包括 `failoverRegion`，则此字段表示主 `objectVersion`。  
**objectVersionLabel**  
（可选）版本的别名。默认为最新版本 AWSCURRENT。有关更多信息，请参阅 [密钥版本](whats-in-a-secret.md#term_version)。如果包括 `failoverRegion`，则此字段表示主 `objectVersionLabel`。  
**JMESPath**  
（可选）密钥中的键映射到要在 Amazon EKS 中挂载的文件。要使用此字段，密钥值必须采用 JSON 格式。如果使用此字段，必须包含子字段 `path` 和 `objectAlias`。    
**path**  
来自密钥值 JSON 中的键-值对的键。如果该字段包含连字符，请使用单引号对其进行转义，例如：`path: '"hyphenated-path"'`  
**objectAlias**  
要挂载到 Amazon EKS 容器组（pod）中的文件名。如果该字段包含连字符，请使用单引号对其进行转义，例如：`objectAlias: '"hyphenated-alias"'`  
**filePermission**  
（可选）4 位八进制字符串，指定用于挂载密钥的文件权限。如果未指定此字段，则其默认为父对象的文件权限。  
**failoverObject**  
（可选）如果您指定此字段，ASCP 会尝试检索主 `objectName` 中指定的密钥和 `failoverObject` `objectName` 子字段中指定的密钥。如果任何一个返回 4xx 错误（例如身份验证问题），ASCP 都不会挂载任何一个密钥。如果成功从主 `objectName` 中检索到密钥，则 ASCP 会挂载该密钥值。如果未成功从主 `objectName` 中检索到密钥，但已成功从失效转移 `objectName` 中检索到密钥，则 ASCP 会挂载该密钥值。如果包含此字段，责必须包含字段 `objectAlias`。有关如何使用此字段的示例，请参阅 [失效转移到其他密钥](#failover-secret)。  
当失效转移密钥不是副本时，通常使用此字段。有关如何指定副本的示例，请参阅 [多区域密钥失效转移](#multi-region-failover)。    
**objectName**  
失效转移密钥的名称或完整 ARN。如果使用 ARN，则 ARN 中的区域必须与字段 `failoverRegion` 匹配。  
**ObjectVersion**  
（可选）密钥的版本 ID。必须与主 `objectVersion` 匹配。不推荐，因为每次更新密钥时都必须更新版本 ID。默认情况下，使用最新版本。  
**objectVersionLabel**  
（可选）版本的别名。默认为最新版本 AWSCURRENT。有关更多信息，请参阅 [密钥版本](whats-in-a-secret.md#term_version)。

### 创建基本 SecretProviderClass 配置以在您的 Amazon EKS 容器中挂载密钥。
<a name="w2aac19c17c18c25c11"></a>

------
#### [ Pod Identity ]

SecretProviderClass 要在同一 Amazon EKS 集群中使用密钥，请执行以下操作：

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets-manager
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "mySecret"
        objectType: "secretsmanager"
    usePodIdentity: "true"
```

------
#### [ IRSA ]

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: deployment-aws-secrets
spec:
  provider: aws
  parameters:
    objects: |
        - objectName: "MySecret"
          objectType: "secretsmanager"
```

------

### SecretProviderClass 用法
<a name="ascp-scenarios-secretproviderclass"></a>

使用这些示例为不同的场景创建 SecretProviderClass 配置。

#### 示例：按名称或 ARN 挂载密钥
<a name="mount-by-name-arn"></a>

此示例说明了如何挂载三种不同类型的密钥：
+ 由完整 ARN 指定的密钥
+ 由名称指定的密钥
+ 密钥的特定版本

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "arn:aws:secretsmanager:us-east-2:777788889999:secret:MySecret2-d4e5f6"
      - objectName: "MySecret3"
        objectType: "secretsmanager"
      - objectName: "MySecret4"
        objectType: "secretsmanager"
        objectVersionLabel: "AWSCURRENT"
```

#### 示例：从密钥挂载键-值对
<a name="mount-key-value-pairs"></a>

此示例说明了如何从 JSON 格式的密钥挂载特定的键-值对：

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "arn:aws:secretsmanager:us-east-2:777788889999:secret:MySecret-a1b2c3"
        jmesPath: 
            - path: username
              objectAlias: dbusername
            - path: password
              objectAlias: dbpassword
```

#### 示例：按文件权限挂载密钥
<a name="mount-by-permission"></a>

此示例说明了如何使用特定文件权限挂载密钥

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "mySecret"
        objectType: "secretsmanager"
        filePermission: "0600"
        jmesPath: 
            - path: username
              objectAlias: dbusername
              filePermission: "0400"
```

#### 示例：失效转移配置示例
<a name="failover-examples"></a>

此示例说明了如何为密钥配置失效转移。

##### 多区域密钥失效转移
<a name="multi-region-failover"></a>

此示例说明了如何为跨多个区域复制的密钥配置自动失效转移：

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    region: us-east-1
    failoverRegion: us-east-2
    objects: |
      - objectName: "MySecret"
```

##### 失效转移到其他密钥
<a name="failover-secret"></a>

此示例说明了如何将失效转移配置为其他密钥（并非副本）：

```
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    region: us-east-1
    failoverRegion: us-east-2
    objects: |
      - objectName: "arn:aws:secretsmanager:us-east-1:777788889999:secret:MySecret-a1b2c3"
        objectAlias: "MyMountedSecret"
        failoverObject: 
          - objectName: "arn:aws:secretsmanager:us-east-2:777788889999:secret:MyFailoverSecret-d4e5f6"
```

## 其他资源
<a name="additional-resources"></a>

有关将 ASCP 与 Amazon EKS 结合使用的更多信息，请参阅以下资源：
+ [将容器组身份与 Amazon EKS 结合使用](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html)
+ [使用 AWS 密钥和配置提供程序](https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_ascp_csi.html)
+ [AWS 秘密商店 CSI 驱动程序开启 GitHub](https://github.com/aws/secrets-store-csi-driver-provider-aws)

# 在 AWS Lambda 函数中使用 AWS Secrets Manager 密钥
<a name="retrieving-secrets_lambda"></a>

AWS Lambda 是一项无服务器计算服务，允许您在不预配置或管理服务器的情况下运行代码。Parameter Store 是一项 AWS Systems Manager功能，它为配置数据管理和密钥管理提供安全的分层存储。您可以使用 AWS 参数和密钥 Lambda 扩展来检索和缓存 Lambda 函数中的 AWS Secrets Manager 密钥和参数存储参数，而无需使用软件开发工具包。有关使用此扩展的详细信息，请参阅 *Lambda 开发人员指南*中的[在 Lambda 函数中使用 Secrets Manager 密钥](https://docs.aws.amazon.com/lambda/latest/dg/with-secrets-manager.html)。

## 将 Lambda 与 Secrets Manager 密钥结合使用
<a name="retrieving-secrets_lambda_getting-started"></a>

《Lambda 开发人员指南》提供了在 Lambda 函数中使用 Secrets Manager 密钥的全面说明。开始使用：

1. 按照在 [Lambda 函数中使用 Secrets Manager 密钥中的 step-by-step](https://docs.aws.amazon.com/lambda/latest/dg/with-secrets-manager.html)教程进行操作，其中包括：
   + 使用首选的运行时（Python、Node.js、Java）创建 Lambda 函数
   + 将 AWS 参数和密钥 Lambda 扩展作为一个层添加
   + 配置必要的权限
   + 编写代码以从扩展中检索密钥
   + 测试函数

1. 了解用于配置扩展行为的环境变量，包括缓存设置和超时

1. 了解使用密钥轮换的最佳实践

### 在 VPC 中使用 Secrets Manager 和 Lambda
<a name="retrieving-secrets_lambda_vpc"></a>

如果 Lambda 函数在 VPC 中运行，您需要创建一个 VPC 端点才能调用 Secrets Manager。有关更多信息，请参阅 [使用 AWS Secrets Manager VPC 终端节点](vpc-endpoint-overview.md)。

## 使用 AWS 参数和密钥 Lambda 扩展
<a name="retrieving-secrets_lambda_parameter-store"></a>

该扩展可以检索 Secrets Manager 密钥和 Parameter Store 参数。有关将扩展与 Parameter Store 参数结合使用的详细信息，请参阅 *AWS Systems Manager 用户指南*中的[在 Lambda 函数中使用 Parameter Store 参数](https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html)。

Systems Manager 文档包括：
+ 详细说明该扩展如何与 Parameter Store 配合使用
+ 将扩展添加到 Lambda 函数的说明
+ 用于配置扩展的环境变量
+ 用于检索参数的示例命令
+ 所有支持的架构和区域 ARNs 的扩展完整列表

# 使用代 AWS Secrets Manager 理
<a name="secrets-manager-agent"></a>

## Secrets Manager 代理的工作原理
<a name="agent-overview"></a>

 AWS Secrets Manager 代理是一项客户端 HTTP 服务，可帮助您标准化在计算环境中使用 Secrets Manager 中的密钥的方式。您可以将以下服务与该密钥一起使用：
+ AWS Lambda
+ Amazon Elastic Container Service
+ Amazon Elastic Kubernetes Service
+ Amazon Elastic Compute Cloud

Secrets Manager 代理检索密钥并将其缓存在内存中，从而可让您的应用程序从本地主机获取密钥，而不必直接调用 Secrets Manager。Secrets Manager 代理只能读取密钥，而无法对其进行修改。

**重要**  
Secrets Manager Agent 使用您环境中的 AWS 凭据调用 Secrets Manager。它包括针对服务器端请求伪造（SSRF）的保护，以协助改进密钥安全性。默认情况下，Secrets Manager 代理使用后量子 ML-KEM 密钥交换作为优先级最高的密钥交换方式。

## 了解 Secrets Manager 代理缓存
<a name="agent-caching"></a>

Secrets Manager 代理使用内存缓存，该缓存会在 Secrets Manager 代理重启时重置。它会根据以下条件定期刷新缓存的密钥值：
+ 默认刷新频率（TTL）为 300 秒
+ 您可以使用配置文件修改 TTL
+ 在 TTL 过期后请求密钥时，就会发生刷新

**注意**  
Secrets Manager 代理不包括缓存失效。如果密钥在缓存条目过期之前轮换，则 Secrets Manager 代理可能会返回过时的密钥值。

Secrets Manager 代理返回的密钥值与 `GetSecretValue` 的响应格式相同。密钥值在缓存中未进行加密。

**Topics**
+ [Secrets Manager 代理的工作原理](#agent-overview)
+ [了解 Secrets Manager 代理缓存](#agent-caching)
+ [构建 Secrets Manager 代理](#secrets-manager-agent-build)
+ [安装 Secrets Manager 代理](#secrets-manager-agent-install)
+ [使用 Secrets Manager 代理检索密钥](#secrets-manager-agent-call)
+ [了解 `refreshNow` 参数](#secrets-manager-agent-refresh)
+ [配置 Secrets Manager 代理](#secrets-manager-agent-config)
+ [可选功能](#secrets-manager-agent-features)
+ [日志记录](#secrets-manager-agent-log)
+ [安全注意事项](#secrets-manager-agent-security)

## 构建 Secrets Manager 代理
<a name="secrets-manager-agent-build"></a>

在开始之前，请确保您已为自己的平台安装标准开发工具和 Rust 工具。

**注意**  
目前，在 macOS 上构建启用 `fips` 功能的代理需要以下解决方法：  
创建名为 `SDKROOT` 的环境变量，该变量设置为运行 `xcrun --show-sdk-path` 的结果

------
#### [ RPM-based systems ]

**在基于 RPM 的系统上构建**

1. 使用存储库中提供的 `install` 脚本。

   该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 `/var/run/awssmatoken` 中。安装脚本创建的 `awssmatokenreader` 组可以读取该令牌。

1. 要允许您的应用程序读取令牌文件，您需要将应用程序在其下运行的用户账户添加到 `awssmatokenreader` 组。例如，您可以使用以下 usermod 命令授予应用程序读取令牌文件的权限，其中*<APP\$1USER>*是运行应用程序的用户 ID。

   ```
   sudo usermod -aG awssmatokenreader <APP_USER>
   ```

**安装开发工具**  
在基于 RPM 的系统上 AL2023，例如安装开发工具组：

   ```
   sudo yum -y groupinstall "Development Tools"
   ```

1. 

**安装 Rust**  
按照 *Rust 文档*中[安装 Rust](https://www.rust-lang.org/tools/install) 的说明进行操作：

   ```
   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions
   . "$HOME/.cargo/env"
   ```

1. 

**构建代理**  
使用 cargo build 命令构建 Secrets Manager 代理：

   ```
   cargo build --release
   ```

   您将在 `target/release/aws_secretsmanager_agent` 下找到可执行文件。

------
#### [ Debian-based systems ]

**在基于 Debian 的系统上构建**

1. 

**安装开发工具**  
在基于 Debian 的系统（例如 Ubuntu）上，安装 build-essential 包：

   ```
   sudo apt install build-essential
   ```

1. 

**安装 Rust**  
按照 *Rust 文档*中[安装 Rust](https://www.rust-lang.org/tools/install) 的说明进行操作：

   ```
   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions
   . "$HOME/.cargo/env"
   ```

1. 

**构建代理**  
使用 cargo build 命令构建 Secrets Manager 代理：

   ```
   cargo build --release
   ```

   您将在 `target/release/aws_secretsmanager_agent` 下找到可执行文件。

------
#### [ Windows ]

**在 Windows 上构建**

1. 

**设置开发环境**  
按照 *Microsoft Windows 文档*中的 [在 Windows 上针对 Rust 设置开发环境](https://learn.microsoft.com/en-us/windows/dev-environment/rust/setup)中的说明进行操作。

1. 

**构建代理**  
使用 cargo build 命令构建 Secrets Manager 代理：

   ```
   cargo build --release
   ```

   您将在 `target/release/aws_secretsmanager_agent.exe` 下找到可执行文件。

------
#### [ Cross-compile natively ]

**本机交叉编译**

1. 

**安装交叉编译工具**  
在 mingw-w64 包可用的发行版（例如 Ubuntu）上，安装交叉编译工具链：

   ```
   # Install the cross compile tool chain
   sudo add-apt-repository universe
   sudo apt install -y mingw-w64
   ```

1. 

**添加 Rust 构建目标**  
安装 Windows GNU 编译目标：

   ```
   rustup target add x86_64-pc-windows-gnu
   ```

1. 

**针对 Windows 构建**  
交叉编译适用于 Windows 的代理：

   ```
   cargo build --release --target x86_64-pc-windows-gnu
   ```

   您将在 `target/x86_64-pc-windows-gnu/release/aws_secretsmanager_agent.exe` 处找到可执行文件。

------
#### [ Cross compile with Rust cross ]

**使用 Rust 交叉进行交叉编译**

如果系统本机没有交叉编译工具，则可以使用 Rust 交叉项目。有关更多信息，请参阅 c [https://github.com/cross-rs/ross](https://github.com/cross-rs/cross)。
**重要**  
我们建议为构建环境提供 32GB 的磁盘空间。

1. 

**设置 Docker**  
安装和配置 Docker：

   ```
   # Install and start docker
   sudo yum -y install docker
   sudo systemctl start docker
   sudo systemctl enable docker # Make docker start after reboot
   ```

1. 

**配置 Docker 权限**  
将用户添加到 Docker 组：

   ```
   # Give ourselves permission to run the docker images without sudo
   sudo usermod -aG docker $USER
   newgrp docker
   ```

1. 

**针对 Windows 构建**  
安装交叉并构建可执行文件：

   ```
   # Install cross and cross compile the executable
   cargo install cross
   cross build --release --target x86_64-pc-windows-gnu
   ```

------

## 安装 Secrets Manager 代理
<a name="secrets-manager-agent-install"></a>

从以下安装选项中选择您的计算环境。

------
#### [ Amazon EC2 ]

**在 Amazon EC2 上安装 Secrets Manager 代理**

1. 

**导航到配置目录**  
更改到配置目录：

   ```
   cd aws_secretsmanager_agent/configuration
   ```

1. 

**运行安装脚本**  
运行存储库中提供的 `install` 脚本。

   该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 `/var/run/awssmatoken` 中。安装脚本创建的 `awssmatokenreader` 组可以读取该令牌。

1. 

**配置应用程序权限**  
将运行应用程序的用户账户添加到 `awssmatokenreader` 组中：

   ```
   sudo usermod -aG awssmatokenreader APP_USER
   ```

   *APP\$1USER*替换为运行应用程序时使用的用户 ID。

------
#### [ Container Sidecar ]

您可以使用 Docker 将 Secrets Manager 代理作为附加容器与应用程序一起运行。然后，您的应用程序可以从 Secrets Manager 代理提供的本地 HTTP 服务器检索密钥。有关 Docker 的信息，请参阅 [Docker 文档](https://docs.docker.com)。

**创建用于 Secrets Manager 代理的附加容器**

1. 

**创建代理 Dockerfile**  
为 Secrets Manager 代理附加容器创建 Dockerfile：

   ```
   # Use the latest Debian image as the base
   FROM debian:latest
   
   # Set the working directory inside the container
   WORKDIR /app 
   
   # Copy the Secrets Manager Agent binary to the container
   COPY secrets-manager-agent . 
   
   # Install any necessary dependencies
   RUN apt-get update && apt-get install -y ca-certificates 
   
   # Set the entry point to run the Secrets Manager Agent binary
   ENTRYPOINT ["./secrets-manager-agent"]
   ```

1. 

**创建应用程序 Dockerfile**  
为您的客户端应用程序创建一个 Dockerfile。

1. 

**创建 Docker Compose 文件**  
创建 Docker Compose 文件来运行具有共享网络接口的两个容器：
**重要**  
您必须加载 AWS 凭据和 SSRF 令牌，应用程序才能使用 Secrets Manager 代理。对于 Amazon EKS 和 Amazon ECS，请参阅以下内容：  
*Amazon EKS 用户指南*中的[管理访问权限](https://docs.aws.amazon.com/eks/latest/userguide/cluster-auth.html)
*Amazon ECS 开发人员指南*中的 [Amazon ECS 任务 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)

   ```
   version: '3'
   services:
       client-application:
       container_name: client-application
       build:
           context: .
           dockerfile: Dockerfile.client
       command: tail -f /dev/null  # Keep the container running
       
   
       secrets-manager-agent:
       container_name: secrets-manager-agent
       build:
           context: .
           dockerfile: Dockerfile.agent
       network_mode: "container:client-application"  # Attach to the client-application container's network
       depends_on:
           - client-application
   ```

1. 

**复制代理二进制文件**  
将 `secrets-manager-agent` 二进制文件复制到包含您的 Dockerfile 和 Docker Compose 文件的同一个目录中。

1. 

**构建并运行容器**  
使用 Docker Compose 构建并运行容器：

   ```
   docker-compose up --build
   ```

1. 

**后续步骤**  
在您的客户端容器中，您现在可使用 Secrets Manager 代理来检索密钥。有关更多信息，请参阅 [使用 Secrets Manager 代理检索密钥](#secrets-manager-agent-call)。

------
#### [ Lambda ]

您可以[将 Secrets Manager 代理打包为 Lambda 扩展](https://docs.aws.amazon.com/lambda/latest/dg/packaging-layers.html)。然后，您可以[将其作为层添加到 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/adding-layers.html)中，并从 Lambda 函数调用 Secrets Manager 代理来获取密钥。

以下说明说明如何使用`secrets-manager-agent-extension.sh`中的示例脚本将 Secret *MyTest*s Manager 代理作为 Lambda 扩展进行安装，[https://github.com/aws/aws-secretsmanager-agent](https://github.com/aws/aws-secretsmanager-agent)从而获取名为的密钥。

**创建用于 Secrets Manager 代理的 Lambda 扩展**

1. 

**打包代理层**  
从 Secrets Manager 代理代码包的根目录运行以下命令：

   ```
   AWS_ACCOUNT_ID=AWS_ACCOUNT_ID
   LAMBDA_ARN=LAMBDA_ARN
   
   # Build the release binary 
   cargo build --release --target=x86_64-unknown-linux-gnu
   
   # Copy the release binary into the `bin` folder
   mkdir -p ./bin
   cp ./target/x86_64-unknown-linux-gnu/release/aws_secretsmanager_agent ./bin/secrets-manager-agent
   
   # Copy the `secrets-manager-agent-extension.sh` example script into the `extensions` folder.
   mkdir -p ./extensions
   cp aws_secretsmanager_agent/examples/example-lambda-extension/secrets-manager-agent-extension.sh ./extensions
   
   # Zip the extension shell script and the binary 
   zip secrets-manager-agent-extension.zip bin/* extensions/*
   
   # Publish the layer version
   LAYER_VERSION_ARN=$(aws lambda publish-layer-version \
       --layer-name secrets-manager-agent-extension \
       --zip-file "fileb://secrets-manager-agent-extension.zip" | jq -r '.LayerVersionArn')
   ```

1. 

**配置 SSRF 令牌**  
代理的默认配置会自动将 SSRF 令牌设置为在预设变量`AWS_SESSION_TOKEN`或`AWS_CONTAINER_AUTHORIZATION_TOKEN`环境变量中设置的值（后一个变量适用于启用的 Lambda 函数）。 SnapStart 或者，您可以改用自己的 Lambda 函数的任意值定义 `AWS_TOKEN` 环境变量，因为该变量优先于其他两个变量。如果您选择使用 `AWS_TOKEN` 环境变量，则必须通过 `lambda:UpdateFunctionConfiguration` 调用来设置该环境变量。

1. 

**将层附加到函数**  
将层版本附加到 Lambda 函数：

   ```
   # Attach the layer version to the Lambda function
   aws lambda update-function-configuration \
       --function-name $LAMBDA_ARN \
       --layers "$LAYER_VERSION_ARN"
   ```

1. 

**更新函数代码**  
更新您的 Lambda 函数以使用 `X-Aws-codes-Secrets-Token` 标头值（设置为来自上述环境变量之一的 SSRF 令牌值）查询 `http://localhost:2773/secretsmanager/get?secretId=MyTest`，从而检索密钥。务必在应用程序代码中实现重试逻辑，以适应 Lambda 扩展初始化和注册中的延迟。

1. 

**测试此函数**  
调用 Lambda 函数以验证是否已正确获取密钥。

------

## 使用 Secrets Manager 代理检索密钥
<a name="secrets-manager-agent-call"></a>

要检索密钥，请调用本地 Secrets Manager 代理端点，并将密钥的名称或 ARN 作为查询参数包括在内。默认情况下，Secrets Manager 代理会检索密钥的 `AWSCURRENT` 版本。要检索其他版本，请使用 versionStage 或 versionId 参数。

**重要**  
为了帮助保护 Secrets Manager 代理，您必须在每个请求中包含 SSRF 令牌标头：`X-Aws-Parameters-Secrets-Token`。Secrets Manager 代理会拒绝没有此标头或具有无效 SSRF 令牌的请求。您可以在 [配置 Secrets Manager 代理](#secrets-manager-agent-config) 中自定义 SSRF 标头名称。

### 所需的权限
<a name="agent-call-permissions"></a>

Secrets Manager Agent 使用 AWS 适用于 Rust 的 SDK，它使用[AWS 凭证提供者链](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/credentials.html)。这些 IAM 凭证的身份决定了 Secrets Manager 代理检索密钥的权限。
+ `secretsmanager:DescribeSecret`
+ `secretsmanager:GetSecretValue`

有关权限的更多信息，请参阅 [的权限参考 AWS Secrets Manager](auth-and-access.md#reference_iam-permissions)。

**重要**  
将密钥值拉入 Secrets Manager 代理后，任何有权访问计算环境和 SSRF 令牌的用户都可以从 Secrets Manager 代理缓存中访问密钥。有关更多信息，请参阅 [安全注意事项](#secrets-manager-agent-security)。

### 示例请求
<a name="agent-call-examples"></a>

------
#### [ curl ]

**Example 示例 — 使用 curl 获取密钥**  
以下 curl 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF，该文件是安装脚本存储示例的位置。  

```
curl -v -H \\
    "X-Aws-Parameters-Secrets-Token: $(/var/run/awssmatoken)" \\
    'http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID' \\
    echo
```

------
#### [ Python ]

**Example 示例 — 使用 Python 获取密钥**  
以下 Python 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF，该文件是安装脚本存储示例的位置。  

```
import requests
import json

# Function that fetches the secret from Secrets Manager Agent for the provided secret id. 
def get_secret():
    # Construct the URL for the GET request
    url = f"http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID"

    # Get the SSRF token from the token file
    with open('/var/run/awssmatoken') as fp:
        token = fp.read() 

    headers = {
        "X-Aws-Parameters-Secrets-Token": token.strip()
    }

    try:
        # Send the GET request with headers
        response = requests.get(url, headers=headers)

        # Check if the request was successful
        if response.status_code == 200:
            # Return the secret value
            return response.text
        else:
            # Handle error cases
            raise Exception(f"Status code {response.status_code} - {response.text}")

    except Exception as e:
        # Handle network errors
        raise Exception(f"Error: {e}")
```

------

## 了解 `refreshNow` 参数
<a name="secrets-manager-agent-refresh"></a>

Secrets Manager 代理使用内存缓存来存储密钥值，该值会定期刷新。默认情况下，当您在生存时间（TTL）到期后请求密钥时，就会发生此刷新，通常每 300 秒刷新一次。但是，这种方法有时会导致密钥值过时，特别是如果密钥在缓存条目过期之前轮换。

为解决此限制，Secrets Manager 代理支持在 URL 中使用称为 `refreshNow` 的参数。您可以使用此参数强制立即刷新密钥的值，绕过缓存并确保您拥有最多的 up-to-date信息。

**默认行为（没有 `refreshNow`）**  
+ 在 TTL 过期之前使用缓存值
+ 仅在 TTL 之后刷新密钥（默认为 300 秒）
+ 如果密钥在缓存过期之前轮换，则可能会返回旧值

**使用 `refreshNow=true` 的行为**  
+ 完全绕过缓存
+ 直接从 Secrets Manager 中检索最新的密钥值
+ 使用新值更新缓存并重置 TTL
+ 确保您始终获得最新的密钥值

### 强制刷新密钥值
<a name="refreshnow-examples"></a>

**重要**  
`refreshNow` 的默认值为 `false`。设置为 `true` 时，它将覆盖 Secrets Manager 代理配置文件中指定的 TTL，并对 Secrets Manager 进行 API 调用。

------
#### [ curl ]

**Example 示例 – 使用 curl 强制刷新密钥**  
以下 curl 示例展示了如何强制 Secrets Manager 代理刷新密钥。该示例依赖于文件中存在的 SSRF，该文件是安装脚本存储示例的位置。  

```
curl -v -H \\
"X-Aws-Parameters-Secrets-Token: $(/var/run/awssmatoken)" \\
'http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID&refreshNow=true' \\
echo
```

------
#### [ Python ]

**Example 示例 – 使用 Python 强制刷新密钥**  
以下 Python 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF，该文件是安装脚本存储示例的位置。  

```
import requests
import json

# Function that fetches the secret from Secrets Manager Agent for the provided secret id. 
def get_secret():
    # Construct the URL for the GET request
    url = f"http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID&refreshNow=true"

    # Get the SSRF token from the token file
    with open('/var/run/awssmatoken') as fp:
        token = fp.read() 

    headers = {
        "X-Aws-Parameters-Secrets-Token": token.strip()
    }

    try:
        # Send the GET request with headers
        response = requests.get(url, headers=headers)

        # Check if the request was successful
        if response.status_code == 200:
            # Return the secret value
            return response.text
        else:
            # Handle error cases
            raise Exception(f"Status code {response.status_code} - {response.text}")

    except Exception as e:
        # Handle network errors
        raise Exception(f"Error: {e}")
```

------

## 配置 Secrets Manager 代理
<a name="secrets-manager-agent-config"></a>

要更改 Secrets Manager 代理的配置，请创建一个 [TOML](https://toml.io/en/) 配置文件，然后调用 `./aws_secretsmanager_agent --config config.toml`。配置选项

**`log_level`**  
Secrets Manager 代理日志中报告的详细程度：DEBUG、INFO、WARN、ERROR 或 NONE。默认值为 INFO。

**`log_to_file`**  
是否记录到文件或 stdout/stderr：`true` 或 `false`。默认值为 `true`。

**`http_port`**  
本地 HTTP 服务器的端口，范围在 1024 到 65535 之间。默认值为 2773。

**`region`**  
用于请求的 AWS 区域。如果未指定区域，则 Secrets Manager 代理会根据 SDK 确定区域。有关更多信息，请参阅《*AWS SDK for Rust 开发人员指南*》中的 [Specify your credentials and default Region](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/credentials.html)。

**`ttl_seconds`**  
缓存项目的 TTL（以秒为单位），范围在 1 到 3600 之间。默认值为 300。0 表示没有缓存。

**`cache_size`**  
缓存中可以存储的最大密钥数，范围为 1 至 1000。默认值为 1000。

**`ssrf_headers`**  
Secrets Manager 代理检查 SSRF 令牌的标头名称列表。默认为 “X-Aws-Parameters-Secrets-Token”。 X-Vault-Token

**`ssrf_env_variables`**  
Secrets Manager 代理按顺序检查 SSRF 令牌的环境变量名称列表。环境变量可以包含令牌或对令牌文件的引用，如下所示：`AWS_TOKEN=file:///var/run/awssmatoken`。默认为 “AWS\$1TOKEN、 AWS\$1SESSION \$1TOKEN、\$1AUTHORIZATION AWS\$1CONTAINER \$1TOKEN”。

**`path_prefix`**  
用于确定请求是否为基于路径的请求的 URI 前缀。默认值为“/v1/”。

**`max_conn`**  
Secrets Manager 代理允许的来自 HTTP 客户端的最大连接数，范围在 1 到 1000 之间。默认值为 800。

## 可选功能
<a name="secrets-manager-agent-features"></a>

通过将 `--features` 标志传递给 `cargo build`，可以使用可选功能构建 Secrets Manager 代理。可用功能如下：生成功能

**`prefer-post-quantum`**  
使 `X25519MLKEM768` 成为最高优先级的密钥交换算法。否则，它可用，但不是最高优先级。 `X25519MLKEM768`是一种混合 post-quantum-secure密钥交换算法。

**`fips`**  
将代理使用的密码套件限制为仅 FIPS 批准的密码。

## 日志记录
<a name="secrets-manager-agent-log"></a>

**本地日志记录**  
Secrets Manager 代理会根据 `log_to_file` 配置变量在本地将错误记录到文件 `logs/secrets_manager_agent.log` 或 stdout/stderr 中。当应用程序调用 Secrets Manager 代理来获取密钥时，这些调用会显示在本地日志中。它们不会出现在 CloudTrail 日志中。

**日志轮换**  
当文件达到 10 MB 时，Secrets Manager 代理会创建一个新的日志文件，并且总共最多存储五个日志文件。

**AWS 服务日志**  
日志不会转到 Secrets Manager CloudTrail、或 CloudWatch。从 Secrets Manager 代理获取密钥的请求不会出现在这些日志中。当 Secrets Manager 代理调用 Secrets Manager 获取密钥时，该呼叫将 CloudTrail 使用包含的用户代理字符串进行录音`aws-secrets-manager-agent`。

您可以在 [配置 Secrets Manager 代理](#secrets-manager-agent-config) 中配置日志记录选项。

## 安全注意事项
<a name="secrets-manager-agent-security"></a>

**信任域**  
对于代理架构，信任域是代理终端节点和 SSRF 令牌可访问的位置，通常是整个主机。为了保持相同的安全状况，Secrets Manager 代理的信任域应与 Secrets Manager 凭证可用的域相匹配。例如，在 Amazon EC2 上，使用 Amazon EC2 角色时，Secrets Manager 代理的信任域将与凭证的域相同。

**重要**  
具有安全意识的应用程序如果尚未使用代理解决方案，并且将 Secrets Manager 凭据锁定到该应用程序，则应考虑使用特定于语言的解决方案 AWS SDKs 或缓存解决方案。有关更多信息，请参阅[获取密钥](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html)。

# 使用 C\$1\$1 AWS 软件开发工具包获取 Secrets Manager 密钥值
<a name="retrieving-secrets-cpp"></a>

对于 C\$1\$1 应用程序，请使用[GetSecretValue](https://docs.aws.amazon.com/goto/SdkForCpp/secretsmanager-2017-10-17/GetSecretValue)或直接调用 SDK [BatchGetSecretValue](https://docs.aws.amazon.com/goto/SdkForCpp/secretsmanager-2017-10-17/BatchGetSecretValue)。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
//! Retrieve an AWS Secrets Manager encrypted secret.
/*!
  \param secretID: The ID for the secret.
  \return bool: Function succeeded.
 */
bool AwsDoc::SecretsManager::getSecretValue(const Aws::String &secretID,
                                            const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SecretsManager::SecretsManagerClient secretsManagerClient(clientConfiguration);

    Aws::SecretsManager::Model::GetSecretValueRequest request;
    request.SetSecretId(secretID);

    Aws::SecretsManager::Model::GetSecretValueOutcome getSecretValueOutcome = secretsManagerClient.GetSecretValue(
            request);
    if (getSecretValueOutcome.IsSuccess()) {
        std::cout << "Secret is: "
                  << getSecretValueOutcome.GetResult().GetSecretString() << std::endl;
    }
    else {
        std::cerr << "Failed with Error: " << getSecretValueOutcome.GetError()
                  << std::endl;
    }

    return getSecretValueOutcome.IsSuccess();
}
```

# 使用 JavaScript AWS SDK 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-javascript"></a>

对于 JavaScript 应用程序，请使用[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#getSecretValue-property](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#getSecretValue-property)或直接调用 SDK [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#batchGetSecretValue-property](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#batchGetSecretValue-property)。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
import {
  GetSecretValueCommand,
  SecretsManagerClient,
} from "@aws-sdk/client-secrets-manager";

export const getSecretValue = async (secretName = "SECRET_NAME") => {
  const client = new SecretsManagerClient();
  const response = await client.send(
    new GetSecretValueCommand({
      SecretId: secretName,
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '584eb612-f8b0-48c9-855e-6d246461b604',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   ARN: 'arn:aws:secretsmanager:us-east-1:xxxxxxxxxxxx:secret:binary-secret-3873048-xxxxxx',
  //   CreatedDate: 2023-08-08T19:29:51.294Z,
  //   Name: 'binary-secret-3873048',
  //   SecretBinary: Uint8Array(11) [
  //      98, 105, 110, 97, 114,
  //     121,  32, 100, 97, 116,
  //      97
  //   ],
  //   VersionId: '712083f4-0d26-415e-8044-16735142cd6a',
  //   VersionStages: [ 'AWSCURRENT' ]
  // }

  if (response.SecretString) {
    return response.SecretString;
  }

  if (response.SecretBinary) {
    return response.SecretBinary;
  }
};
```

# 使用 Kotlin AWS SDK 获取 Secrets Manager 的密钥值
<a name="retrieving-secrets-kotlin"></a>

对于 Kotlin 应用程序，请使用[GetSecretValue](https://github.com/awslabs/aws-sdk-kotlin#generating-api-documentation)或[BatchGetSecretValue](https://github.com/awslabs/aws-sdk-kotlin#generating-api-documentation)直接调用 SDK。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
suspend fun getValue(secretName: String?) {
    val valueRequest =
        GetSecretValueRequest {
            secretId = secretName
        }

    SecretsManagerClient.fromEnvironment { region = "us-east-1" }.use { secretsClient ->
        val response = secretsClient.getSecretValue(valueRequest)
        val secret = response.secretString
        println("The secret value is $secret")
    }
}
```

# 使用 PHP AWS 开发工具包获取 Secrets Manager 密钥值
<a name="retrieving-secrets-php"></a>

对于 PHP 应用程序，请直接使用 [https://docs.aws.amazon.com//aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#getsecretvalue](https://docs.aws.amazon.com//aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#getsecretvalue) 或 [https://docs.aws.amazon.com//aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#batchGetsecretvalue](https://docs.aws.amazon.com//aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#batchGetsecretvalue) 调用 SDK。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
<?php

  /**
    * Use this code snippet in your app.
    *
    * If you need more information about configurations or implementing the sample code, visit the AWS docs:
    * https://aws.amazon.com/developer/language/php/
    */
  
  require 'vendor/autoload.php';
  
  use Aws\SecretsManager\SecretsManagerClient;
  use Aws\Exception\AwsException;
  
  /**
    * This code expects that you have AWS credentials set up per:
    * https://<<{{DocsDomain}}>>/sdk-for-php/v3/developer-guide/guide_credentials.html
    */
  
  // Create a Secrets Manager Client
  $client = new SecretsManagerClient([
      'profile' => 'default',
      'version' => '2017-10-17',
      'region' => '<<{{MyRegionName}}>>',
  ]);
  
  $secret_name = '<<{{MySecretName}}>>';
  
  try {
      $result = $client->getSecretValue([
          'SecretId' => $secret_name,
      ]);
  } catch (AwsException $e) {
      // For a list of exceptions thrown, see
      // https://<<{{DocsDomain}}>>/secretsmanager/latest/apireference/API_GetSecretValue.html
      throw $e;
  }
  
  // Decrypts secret using the associated KMS key.
  $secret = $result['SecretString'];
  
  // Your code goes here
```

# 使用 Ruby AWS SDK 获取 Secrets Manager 密钥值
<a name="retrieving-secrets-ruby"></a>

对于 Ruby 应用程序，请直接使用 [https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#get_secret_value-instance_method](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#get_secret_value-instance_method) 或 [https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#batch_get_secret_value-instance_method](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#batch_get_secret_value-instance_method) 调用 SDK。

以下代码示例展示了如何获取 Secrets Manager 密钥值。

**所需权限：**`secretsmanager:GetSecretValue`

```
  # Use this code snippet in your app.
  # If you need more information about configurations or implementing the sample code, visit the AWS docs:
  # https://aws.amazon.com/developer/language/ruby/
  
  require 'aws-sdk-secretsmanager'
  
  def get_secret
    client = Aws::SecretsManager::Client.new(region: '<<{{MyRegionName}}>>')
  
    begin
      get_secret_value_response = client.get_secret_value(secret_id: '<<{{MySecretName}}>>')
    rescue StandardError => e
      # For a list of exceptions thrown, see
      # https://<<{{DocsDomain}}>>/secretsmanager/latest/apireference/API_GetSecretValue.html
      raise e
    end
  
    secret = get_secret_value_response.secret_string
    # Your code goes here.
  end
```

# 使用获取密钥值 AWS CLI
<a name="retrieving-secrets_cli"></a>

**所需权限：**`secretsmanager:GetSecretValue`

**Example 检索密钥的加密密钥值**  
以下 [https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/get-secret-value.html](https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/get-secret-value.html) 示例获取当前密钥值。  

```
aws secretsmanager get-secret-value \
    --secret-id MyTestSecret
```

**Example 检索之前的密钥值**  
以下 [https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/get-secret-value.html](https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/get-secret-value.html) 示例获取之前的密钥值。  

```
aws secretsmanager get-secret-value \
        --secret-id MyTestSecret
        --version-stage AWSPREVIOUS
```

## 使用批量获取一组机密 AWS CLI
<a name="retrieving-secrets-cli-batch"></a>

**所需权限：**
+ `secretsmanager:BatchGetSecretValue` 
+ 对要检索的每个密钥拥有 `secretsmanager:GetSecretValue` 权限。
+ 如果您使用筛选器，则还必须拥有 `secretsmanager:ListSecrets`。

有关权限策略的示例，请参阅 [示例：批量检索一组密钥值的权限](auth-and-access_iam-policies.md#auth-and-access_examples_batch)。

**重要**  
如果您的 VPCE 策略拒绝在您正在检索的群组中检索单个秘密的权限，则 `BatchGetSecretValue` 不会返回任何秘密值，并且会返回错误。

**Example 检索按名称列出的一组秘密的秘密值**  
以下 [https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/batch-get-secret-value.html](https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/batch-get-secret-value.html) 示例获取三个秘密的秘密值。  

```
aws secretsmanager batch-get-secret-value \
          --secret-id-list MySecret1 MySecret2 MySecret3
```

**Example 检索筛选器选择的一组秘密的秘密值**  
以下 [https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/batch-get-secret-value.html](https://docs.aws.amazon.com//cli/latest/reference/secretsmanager/batch-get-secret-value.html) 示例获取具有名为“Test”的标签的秘密的秘密值。  

```
aws secretsmanager batch-get-secret-value \
          --filters Key="tag-key",Values="Test"
```

# 使用 AWS 控制台获取密钥值
<a name="retrieving-secrets-console"></a>

**检索密钥（控制台）**

1. 打开 Secrets Manager 控制台，网址为[https://console.aws.amazon.com/secretsmanager/](https://console.aws.amazon.com/secretsmanager/)。

1. 在秘密列表中，选择要检索的秘密。

1. 在**密钥值**部分中，选择**检索密钥值**。

   Secrets Manager 显示秘密的当前版本 (`AWSCURRENT`)。要查看秘密的[其他版本](whats-in-a-secret.md#term_version)，例如 `AWSPREVIOUS` 或带有自定义标签的版本，请使用 [使用获取密钥值 AWS CLI](retrieving-secrets_cli.md)。

# 在中使用 AWS Secrets Manager 秘密 AWS Batch
<a name="integrating_BATCH"></a>

AWS Batch 可帮助您在上运行批量计算工作负载 AWS 云。使用 AWS Batch，您可以将敏感数据注入作业，方法是将敏感数据存储在 AWS Secrets Manager 机密中，然后在作业定义中引用它们。有关更多信息，请参阅[使用 Secrets Manager 指定敏感数据](https://docs.aws.amazon.com/batch/latest/userguide/specifying-sensitive-data-secrets.html)。

# 在 CloudFormation 资源中获取 AWS Secrets Manager 秘密
<a name="cfn-example_reference-secret"></a>

使用 CloudFormation，您可以检索密钥以在其他 CloudFormation 资源中使用。常见场景是首先使用 Secret Manager 生成的密码创建密钥，然后从该密钥中检索用户名和密码，以用作新数据库的凭证。有关使用创建密钥的信息 CloudFormation，请参阅[在中创建 AWS Secrets Manager 密钥 AWS CloudFormation](cloudformation.md)。

要检索 CloudFormation 模板中的密钥，请使用*动态引用*。创建堆栈时，动态引用会将密钥值提取到 CloudFormation 资源中，因此您不必对机密信息进行硬编码。相反，您可以通过名称或 ARN 来引用密钥。您可以在任何资源属性中使用对密钥的动态引用。您不能在资源元数据（例如 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html)）中使用对密钥的动态引用，因为那样会使密钥值在控制台中可见。

密钥的动态引用模式如下：

```
{{resolve:secretsmanager:secret-id:SecretString:json-key:version-stage:version-id}}
```

**secret-id**  
密钥的名称或 ARN。要访问您 AWS 账户中的密钥，您可以使用该密钥名称。要访问其他 AWS 账户中的密钥，请使用该密钥的 ARN。

**json-key**（可选）  
要检索其值的键值对的键名称。如果未指定`json-key`，则 CloudFormation 检索整个机密文本。此分段不得包含冒号字符 ( `:` )。

**version-stage**（可选）  
要使用的密钥的[版本](whats-in-a-secret.md#term_version)。Secrets Manager 在轮换过程中使用暂存标注来跟踪不同的版本。如果您使用 `version-stage`，则不要指定 `version-id`。如果您既未指定 `version-stage`，也未指定 `version-id`，则原定设置将为 `AWSCURRENT` 版本。此分段不得包含冒号字符 ( `:` )。

**version-id**（可选）  
要使用的密钥版本的唯一标识符。如果指定 `version-id`，则不要指定 `version-stage`。如果您既未指定 `version-stage`，也未指定 `version-id`，则原定设置将为 `AWSCURRENT` 版本。此分段不得包含冒号字符 ( `:` )。

有关更多信息，请参阅[使用动态引用指定 Secrets Manager 秘密](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-secretsmanager)。

**注意**  
不要使用反斜杠`(\)`作为最终值来创建动态引用。 CloudFormation 无法解析这些引用，这会导致资源故障。

# 在 GitHub 工作中使用 AWS Secrets Manager 秘密
<a name="retrieving-secrets_github"></a>

要在 GitHub 作业中使用密钥，您可以使用 GitHub 操作从 AWS Secrets Manager 中检索密钥并将其作为屏蔽的[环境变量](https://docs.github.com/en/actions/learn-github-actions/environment-variables)添加到 GitHub 工作流程中。有关 GitHub 操作的更多信息，请参阅[了解*GitHub 文档*中的 GitHub 操作](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions)。

当你向 GitHub 环境中添加密钥时，该密钥可用于 GitHub 工作中的所有其他步骤。按照操作[安全强化中的指导进行 GitHub 操作](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)，以帮助防止环境中的密钥被滥用。

您可以将密钥值中的整个字符串设置为环境变量值，或者如果字符串为 JSON，则可以解析 JSON，以为每个 JSON 键值对设置单独的环境变量。如果密钥值是二进制，则操作会将密钥值转换为字符串。

若要查看从密钥创建的环境变量，请启用调试日志记录。有关更多信息，请参阅*GitHub 文档*中的[启用调试日志记录](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging)。

要使用根据您的密钥创建的环境变量，请参阅*GitHub 文档*中的[环境变量](https://docs.github.com/en/actions/learn-github-actions/environment-variables)。

## 先决条件
<a name="retrieving-secrets_github_prereq"></a>

要使用此操作，您首先需要配置 AWS 凭证，然后使用`configure-aws-credentials`步骤 AWS 区域 在您的 GitHub 环境中进行设置。按照[配置 AWS 凭证操作中的说明进行 GitHub 操作，](https://github.com/aws-actions/configure-aws-credentials)以便**使用 GitHub OIDC 提供程序直接担任角色**。这让您能够使用短期凭证，避免在 Secrets Manager 之外存储额外的访问密钥。

操作承担的 IAM 角色必须具有下列权限：
+ 您要检索的密钥的 `GetSecretValue` 权限。
+ 所有密钥的 `ListSecrets` 权限。
+ （可选）`Decrypt`上 KMS key 是否使用加密密钥 客户自主管理型密钥。

有关更多信息，请参阅 [的身份验证和访问控制 AWS Secrets Manager](auth-and-access.md)。

## 用法
<a name="retrieving-secrets_github_usage"></a>

若要使用该操作，请在工作流程中添加一个使用以下语法的步骤。

```
- name: Step name
  uses: aws-actions/aws-secretsmanager-get-secrets@v2
  with:
    secret-ids: |
      secretId1
      ENV_VAR_NAME, secretId2
    name-transformation: (Optional) uppercase|lowercase|none
    parse-json-secrets: (Optional) true|false
```参数

`secret-ids`  
密钥 ARN、名称和名称前缀。  
若要设置环境变量名称，请在密钥 ID 前输入该名称，然后输入逗号。例如，`ENV_VAR_1, secretId` 从密钥 `secretId` 中创建名为 **ENV\$1VAR\$11** 的环境变量。环境变量的名称可以包含小写字母、数字和下划线。  
若要使用前缀，请输入至少三个字符，然后输入星号。例如，`dev*` 匹配名称以 **dev** 开头的所有密钥。最多可以检索 100 个匹配密钥。如果您设置了变量名称，并且前缀与多个密钥匹配，则操作将失败。

`name-transformation`  
默认情况下，该步骤从密钥名称创建每个环境变量名称，并转换为仅包含大写字母、数字和下划线，防止名称以数字开头。对于名称中的字母，您可以通过 `lowercase` 将步骤配置为使用小写字母，或者通过 `none` 配置为不改变字母的大小写。默认值为 `uppercase`。

`parse-json-secrets`  
（可选）默认情况下，该操作将环境变量值设置为密钥值中的整个 JSON 字符串。将 `parse-json-secrets` 设置为 `true`，以为 JSON 中的每个键值对创建环境变量。  
请注意，如果 JSON 使用区分大小写的密钥（例如“name”和“Name”），则该操作将出现重复的名称冲突。在这种情况下，请将 `parse-json-secrets` 设置为 `false` 并单独解析 JSON 密钥值。

## 环境变量命名
<a name="retrieving-secrets_github_alias"></a>

操作创建的环境变量的名称与它们来源的密钥相同。环境变量的命名要求比密钥的命名要求更严格，因此操作会转换密钥名称，以满足这些要求。例如，该操作将把小写字母转换为大写字母。如果解析密钥的 JSON，则环境变量名称将同时包含密钥名称和 JSON 键名称，例如 `MYSECRET_KEYNAME`。您可以将操作配置为不转换小写字母。

如果两个环境变量具有相同的名称，则操作将失败。在这种情况下，您必须将要用于环境变量的名称指定为*别名*。

名称可能冲突的示例：
+ 名为 “” MySecret 的密钥和名为 “mysecret” 的密钥都将成为名为 “MYSECRET” 的环境变量。
+ 名为“Secret\$1keyname”的密钥以及名为“Secret”且具有“keyname”键的 JSON 解析密钥都将成为名为“SECRET\$1KEYNAME”的环境变量。

您可以通过指定*别名*来设置环境变量名称，如以下示例所示，它会创建一个名为 `ENV_VAR_NAME` 的变量。

```
secret-ids: |
  ENV_VAR_NAME, secretId2
```

**空白别名**
+ 如果您设置 `parse-json-secrets: true` 并输入空白别名，后跟逗号，然后是密钥 ID，则操作会将环境变量命名为与解析后的 JSON 键相同。变量名称不包含密钥名称。

  如果密钥不包含有效的 JSON，则操作会创建一个环境变量并将其命名为与密钥名称相同。
+ 如果您设置 `parse-json-secrets: false` 并输入空白别名，后跟逗号，然后是密钥 ID，则操作将命名环境变量，就好像您没有指定别名一样。

以下示例显示了一个空白别名。

```
,secret2
```

## 示例
<a name="retrieving-secrets_github_examples"></a>

**Example 1 按名称和 ARN 获取密钥**  
下列示例为按名称和 ARN 标识的密钥创建环境变量。  

```
- name: Get secrets by name and by ARN
  uses: aws-actions/aws-secretsmanager-get-secrets@v2
  with:
    secret-ids: |
      exampleSecretName
      arn:aws:secretsmanager:us-east-2:123456789012:secret:test1-a1b2c3
      0/test/secret
      /prod/example/secret
      SECRET_ALIAS_1,test/secret
      SECRET_ALIAS_2,arn:aws:secretsmanager:us-east-2:123456789012:secret:test2-a1b2c3
      ,secret2
```
已创建的环境变量：  

```
EXAMPLESECRETNAME: secretValue1
TEST1: secretValue2
_0_TEST_SECRET: secretValue3
_PROD_EXAMPLE_SECRET: secretValue4
SECRET_ALIAS_1: secretValue5
SECRET_ALIAS_2: secretValue6
SECRET2: secretValue7
```

**Example 2 获取所有以前缀开头的密钥**  
以下示例为所有名称以开头的密钥创建环境变量*beta*。  

```
- name: Get Secret Names by Prefix
  uses: 2
  with:
    secret-ids: |
      beta*    # Retrieves all secrets that start with 'beta'
```
已创建的环境变量：  

```
BETASECRETNAME: secretValue1
BETATEST: secretValue2
BETA_NEWSECRET: secretValue3
```

**Example 3 在密钥中解析 JSON**  
下列示例通过解析密钥中的 JSON 来创建环境变量。  

```
- name: Get Secrets by Name and by ARN
  uses: aws-actions/aws-secretsmanager-get-secrets@v2
  with:
    secret-ids: |
      test/secret
      ,secret2
    parse-json-secrets: true
```
密钥 `test/secret` 具有下列密钥值。  

```
{
  "api_user": "user",
  "api_key": "key",
  "config": {
    "active": "true"
  }
}
```
密钥 `secret2` 具有下列密钥值。  

```
{
  "myusername": "alejandro_rosalez",
  "mypassword": "EXAMPLE_PASSWORD"
}
```
已创建的环境变量：  

```
TEST_SECRET_API_USER: "user"
TEST_SECRET_API_KEY: "key"
TEST_SECRET_CONFIG_ACTIVE: "true"
MYUSERNAME: "alejandro_rosalez"
MYPASSWORD: "EXAMPLE_PASSWORD"
```

**Example 4 对环境变量名称使用小写字母**  
以下示例将创建一个具有小写名称的环境变量。  

```
- name: Get secrets
  uses: aws-actions/aws-secretsmanager-get-secrets@v2
  with:
    secret-ids: exampleSecretName
    name-transformation: lowercase
```
已创建的环境变量：  

```
examplesecretname: secretValue
```

# 用 AWS Secrets Manager 于 GitLab
<a name="integrating_gitlab"></a>

AWS Secrets Manager 与。集成 GitLab。你可以利用 Secrets Manager 的密钥来保护你的 GitLab凭证，这样它们就不会再被硬编码了。 GitLab相反，当你的应用程序在 GitLab CI/CD 管[GitLab 道](https://docs.gitlab.com/runner/)中运行作业时，Runner 会从 Secrets Manager 中检索这些机密。

要使用此集成，您需要在 IAM 中创建一个 [OpenID Connect (OIDC) 身份提供商 AWS Identity and Access Management 和一个 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)。这允许 GitLab Runner 访问你的 Secrets Manager 密钥。[有关 C GitLab I/CD 和 OIDC 的更多信息，请参阅文档。GitLab](https://docs.gitlab.com/ci/cloud_services/aws/)

## 注意事项
<a name="gitlab-integration-considerations"></a>

如果您使用的是非公共 GitLab 实例，则无法使用此 Secrets Manager 集成。相反，请参阅[非公共实例的GitLab 文档](https://docs.gitlab.com/ci/cloud_services/aws/#configure-a-non-public-gitlab-instance)。

## 先决条件
<a name="gitlab-integration-prerequisites"></a>

要将 Secrets Manager 与集成 GitLab，请完成以下先决条件：

1. 

**创建密 AWS Secrets Manager 钥**

   你需要一个 Secrets Manager 密钥，该密钥将在你的 GitLab 工作中检索，无需对这些凭据进行硬编码。在[配置 GitLab 管道](#configure-gitlab-pipeline)时，你需要 Secrets Manager 的密钥 ID。请参阅[创建密 AWS Secrets Manager 钥](create_secret.md)了解更多信息。

1. 

**在 IAM 控制台中创建 GitLab 您的 OIDC 提供商。**

   在此步骤中，您将在 IAM 控制台中创建 GitLab 您的 OIDC 提供商。[有关更多信息，请参阅[创建 OpenID Connect (OIDC) 身份](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_providers_create_oidc.html)提供商和文档。GitLab](https://docs.gitlab.com/ci/cloud_services/aws/)

   在 IAM 控制台中创建 OIDC 提供者时，请使用以下配置：

   1. <a name="step2-oidc-provider"></a>将设置`provider URL`为您的 GitLab 实例。例如 **gitlab.example.com**。

   1. <a name="step2-oidc-audience"></a>将 `audience` 或 `aud` 设置为 **sts.amazonaws.com**。

1. 

**创建 IAM 角色和策略**

   您将需要创建 IAM 角色和策略。此角色由 with GitLab [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) 担任。有关更多信息，请参阅[使用自定义信任策略创建角色](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-custom.html)。

   1. 在 IAM 控制台中，在创建 IAM 角色时使用以下设置：
      + 将 `Trusted entity type` 设置为 **Web identity**。
      + 将 `Group` 设置为 **your GitLab group**。
      + 设置`Identity provider`为您在步骤 2 中使用的提供商 URL（[GitLab 实例](#step2-oidc-provider)）。
      + 将 `Audience` 设置为在步骤 2 中使用的相同[受众](#step2-oidc-audience)。

   1. 以下是允许 GitLab 代入角色的信任策略示例。您的信任策略应列出您 GitLab 的 AWS 账户、URL 和[项目路径](https://docs.gitlab.com/user/project/)。  
****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Principal": {
              "Federated": "arn:aws:iam::111122223333:oidc-provider/gitlab.example.com"
            },
            "Condition": {
              "StringEquals": {
                "gitlab.example.com:aud": [
                  "sts.amazon.com"
                ]
              },
              "StringLike": {
                "gitlab.example.com:sub": [
                  "project_path:mygroup/project-*:ref_type:branch-*:ref:main*"
                ]
              }
            }
          }
        ]
      }
      ```

   1. 您还需要创建一个 IAM 策略以允许 GitLab 访问 AWS Secrets Manager。您可以将此策略添加到信任策略。有关更多信息，请参阅[创建 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html)。  
****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:your-secret"
          }
        ]
      }
      ```

## AWS Secrets Manager 与集成 GitLab
<a name="integrating-aws-secrets-manager-gitlab"></a>

完成先决条件后，您可以配置为使用 Sec GitLab rets Manager 来保护您的凭证。

### 将 GitLab 管道配置为使用 Secrets Manager
<a name="configure-gitlab-pipeline"></a>

您需要使用以下信息更新 [GitLab CI/CD 配置文件](https://docs.gitlab.com/ci/yaml/yaml_optimization/)：
+ 设置为 STS 的令牌的受众。
+ Secrets Manager 密钥 ID。
+ 您希望 GitLab Runner 在 GitLab管道中执行任务时扮演的 IAM 角色。
+ 密钥的存储位置。 AWS 区域 

GitLab 从 Secrets Manager 中获取密钥并将该值存储在临时文件中。此文件的路径存储在 CI/CD 变量中，类似于[文件类型 CI/CD](https://docs.gitlab.com/ci/variables/#use-file-type-cicd-variables) 变量。

以下是 GitLab CI/CD 配置文件的 YAML 文件片段：

```
variables:
  AWS_REGION: us-east-1
  AWS_ROLE_ARN: 'arn:aws:iam::111122223333:role/gitlab-role'
job:
  id_tokens:
    AWS_ID_TOKEN:
      aud: 'sts.amazonaws.com'
  secrets:
    DATABASE_PASSWORD:
      aws_secrets_manager:
        secret_id: "arn:aws:secretsmanager:us-east-1:111122223333:secret:secret-name"
```

有关更多信息，请参阅 S [GitLabecrets Manager 集成文档](https://docs.gitlab.com/ci/secrets/aws_secrets_manager/)。

或者，您也可以在中测试 OIDC 配置。 GitLab有关更多信息[，请参阅测试 OIDC 配置的GitLab 文档](https://docs.gitlab.com/ci/cloud_services/aws/#test-the-oidc-configuration)。

## 问题排查
<a name="troubleshooting-integration"></a>

以下内容可以帮助您解决在将 Secrets Manager 与集成时可能遇到的常见问题 GitLab。

### GitLab 管道问题
<a name="gitlab-pipeline-issues"></a>

如果您遇到 GitLab 管道问题，请确保以下几点：
+ 您的 YAML 文件格式正确。有关更多信息，请参阅 [GitLab 文档](https://docs.gitlab.com/ee/ci/yaml/)。
+ 您的 GitLab 管道扮演了正确的角色，拥有相应的权限，并且可以访问正确的 AWS Secrets Manager 密钥。

### 其他资源
<a name="additional-resources"></a>

以下资源可以帮助您解决 GitLab 和的问题 AWS Secrets Manager：
+ [GitLab OIDC 疑难解答](https://docs.gitlab.com/ci/cloud_services/aws/#troubleshooting)
+ [调试 GitLab CI/CD 管道](https://docs.gitlab.com/ee/ci/troubleshooting.html)
+ [问题排查](ascp-eks-installation.md#troubleshooting)

# 在中使用 AWS Secrets Manager 秘密 AWS IoT Greengrass
<a name="integrating-greengrass"></a>

AWS IoT Greengrass 是将云功能扩展到本地设备的软件。这使得设备可以更靠近信息源来收集和分析数据，自主响应本地事件，同时在本地网络上彼此安全地通信。

AWS IoT Greengrass 允许您使用 AWS IoT Greengrass 设备上的服务和应用程序进行身份验证，而无需对密码、令牌或其他机密进行硬编码。您可以使用在云端安全 AWS Secrets Manager 地存储和管理您的密钥。 AWS IoT Greengrass 将 Secrets Manager 扩展到 AWS IoT Greengrass 核心设备，因此您的连接器和 Lambda 函数可以使用本地密钥与服务和应用程序进行交互。

要将密钥集成到 AWS IoT Greengrass 群组中，您需要创建一个引用 Secrets Manager 密钥的群组资源。此密钥资源使用关联 ARN 引用云密钥。要了解如何创建、管理和使用秘密资源，请参阅 AWS IoT 开发者指南中的[使用机密资源](https://docs.aws.amazon.com/greengrass/latest/developerguide/secrets-using.html)。

要将密钥部署到 AWS IoT Greengrass 核心，请参阅[将密钥部署到 AWS IoT Greengrass 核心。](https://docs.aws.amazon.com/greengrass/latest/developerguide/secrets.html)

# 在参数存储中使用 AWS Secrets Manager 密钥
<a name="integrating_parameterstore"></a>

AWS Systems Manager Parameter Store 为配置数据管理和密钥管理提供安全的分层存储。也可以将密码、数据库字符串和许可证代码等数据存储为参数值。不过，Parameter Store 不会为存储的密钥提供自动轮换服务。相反，Parameter Store 允许您在 Secrets Manager 中存储密钥，然后以 Parameter Store 参数形式引用该密钥。

使用 Secrets Manager 配置 Parameter Store 时，`secret-id` Parameter Store 需要在名称字符串之前使用正斜杠 (/)。

有关更多信息，请参阅*AWS Systems Manager 用户指南*中的通过[参数存储参数引用 AWS Secrets Manager 密钥](https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-ps-secretsmanager.html)。