Testing, Security & Cost Controls

GitHub Actions Quality Gates

The main branch workflow runs four independent jobs before a change is considered to have passed the quality gate:

  • Scan the full Git history for secrets with Gitleaks.
  • Compile the backend and run 204 pytest tests.
  • Run frontend tests and create the production build.
  • Check Terraform formatting, init -backend=false, and validate.

Successful LiveCap GitHub Actions run

CI is validation-only. The workflow does not deploy, run terraform apply, destroy resources, or migrate Terraform state.

Functional Testing

Backend – 204 Unit Tests

cd backend
python -m pytest -v

The test suite covers:

  • WebSocket session lifecycle (open, audio, close, timeout)
  • Session registry (global and per-IP limits)
  • Transcribe stream management (start, partial results, finalize)
  • Translate integration (finalized-only, language selection)
  • S3 export (TXT serialization, presigned URL generation)
  • Error handling (Transcribe error, connection drop, cleanup)

All 204 tests pass on Python 3.11. Running time: approximately 8 seconds.

Frontend – 11 Vitest Tests

cd frontend
npm test

Covers: component rendering, WebSocket hook state transitions, session timer, and microphone permission error states. Zero production vulnerabilities at release time.

Terraform – Syntax Validation Only

CI never applies infrastructure. It validates format and syntax only:

terraform -chdir=infrastructure/terraform fmt -check
terraform -chdir=infrastructure/terraform init -backend=false
terraform -chdir=infrastructure/terraform validate

Secret Scanning with Gitleaks

gitleaks detect --source . --verbose

Gitleaks runs against the full Git history. A clean scan is required before any git push.

Logs and Metrics

CloudWatch Application Logs

The FastAPI backend emits structured JSON logs to the /ecs/livecap-backend-dev CloudWatch log group. Log retention is 14 days.

# Stream live logs
aws logs tail /ecs/livecap-backend-dev --follow --region ap-southeast-1 --profile <aws-profile>

Key log events you will see during a session:

  • session_start – new session opened, with session ID and client IP hash
  • websocket_connect – WebSocket connection established
  • websocket_disconnect – client disconnected or timed out
  • session_end – session closed, with duration and reason
  • integration_error – error from Transcribe, Translate, or S3

CloudWatch log groups showing the livecap log group

Livecap log group detail with log streams

CloudWatch log stream detail showing backend session events

Sample log events from a live transcription session

Key Metrics to Monitor

MetricSourceWhat it tells you
HTTPCode_Target_5XX_CountALBBackend errors returned to CloudFront
HealthyHostCountALB Target GroupNumber of healthy Fargate tasks
CPUUtilizationECSTask CPU usage (alert if > 80%)
MemoryUtilizationECSTask memory usage
BlockedRequestsWAFWAF is actively blocking threats
4xx/5xx error rateCloudFrontEnd-to-end error rate

Setting a CloudWatch Alarm (Example)

Create an alarm that fires when the ALB returns 5XX errors:

aws cloudwatch put-metric-alarm `
  --alarm-name "livecap-alb-5xx" `
  --metric-name "HTTPCode_Target_5XX_Count" `
  --namespace "AWS/ApplicationELB" `
  --statistic Sum `
  --period 300 `
  --threshold 5 `
  --comparison-operator GreaterThanOrEqualToThreshold `
  --evaluation-periods 1 `
  --alarm-actions "arn:aws:sns:ap-southeast-1:720459752315:livecap-alerts" `
  --region ap-southeast-1 --profile <aws-profile>

Security Controls

Already Deployed

ControlImplementation
No root account usageDeployment uses IAM user camgiacntn
IAM least privilegeSeparate task execution role and task role
No hardcoded credentialsIAM roles only; no keys in .env, images, or Git
Private S3 frontendBlock public access + OAC origin
Private S3 transcriptsBlock public access; presigned URLs expire in 24 hours
HTTPS everywhereCloudFront terminates viewer TLS
WAF at CloudFront and ALBManaged rules in BLOCK mode; rate-based rules
CORS restrictionALLOWED_ORIGIN limits accepted frontend origin
Session limits4 global + 1 per IP prevent runaway Transcribe cost
Transcript expiry14-day S3 lifecycle rule; no raw audio stored
Secret scanningGitleaks runs in CI on full Git history
Immutable image tagsGit SHA tags prevent accidental latest drift

WAF Verification

Both Web ACLs are in BLOCK mode. Production probes confirmed:

  • Cross-site scripting (XSS) attempts → HTTP 403
  • Log4J exploit strings → HTTP 403

WAF runtime security verification – blocked XSS and Log4J probes

Cost Optimization

Current Cost Drivers (ap-southeast-1)

ResourceCost basisOptimization
ECS FargatePer vCPU-second + GB-secondScale to 0 when idle (target feature)
ALBFixed hourly + LCUIncurs cost even when ECS is at 0; only removed by destroying the full stack
NAT GatewayHourly + per-GB dataSingle NAT in one AZ (cost trade-off)
Amazon TranscribePer minute of audioSession limits cap usage
Amazon TranslatePer million charactersOnly finalized segments are translated
CloudWatchLog ingestion + storage14-day retention limits storage cost
WAFPer ACL + per ruleFixed baseline; worth it for blocking

Cost-Saving Practices Already Applied

  • 14-day log and transcript retention – avoids indefinite storage growth.
  • Session duration limit (30 min) – bounds maximum Transcribe minutes per session.
  • Session concurrency limits – prevent abuse-driven Transcribe/Translate costs.
  • Translate only finalized text – partial/interim results are discarded before translation, saving characters.
  • ECS scale-to-zero – Wake Lambda brings desired count from 0 → 1 on first request; idle scale-down returns it to 0 after inactivity.

Deployed AWS Budget

An AWS Budget alert is managed by Terraform at $50/month. It sends a notification directly to an email subscriber when actual or forecast spend approaches the threshold (not via SNS).

Note: Budget alerts are a delayed billing signal, not real-time enforcement. They help you notice runaway costs within hours, not seconds.