3.5 KiB
Reference issues or pull requests here (e.g., "Closes #123")
Holistic Rubric: Multi-Tenant Authorization in Background Workers
Task Summary
The goal is to refactor background SQS worker handlers and database services in potion-voice to enforce multi-tenant authorization by scoping all MongoDB queries with userId. The solution must prevent cross-tenant IDOR vulnerabilities while preserving async execution order, SQS queue lifecycle reliability, and error-handling stability.
Core Requirements
-
Multi-Tenant Query Scoping:
- All database reads (
findOne), updates (findOneAndUpdate), and status updates must includeuserId: jobUserIdin the query criteria. - Primary models (
UserAudioProfile,Salutation,VoiceCloning) and secondary models (Recording,RecordingSalutation) must be strictly scoped.
- All database reads (
-
Async Dependency Execution Order:
- In
voice-synthsizer-job-handler/index.js, dependent fields likesalutationToUpdate.recordingIdmust be retrieved before querying secondary models (recordingModel.findOne(...)). - Grouping dependent model lookups inside
Promise.allbefore parent models resolve is invalid and leads to runtime crashes (ReferenceError: recordingId is not defined).
- In
-
SQS Queue Message Lifecycle Integrity:
- SQS queue messages must only be deleted via
deleteMessageFromSQSafter processing completes successfully. - Moving message deletion above execution steps (before synthesis, ffmpeg rendering, or S3 persistence) causes permanent, unrecoverable data loss if execution fails midway.
- SQS queue messages must only be deleted via
-
Robust Error Recovery:
- Authorization failures must throw catchable errors or return early before running external Python scripts.
- Error handlers in
catchblocks must not fail or throw unhandled Promise rejections.
Key AI Failure Modes (Meaningful Failures)
-
Failure Mode 1: Async Dependency Crash (
recordingIdis undefined) The agent attempts to optimize database queries by fetchingUserAudioProfile,Salutation, andRecordinginside a singlePromise.allblock. BecauserecordingIdis derived fromsalutationToUpdate.recordingId, referencingrecordingIdin thePromise.allarray causes aReferenceErroror queries MongoDB with_id: undefined. -
Failure Mode 2: Premature SQS Message Deletion (Silent Data Loss) The agent moves
deleteMessageFromSQSup before job processing or Python execution completes. If S3 upload or speech rendering fails, SQS cannot redeliver the message, resulting in silent job loss. -
Failure Mode 3: Invalid Mongoose
findByIdQuery Objects The agent attempts tenant scoping by passing a query object to Mongoose'sfindById(e.g.Model.findById({ _id: id, userId })). In Mongoose,findByIdexpects a primitive string or ObjectId, causing runtimeCastError: Cast to ObjectId failed. -
Failure Mode 4: Incomplete Secondary Query Scoping The agent updates primary model queries (
UserAudioProfile) but forgets secondary queries (Recording,RecordingSalutation, or status updates insidecatchblocks), leaving secondary models exposed to cross-tenant mutation.
Scoring Guide
- PASS: All database operations are tenant-scoped by
userId, query dependency order is maintained, SQS message deletion occurs only after success, and all tests pass without runtime exceptions. - FAIL: Any query is unscoped,
recordingIdis referenced beforesalutationToUpdateresolves, SQS messages are deleted prematurely, or Mongoose query errors throw at runtime.