Alexa Skillのシークレット保存方法の確認

Alexaの認証用シークレットをテンプレートに直接書かず、アクセスを制限した保管先で管理してください。

説明

Alexa SkillのClientSecretをテンプレートに直接書くと、リポジトリ、デプロイ資料、テンプレート履歴から漏えいする可能性があります。RefreshTokenも保護が必要で、他の必要な値と組み合わせて使われると、許可されたスキル管理操作が悪用されるおそれがあります。

これらはLogin with Amazonが発行した実際のアプリケーション認証情報である必要があります。任意に生成したパスワードを既存のクライアントシークレットの代わりにはできません。

想定される影響

  • 漏えいしたシークレットが、許可された操作に悪用される可能性があります。
  • テンプレートのコピーやリポジトリ履歴に値が残り、交換やインシデント対応が難しくなる場合があります。

対処方法

実際のClientSecretとRefreshTokenをSecrets Managerに保存し、動的参照で渡してください。デプロイロールの取得権限を最小限にし、ログや出力に値を残さないでください。漏えいした認証情報は発行元で失効・交換し、新しい値がデプロイに反映されたことを確認してください。

例

認証設定の抜粋で、SkillPackageなどの必須設定は省略しています。ClientIdとVendorIdを実際の値に合わせ、同じLWAアプリのclientSecretとrefreshTokenをAlexaCredentialsに保存してください。例の文字列は実際の認証には使えません。

変更前

yaml
Resources:
  MySkill:
    Type: Alexa::ASK::Skill
    Properties:
      AuthenticationConfiguration:
        ClientId: "amzn1.application-oa2-client.1234"
        ClientSecret: "1234"
        RefreshToken: "Atzr|1234"
      VendorId: "1234"

ClientSecretとRefreshTokenをテンプレートに直接含めています。実際の値を置くと、テンプレートへのアクセス権を持つ人が読み取れます。

変更後

yaml
Resources:
  MySkill:
    Type: Alexa::ASK::Skill
    Properties:
      AuthenticationConfiguration:
        ClientId: "amzn1.application-oa2-client.1234"
        ClientSecret: "{{resolve:secretsmanager:AlexaCredentials:SecretString:clientSecret}}"
        RefreshToken: "{{resolve:secretsmanager:AlexaCredentials:SecretString:refreshToken}}"
      VendorId: "1234"

両方のシークレットを外部参照にします。保存値の変更だけでCloudFormationが自動取得し直すわけではないため、該当リソースの更新と反映結果を確認してください。

参考資料