VEAI-LAB. ← All case studies
Case Study · Identity / Security

A Fail-Closed Identity Boundary for an Alexa Skill — Without Breaking the Household Already Using It

A working single-household medication-logging skill needed to become safe for invited households. I designed and delivered a fail-closed identity boundary — Alexa must resolve exactly one household before it touches any data — behind a feature flag, so the family already relying on it in production was never at risk.

Project: Medication Promise (おくすりの約束) · Role: Solo technical PM / engineer · Evidence: public repo larai-w/medication-promise-app (issue #12, tasks #22–#26, PR #33)
Medication Promise voice flow with a fail-closed household-identity boundary using Cognito and aws-jwt-verify
Voice + web logging behind a fail-closed household-identity boundary (Cognito · aws-jwt-verify).

Context

Medication Promise lets a family record medication timings by voice through Alexa or from a web app, running in a private-access production deployment for one household. The Alexa Lambda, however, still read and wrote through a fixed legacy partition (USER#default-user). Acceptable for one private household — but not a valid path to an invited-household beta, where a skill must never operate on the wrong family's data.

Constraints

What I did — and deliberately didn't do

I scoped #12 to a verifiable identity boundary for one linked household, and explicitly out of scope: public self-service signup, multi-household switching inside Alexa, and role management. Ambiguity (a linked user mapping to more than one active household) fails closed rather than guessing.

Architecture & security decisions

The data path moved from "construct the partition key from a fixed USER_ID" to resolve identity, then derive the partition:

Key decisions: one shared identity provider for Web and Alexa (Cognito), so both surfaces resolve the same sub; fail-closed everywhere — missing, invalid, expired, ambiguous, or disabled identities are rejected before any DynamoDB access, each mapped to a supportive, non-leaking spoken message, with no raw tokens logged; and injectable seams (token verifier and membership lookup are parameters) so the boundary is unit-testable without a real user pool.

Delivery & governance (the safe cutover)

The most important product decision was not flipping production. The handler runs in legacy or household mode via an ALEXA_HOUSEHOLD_MODE environment flag, defaulting to legacy. Production keeps the working single-household path until the linked flow is verified end to end on a real device; only then does the flag flip — and rollback is flipping it back. The migration is identity state, not record state: records already live in a household partition, so there's no risky backfill. Work was framed as a user story with acceptance criteria, split into tasks #22–#26, and shipped via reviewed PR #33 with CI green.

Outcomes

Honest limitations

Lessons

Evidence

Repo: github.com/larai-w/medication-promise-app — issue #12, tasks #22–#26; PR #33. docs/ALEXA_ACCOUNT_LINKING_CONFIG.md (sanitised config), design docs, and alexa/ (household.mjs, cognito.mjs, dynamodb.mjs, index.mjs, tests).

Shipping something real people already depend on?

Release discipline for health-adjacent, multi-tenant builds — reversible cutovers, boundary tests, no drama.

Book a Free Consultation