Amazon Alexa Smart Home → Home Assistant through nginx, with optional mTLS between AWS Lambda and your reverse proxy. CloudFormation deploy. No Envoy, no Nabu Casa subscription, no long-lived HA token in production.
Alexa skill → Lambda → https://ha.example.com/api/alexa/smart_home (mTLS) → nginx → HA
Alexa app → https://ha.example.com/auth/authorize + /auth/token (no client cert)
| Path | What |
|---|---|
lambda/ |
Python proxy (lambda_function.py), dependencies |
cfn/template.yaml |
CloudFormation: Lambda, IAM, Alexa invoke permission |
nginx/homeassistant.conf |
mTLS + OAuth path exceptions |
unraid/step-ca.xml |
unRAID Community Applications template for smallstep/step-ca |
docs/ |
Alexa setup, step-ca, nginx |
.github/workflows/ |
Build zip → S3 → cloudformation deploy (manual dispatch) |
- Home Assistant: enable
alexa.smart_home; set external URL tohttps://ha.example.com. - Alexa Developer Console: create Smart Home skill (payload v3); note Skill ID.
- mTLS (recommended): run step-ca (see
docs/step-ca.md), issue a client cert, store it in an SSM SecureString parameter. - Deploy: see
docs/alexa-setup.mdfor theaws cloudformation deploycommand, or run thedeployGitHub Action (setAWS_ROLE_ARN,ARTIFACT_BUCKET,AWS_REGION). - Link account in the Alexa app.
Region: North America → us-east-1.
This stack is designed to run at ~$0/month: arm64 Lambda at 128MB, free SSM standard-tier SecureString parameters instead of Secrets Manager, and a configurable CloudWatch log retention (default 90 days).
Without it, anyone on the Internet who can reach ha.example.com can attempt
Home Assistant logins. With mTLS, nginx refuses connections that do not present
a client certificate from your private CA — while Amazon’s OAuth callbacks
(/auth/*) stay reachable so account linking still works.
- Lambda proxy pattern: haaska and the Home Assistant Alexa docs.
- CA: Smallstep step-ca.