Alexa Skill secret storage needs review

Keep Alexa authentication secrets out of template text and manage them in an access-controlled secret store.

Description

Writing an Alexa Skill ClientSecret directly in a template can expose it through repositories, deployment material or template history. RefreshToken also needs protection; leaked credentials used with the other required values can enable misuse of permitted skill-management operations.

These must be actual application credentials issued by Login with Amazon. A randomly generated password cannot replace an existing client secret.

Potential impact

  • Exposed secrets may be used to perform the operations they authorize.
  • Copies in templates and repository history can complicate credential replacement and incident response.

Remediation

Store the actual ClientSecret and RefreshToken in Secrets Manager and pass them through dynamic references. Limit the deployment role’s retrieval permissions and keep values out of logs and outputs. Revoke or replace exposed credentials at the issuing service and verify that deployments use the new values.

Examples

These authentication excerpts omit required settings such as SkillPackage. Use the actual ClientId and VendorId, and store clientSecret and refreshToken for the same LWA app in AlexaCredentials. The literal example strings are not usable credentials.

Before

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

ClientSecret and RefreshToken are embedded in the template. Anyone with access to it could read actual secrets placed there.

After

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"

Both secrets are referenced externally. Changing the stored values alone does not make CloudFormation retrieve them again; verify the relevant resource update and its result.

References