Secrets Manager API および AWS SDK for PHP バージョン 3 を使用したシークレットの管理
AWS Secrets Manager は、パスワード、API キー、データベース認証情報などの共有されたシークレットを保存し、管理します。Secrets Manager サービスにより、開発者はデプロイされたコードのハードコードされた認証情報を、Secrets Manager への埋め込みの呼び出しで置き換えることができます。
Secrets Manager では、Amazon Relational Database Service (Amazon RDS) データベースの認証情報のスケジュールされた自動ローテーションがネイティブにサポートされ、アプリケーションのセキュリティが向上します。また、Secrets Manager は、AWS Lambda を使って他のデータベースやサードパーティーのサービスのシークレットをシームレスにローテーションさせ、サービス固有の詳細を実装することができます。
以下の例では、次の方法を示しています。
-
CreateSecret を使用してシークレットを作成します。
-
GetSecretValue を使用してシークレットを取得します。
-
ListSecrets を使用して、Secrets Manager によって保存されたすべてのシークレットをリストします。
-
DescribeSecret を使用して、指定されたシークレットの詳細を取得します。
-
PutSecretValue を使用して、指定されたシークレットを更新します。
-
RotateSecret を使用してシークレットの更新を設定します。
-
DeleteSecret を使用して、シークレットを削除対象としてマークします。
AWS SDK for PHP 用のすべてのサンプルコードは GitHub
認証情報
サンプルコードを実行する前に、AWS の認証情報を設定します (AWS SDK for PHP バージョン 3 を使用した AWS での認証 を参照)。AWS SDK for PHP からのインポート (AWS SDK for PHP バージョン 3 のインストール を参照)。
Secrets Manager でのシークレットの作成
Secrets Manager でシークレットを作成するには、CreateSecret オペレーションを使用します。
この例では、ユーザー名とパスワードは JSON 文字列として保存されます。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; $secret = json_encode([ "username" => getenv("SMDEMO_USERNAME"), "password" => getenv("SMDEMO_PASSWORD"), ]); $description = '<<Description>>'; try { $result = $client->createSecret([ 'Description' => $description, 'Name' => $secretName, 'SecretString' => $secret, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
Secrets Manager からのシークレットの取得
Secrets Manager に保存されているシークレットの値を取得するには、GetSecretValue オペレーションを使用します。
次の例では、secret シークレットは保存された値を含む文字列です。username の値が <<USERNAME>> で、password の値が <<PASSWORD>> の場合、secret 出力は 次のようになります。
{"username":"<<USERNAME>>","password":"<<PASSWORD>>"}
json_decode($secret, true) を使用して配列の値にアクセスします。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-east-1', ]); $secretName = 'MySecretName'; try { $result = $client->getSecretValue([ 'SecretId' => $secretName, ]); } catch (AwsException $e) { $error = $e->getAwsErrorCode(); if ($error == 'DecryptionFailureException') { // Secrets Manager can't decrypt the protected secret text using the provided AWS KMS key. // Handle the exception here, and/or rethrow as needed. throw $e; } if ($error == 'InternalServiceErrorException') { // An error occurred on the server side. // Handle the exception here, and/or rethrow as needed. throw $e; } if ($error == 'InvalidParameterException') { // You provided an invalid value for a parameter. // Handle the exception here, and/or rethrow as needed. throw $e; } if ($error == 'InvalidRequestException') { // You provided a parameter value that is not valid for the current state of the resource. // Handle the exception here, and/or rethrow as needed. throw $e; } if ($error == 'ResourceNotFoundException') { // We can't find the resource that you asked for. // Handle the exception here, and/or rethrow as needed. throw $e; } } // Decrypts secret using the associated KMS CMK. // Depending on whether the secret is a string or binary, one of these fields will be populated. if (isset($result['SecretString'])) { $secret = $result['SecretString']; } else { $secret = base64_decode($result['SecretBinary']); } print $secret; $secretArray = json_decode($secret, true); $username = $secretArray['username']; $password = $secretArray['password']; // Your code goes here;
Secrets Manager に保存されているシークレットのリスト
Secrets Manager によって保存されたすべてのシークレットのリストを取得するには、ListSecrets オペレーションを使用します。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); try { $result = $client->listSecrets([ ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
シークレットに関する詳細情報の取得
保存されたシークレットには、更新ルールに関するメタデータ、最終アクセス時間または変更時間、ユーザーが作成したタグ、および Amazon リソースネーム (ARN) が含まれています。Secrets Manager に保存されている、指定されたシークレットの詳細を取得するには、DescribeSecret オペレーションを使用します。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; try { $result = $client->describeSecret([ 'SecretId' => $secretName, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
シークレット値を更新する
新しく暗号化されたシークレットの値を Secrets Manager に保存するには、PutSecretValue オペレーションを使用します。
これにより、シークレットの新しいバージョンが作成されます。シークレットのバージョンが既に存在する場合、VersionStages パラメータと AWSCURRENT の値を追加し、この値を取得するときに新しい値が使用されるようにします。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; $secret = json_encode([ "username" => getenv("SMDEMO_USERNAME"), "password" => getenv("SMDEMO_PASSWORD"), ]); try { $result = $client->putSecretValue([ 'SecretId' => $secretName, 'SecretString' => $secret, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
Secrets Manager の既存のシークレット値のローテーション
Secrets Manager に保存されている既存のシークレットの値をローテーションするには、Lambda ローテーション関数と RotateSecret オペレーションを使用します。
開始する前に、シークレットをローテーションする Lambda 関数を作成します。現在、AWS コードサンプルカタログには、Amazon RDS データベースの認証情報をローテーションするための複数の Lambda コード例が含まれています。
注記
シークレットのローテーションの詳細については、「AWS Secrets Manager ユーザーガイド」の「AWS Secrets Manager シークレットのローテーション」を参照してください。
Lambda 関数を設定したら、新しいシークレットのローテーションを設定します。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; $lambda_ARN = 'arn:aws:lambda:us-west-2:123456789012:function:MyTestDatabaseRotationLambda'; $rules = ['AutomaticallyAfterDays' => 30]; try { $result = $client->rotateSecret([ 'RotationLambdaARN' => $lambda_ARN, 'RotationRules' => $rules, 'SecretId' => $secretName, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
更新が設定されている場合、RotateSecret オペレーションを使用して更新を実装できます。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; try { $result = $client->rotateSecret([ 'SecretId' => $secretName, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
Secrets Manager からのシークレットの削除
指定されたシークレットを Secrets Manager から削除するには、DeleteSecret オペレーションを使用します。シークレットが誤って削除されないようにするため、削除を元に戻すことが可能な復旧期間を指定できる DeletionDate スタンプが、自動的にシークレットに追加されます。復旧期間を指定しない場合のデフォルトの期間は、30 日です。
インポート。
require 'vendor/autoload.php'; use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException;
サンプルコード
$client = new SecretsManagerClient([ 'profile' => 'default', 'version' => '2017-10-17', 'region' => 'us-west-2' ]); $secretName = 'MySecretName'; try { $result = $client->deleteSecret([ 'SecretId' => $secretName, ]); var_dump($result); } catch (AwsException $e) { // output error message if fails echo $e->getMessage(); echo "\n"; }
関連情報
AWS SDK for PHP の例では、AWS Secrets Manager API リファレンスの以下の REST オペレーションを使用しています。
AWS Secrets Manager の使用の詳細については、AWS Secrets Manager ユーザーガイドを参照してください。