

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 擷取秘密值
<a name="ipc-secret-manager"></a>

使用 Secret Manager IPC 服務，從核心裝置上的秘密擷取秘密值。您可以使用[秘密管理員元件](secret-manager-component.md)，將加密的秘密部署到核心裝置。然後，您可以使用 IPC 操作來解密秘密，並在自訂元件中使用其值。

**Topics**
+ [最低 SDK 版本](#ipc-secret-manager-sdk-versions)
+ [Authorization](#ipc-secret-manager-authorization)
+ [GetSecretValue](#ipc-operation-getsecretvalue)
+ [範例](#ipc-secret-manager-examples)

## 最低 SDK 版本
<a name="ipc-secret-manager-sdk-versions"></a>

下表列出 AWS IoT Device SDK 您必須用來從核心裝置上的秘密擷取秘密值的 最低版本。


| SDK | 最低版本 | 
| --- | --- | 
|  [AWS IoT Device SDK for Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  v1.2.10  | 
|  [AWS IoT Device SDK for Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  1.5.3 版  | 
|  [AWS IoT Device SDK 適用於 C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  1.17.0 版  | 
|  [AWS IoT Device SDK for JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  v1.12.0  | 

## Authorization
<a name="ipc-secret-manager-authorization"></a>

若要在自訂元件中使用秘密管理員，您必須定義授權政策，允許元件取得存放在核心裝置上的秘密值。如需定義授權政策的資訊，請參閱 [授權元件執行 IPC 操作](interprocess-communication.md#ipc-authorization-policies)。

秘密管理員的授權政策具有下列屬性。

**IPC 服務識別符：** `aws.greengrass.SecretManager`


| 作業 | Description | Resources | 
| --- | --- | --- | 
|  `aws.greengrass#GetSecretValue` 或 `*`  |  允許元件取得在核心裝置上加密的秘密值。  |  Secrets Manager 秘密 ARN，或`*`允許存取所有秘密。  | 

### 授權政策範例
<a name="ipc-secret-manager-authorization-policy-examples"></a>

您可以參考下列授權政策範例，協助您設定元件的授權政策。

**Example 範例授權政策**  
下列範例授權政策允許元件取得核心裝置上任何秘密的值。  
我們建議您在生產環境中減少授權政策的範圍，以便元件僅擷取其使用的秘密。部署元件時，您可以將`*`萬用字元變更為秘密 ARNs 清單。

```
{
  "accessControl": {
    "aws.greengrass.SecretManager": {
      "com.example.MySecretComponent:secrets:1": {
        "policyDescription": "Allows access to a secret.",
        "operations": [
          "aws.greengrass#GetSecretValue"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

## GetSecretValue
<a name="ipc-operation-getsecretvalue"></a>

取得您存放在核心裝置上的秘密值。

此操作類似於 Secrets Manager 操作，您可以用來取得 中的秘密值 AWS 雲端。如需詳細資訊，請參閱 *AWS Secrets Manager API 參考*中的 [GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)。

### 請求
<a name="ipc-operation-getsecretvalue-request"></a>

此操作的請求具有下列參數：

`refresh` (Python：`refresh`)  
（選用）：是否要將請求的秘密與來自 AWS Secrets Manager 服務的最新值同步。  
當設定為 true 時，秘密管理員會請求 AWS Secrets Manager 服務以取得指定秘密標籤的最新值，並將該值傳回為回應。否則，將會傳回儲存在本機的秘密值。  
 此參數無法與請求中的`versionId`參數搭配使用。此參數可搭配 Nucleus 2.13.0 及更高版本使用。

`secretId` (Python：`secret_id`)  
要取得的秘密名稱。您可以指定 Amazon Resource Name (ARN) 或秘密的易記名稱。

`versionId` (Python：`version_id`)  
（選用） 要取得的版本 ID。  
您可指定為 `versionId` 或 `versionStage`。  
如果您未指定 `versionId`或 `versionStage`，則此操作預設為具有 `AWSCURRENT`標籤的 版本。

`versionStage` (Python：`version_stage`)  
（選用） 要取得之版本的預備標籤。  
您可指定為 `versionId` 或 `versionStage`。  
如果您未指定 `versionId`或 `versionStage`，則此操作預設為具有 `AWSCURRENT`標籤的 版本。

### 回應
<a name="ipc-operation-getsecretvalue-response"></a>

此操作的回應包含下列資訊：

`secretId` (Python：`secret_id`)  
秘密的 ID。

`versionId` (Python：`version_id`)  
此版本秘密的 ID。

`versionStage` (Python：`version_stage`)  
連接到此版本秘密的預備標籤清單。

`secretValue` (Python：`secret_value`)  
此版本秘密的值。此物件 `SecretValue`包含下列資訊。    
`secretString` (Python：`secret_string`)  
您以字串形式提供給 Secrets Manager 的受保護秘密資訊的解密部分。  
`secretBinary` (Python：`secret_binary`)  
（選用） 您以位元組陣列形式提供給 Secrets Manager 做為二進位資料的受保護秘密資訊的解密部分。此屬性包含二進位資料做為 base64 編碼字串。  
如果您在 Secrets Manager 主控台中建立秘密，則不會使用此屬性。

### 範例
<a name="ipc-operation-getsecretvalue-examples"></a>

下列範例示範如何在自訂元件程式碼中呼叫此操作。

------
#### [ Java (IPC client V1) ]

**Example 範例：取得秘密值**  
此範例使用 `IPCUtils`類別來建立與 AWS IoT Greengrass Core IPC 服務的連線。如需詳細資訊，請參閱[連線至 AWS IoT Greengrass Core IPC 服務](interprocess-communication.md#ipc-service-connect)。

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GetSecretValueResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.GetSecretValueRequest;
import software.amazon.awssdk.aws.greengrass.model.GetSecretValueResponse;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class GetSecretValue {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        String secretArn = args[0];
        String versionStage = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            GetSecretValueResponseHandler responseHandler =
                    GetSecretValue.getSecretValue(ipcClient, secretArn, versionStage);
            CompletableFuture<GetSecretValueResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                GetSecretValueResponse response = futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                response.getSecretValue().postFromJson();
                String secretString = response.getSecretValue().getSecretString();
                System.out.println("Successfully retrieved secret value: " + secretString);
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while retrieving secret: " + secretArn);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while retrieving secret: " + secretArn);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static GetSecretValueResponseHandler getSecretValue(GreengrassCoreIPCClient greengrassCoreIPCClient, String secretArn, String versionStage) {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest();
        getSecretValueRequest.setSecretId(secretArn);
        getSecretValueRequest.setVersionStage(versionStage);
        return greengrassCoreIPCClient.getSecretValue(getSecretValueRequest, Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 範例：取得秘密值**  
此範例假設您使用 AWS IoT Device SDK 適用於 Python v2 的 1.5.4 版或更新版本。

```
import json

import awsiot.greengrasscoreipc
from awsiot.greengrasscoreipc.model import (
    GetSecretValueRequest,
    GetSecretValueResponse,
    UnauthorizedError
)

secret_id = 'arn:aws:secretsmanager:us-west-2:123456789012:secret:MyGreengrassSecret-abcdef'
TIMEOUT = 10

ipc_client = awsiot.greengrasscoreipc.connect()

request = GetSecretValueRequest()
request.secret_id = secret_id
request.version_stage = 'AWSCURRENT'
operation = ipc_client.new_get_secret_value()
operation.activate(request)
future_response = operation.get_response()
response = future_response.result(TIMEOUT)
secret_json = json.loads(response.secret_value.secret_string)
# Handle secret value.
```

------
#### [ JavaScript ]

**Example 範例：取得秘密值**  

```
import {
    GetSecretValueRequest,
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
 
class GetSecretValue {
    private readonly secretId : string;
    private readonly versionStage : string;
    private ipcClient : greengrasscoreipc.Client
 
    constructor() {
        this.secretId = "<define_your_own_secretId>"
        this.versionStage = "<define_your_own_versionStage>"
 
        this.getSecretValue().then(r => console.log("Started workflow"));
    }
 
    private async getSecretValue() {
        try {
            this.ipcClient = await getIpcClient();
 
            const getSecretValueRequest : GetSecretValueRequest = {
                secretId: this.secretId,
                versionStage: this.versionStage,
            };
 
            const result = await this.ipcClient.getSecretValue(getSecretValueRequest);
            const secretString = result.secretValue.secretString;
            console.log("Successfully retrieved secret value: " + secretString)
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
export async function getIpcClient(){
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}
 
const getSecretValue = new GetSecretValue();
```

------

## 範例
<a name="ipc-secret-manager-examples"></a>

使用下列範例來了解如何在元件中使用秘密管理員 IPC 服務。

### 範例：列印秘密 (Python、IPC 用戶端 V1)
<a name="ipc-secret-manager-example-print-secret-python"></a>

此範例元件會列印您部署到核心裝置的秘密值。

**重要**  
此範例元件會列印秘密的值，因此只能與存放測試資料的秘密搭配使用。請勿使用此元件來列印存放重要資訊的秘密值。

**Topics**
+ [Recipe](#ipc-secret-manager-example-print-secret-python-recipe)
+ [成品](#ipc-secret-manager-example-print-secret-python-artifacts)
+ [Usage](#ipc-secret-manager-example-print-secret-python-usage)

#### Recipe
<a name="ipc-secret-manager-example-print-secret-python-recipe"></a>

下列範例配方會定義秘密 ARN 組態參數，並允許元件取得核心裝置上任何秘密的值。

**注意**  <a name="ipc-secret-manager-authorization-policy-resource-wildcard"></a>
我們建議您在生產環境中減少授權政策的範圍，以便元件僅擷取其使用的秘密。部署元件時，您可以將`*`萬用字元變更為秘密 ARNs 清單。

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

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PrintSecret",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Prints the value of an AWS Secrets Manager secret.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.SecretManager": {
      "VersionRequirement": "^2.0.0",
      "DependencyType": "HARD"
    }
  },
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "SecretArn": "",
      "accessControl": {
        "aws.greengrass.SecretManager": {
          "com.example.PrintSecret:secrets:1": {
            "policyDescription": "Allows access to a secret.",
            "operations": [
              "aws.greengrass#GetSecretValue"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "python3 -m pip install --user awsiotsdk",
        "Run": "python3 -u {artifacts:path}/print_secret.py \"{configuration:/SecretArn}\""
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "install": "py -3 -m pip install --user awsiotsdk",
        "Run": "py -3 -u {artifacts:path}/print_secret.py \"{configuration:/SecretArn}\""
      }
    }
  ]
}
```

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

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PrintSecret
ComponentVersion: 1.0.0
ComponentDescription: Prints the value of a Secrets Manager secret.
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.SecretManager:
    VersionRequirement: "^2.0.0"
    DependencyType: HARD
ComponentConfiguration:
  DefaultConfiguration:
    SecretArn: ''
    accessControl:
      aws.greengrass.SecretManager:
        com.example.PrintSecret:secrets:1:
          policyDescription: Allows access to a secret.
          operations:
            - aws.greengrass#GetSecretValue
          resources:
            - "*"
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: python3 -m pip install --user awsiotsdk
      Run: python3 -u {artifacts:path}/print_secret.py "{configuration:/SecretArn}"
  - Platform:
      os: windows
    Lifecycle:
      install: py -3 -m pip install --user awsiotsdk
      Run: py -3 -u {artifacts:path}/print_secret.py "{configuration:/SecretArn}"
```

------

#### 成品
<a name="ipc-secret-manager-example-print-secret-python-artifacts"></a>

下列範例 Python 應用程式示範如何使用 Secret Manager IPC 服務來取得核心裝置上的秘密值。

```
import concurrent.futures
import json
import sys
import traceback

import awsiot.greengrasscoreipc
from awsiot.greengrasscoreipc.model import (
    GetSecretValueRequest,
    GetSecretValueResponse,
    UnauthorizedError
)

TIMEOUT = 10

if len(sys.argv) == 1:
    print('Provide SecretArn in the component configuration.', file=sys.stdout)
    exit(1)

secret_id = sys.argv[1]

try:
    ipc_client = awsiot.greengrasscoreipc.connect()

    request = GetSecretValueRequest()
    request.secret_id = secret_id
    operation = ipc_client.new_get_secret_value()
    operation.activate(request)
    future_response = operation.get_response()

    try:
        response = future_response.result(TIMEOUT)
        secret_json = json.loads(response.secret_value.secret_string)
        print('Successfully got secret: ' + secret_id)
        print('Secret value: ' + str(secret_json))
    except concurrent.futures.TimeoutError:
        print('Timeout occurred while getting secret: ' + secret_id, file=sys.stderr)
    except UnauthorizedError as e:
        print('Unauthorized error while getting secret: ' + secret_id, file=sys.stderr)
        raise e
    except Exception as e:
        print('Exception while getting secret: ' + secret_id, file=sys.stderr)
        raise e
except Exception:
    print('Exception occurred when using IPC.', file=sys.stderr)
    traceback.print_exc()
    exit(1)
```

#### Usage
<a name="ipc-secret-manager-example-print-secret-python-usage"></a>

您可以使用此範例元件搭配[秘密管理員元件](secret-manager-component.md)，在核心裝置上部署和列印秘密的值。

**建立、部署和列印測試秘密**

1. 使用測試資料建立 Secrets Manager 秘密。

------
#### [ Linux or Unix ]

   ```
   aws secretsmanager create-secret \
     --name MyTestGreengrassSecret \
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   aws secretsmanager create-secret ^
     --name MyTestGreengrassSecret ^
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------
#### [ PowerShell ]

   ```
   aws secretsmanager create-secret `
     --name MyTestGreengrassSecret `
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------

   儲存秘密的 ARN，以便在下列步驟中使用。

   如需詳細資訊，請參閱*AWS Secrets Manager 《 使用者指南*》中的[建立秘密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_create-basic-secret.html)。

1. 使用下列組態合併更新來部署[秘密管理員元件](secret-manager-component.md) (`aws.greengrass.SecretManager`)。指定您先前建立之秘密的 ARN。

   ```
   {
     "cloudSecrets": [
       {
         "arn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret-abcdef"
       }
     ]
   }
   ```

   如需詳細資訊，請參閱 [將 AWS IoT Greengrass 元件部署至裝置](manage-deployments.md)或 [Greengrass CLI 部署命令](gg-cli-deployment.md)。

1. 使用下列組態合併更新，在本節中建立和部署範例元件。指定您先前建立之秘密的 ARN。

   ```
   {
     "SecretArn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret",
     "accessControl": {
       "aws.greengrass.SecretManager": {
         "com.example.PrintSecret:secrets:1": {
           "policyDescription": "Allows access to a secret.",
           "operations": [
             "aws.greengrass#GetSecretValue"
           ],
           "resources": [
             "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret-abcdef"
           ]
         }
       }
     }
   }
   ```

   如需詳細資訊，請參閱[建立 AWS IoT Greengrass 元件](create-components.md)

1. 檢視 AWS IoT Greengrass 核心軟體日誌以驗證部署是否成功，並檢視`com.example.PrintSecret`元件日誌以查看列印的秘密值。如需詳細資訊，請參閱[監控 AWS IoT Greengrass 日誌](monitor-logs.md)。