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
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
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.