Data Flow & Architecture

Garage Check — technical overview for compliance review. Last updated: 26 July 2026.

Correction, 26 July 2026: an earlier revision of this page published today placed the door-state classification on operator-controlled hardware in Karlsruhe, Germany. That was based on a geolocation lookup of the front-door IP address and was wrong. The Karlsruhe host is a TLS-terminating reverse proxy operated by Contabo GmbH; the model and GPU are on operator-owned hardware in the United Arab Emirates. The corrected two-tier chain is described below and in Privacy Policy §4 and §11.

1. Data storage locations and systems

All stored data lives in Amazon Web Services, region us-east-1 (N. Virginia, USA) — accounts, garage configuration, check events, snapshot images, secrets, and logs.

One processing step runs outside AWS, and it spans two non-AWS locations. The door-state classification is performed by a model running on hardware Erbacci owns and operates in the United Arab Emirates. It is reached at vision.erbacciltd.com, whose public endpoint is a reverse proxy on a server hosted by Contabo GmbH in Karlsruhe, Germany (EU). TLS terminates at that proxy: Contabo is therefore an infrastructure sub-processor that handles the customer frame in plaintext in transit, and is declared as such rather than folded into "operator-controlled infrastructure". From the proxy the request is carried on to the inference node in the UAE, which runs the model. Since Garage Check is offered in the United States only, the classification path is an international transfer of the snapshot: US → Germany (EU) → UAE, for the duration of the inference call; it is disclosed as such in the Privacy Policy (§4 and §11). The operator persists nothing on either hop — the frame is decoded in memory on the inference node, sent to the model on that same machine, and discarded when the request ends; the inference route never writes it to disk. The proxy's role is transit only and the operator keeps no copy there; what Contabo's own proxy and host layers may retain in transit (access logs, request-body buffering) is not operator-attested and is an open item for this review. If the node errors, times out, or returns an unusable body, the classification falls back automatically to Amazon Bedrock in us-east-1 (see §2 step 3). Only the derived result — door state, confidence, and a vehicle-visible boolean — returns to AWS. Storage never leaves AWS.

StoreSystemContentsProtection / retention
AccountsAmazon DynamoDBUser record: Ring account id, email, subscription state, Ring access/refresh tokens (encrypted at rest)Encrypted at rest (AWS-managed); on unlink, Ring tokens and account binding are deleted and a minimal record (email, subscription state, disclaimer acceptance) is retained for re-link; fully deleted on account deletion
GaragesAmazon DynamoDBUser-entered garage config: name, selected camera id, time zone, nightly check time, preferencesEncrypted at rest; deleted on garage removal / account deletion
Check eventsAmazon DynamoDBDerived door-state result, scenario, timestamps, frame freshness (no identity data, no plates)Encrypted at rest; TTL 30/90 days by tier
Check snapshotsAmazon S3 (private bucket)Single still frame per check + SHA-256 hash of the image bytesEncrypted at rest; deleted by an automatic 90-day storage lifecycle at the latest, and immediately on camera removal, Ring unlink, garage history purge, or account deletion
Front door / TLS termination (no store)Reverse proxy (Caddy) at vision.erbacciltd.com, on a server hosted by Contabo GmbH, Karlsruhe, Germany (EU)The snapshot bytes in transit only. TLS terminates here, so Contabo infrastructure handles the frame in plaintext in transit. No model runs here and no classification is performed hereNot persisted by the operator — proxied on to the inference node, no operator-held copy. What Contabo's own proxy/host layer may retain in transit (access logs, request-body buffering) is not operator-attested — open item for this review. Reached over HTTPS with a required bearer token (a header-less request gets HTTP 403); the token is an AWS SSM SecureString read by the Lambda at runtime. Contabo is declared an infrastructure sub-processor for this hop
Door-state inference (no store)Operator-owned hardware in the United Arab Emirates, behind the Germany front door (FastAPI/uvicorn + Ollama on the node's GPU)The snapshot bytes, transiently, for the single "what state is this garage door in?" call. Model: qwen3.5 9B (Q8) served by Ollama, inference only — no training or fine-tuning on customer dataNot persisted. Decoded in memory, resized into an in-memory buffer, posted to Ollama on localhost, discarded at end of request; never written to disk. Node logs carry decision, confidence, latency, model, requestId only — never image bytes or base64
SecretsAWS Secrets Manager / AWS SSM Parameter StoreRing client credentials, HMAC key, JWT signing secret, Resend API key; vision-node bearer token (SSM SecureString)KMS-encrypted; least-privilege IAM access
LogsAmazon CloudWatch / CloudTrailDiagnostic and audit logs (no media)30-day retention (diagnostics)

2. Data flow between systems

  1. Scheduler → Sweep Lambda → SQS. A periodic sweep finds garages whose local check time has arrived (or a user taps "Check now") and enqueues one check job per garage. No media has been fetched yet.
  2. SQS → Check Lambda → Ring Partner API. The check Lambda retrieves the freshest available still frame for the selected outdoor camera over TLS. If no sufficiently recent frame exists, it opens a short (~8 s) server-side RTSP live session solely to prompt the camera to record ("wake"), then pulls a frame from that window; if the wake fails, it falls back to the newest older frame and marks the result stale. Wake media is machine-processed only — never viewed by a human.
  3. Check Lambda → S3, then classification. The single frame is stored in encrypted S3 in us-east-1 with a byte-exact SHA-256 hash. Storage stays in AWS; only the classification leaves it. Either way the model returns the door state only — open / partially open / closed / not visible / unknown — plus a boolean vehicle-visible flag. No person identification, no plate reading. Accuracy validation of the self-hosted model against the Bedrock path has been carried out. On 18 real frames labelled by hand — 9 with the door closed, 4 open, 5 with no door in view — the self-hosted model read 16 correctly and the Bedrock path 17. Neither ever reported a closed door when the door was open, which is the one error that would suppress an alert; the self-hosted model's mistakes all run the other way, reporting open when the door is shut, which produces a redundant notification rather than a missing one. The sample is small and drawn from a single camera position, and we re-measure when either model changes.
  4. Check Lambda → DynamoDB. The derived result (door state, scenario, timestamps, frame freshness) is written as a TTL'd check event keyed to the user.
  5. Notification dispatch. Each check result is delivered by email via Resend (our email delivery subprocessor) to the user's Ring-account email address, and additionally by push notification via APNs/FCM when a mobile device is registered: HIGH when the door looks open, LOW "all clear" when closed (user can opt out), MEDIUM when the check was inconclusive or no media existed. A push carries no image — only the wording of the result — because a pre-signed link is long enough to push the message past the size limit the mobile push services impose, and a message over that limit is discarded without notice. The result email contains the door-state result and a time-limited pre-signed link (valid up to 24 hours) to the snapshot image. Sign-in one-time codes are also emailed via Resend. Resend receives the recipient address and message content — never media bytes or account tokens.
  6. App → API Gateway → API Lambda. The user authenticates (passwordless email OTP → JWT) and reads their own garages, check history, and snapshots via short-lived presigned S3 URLs. All access is scoped to the authenticated account.
  7. Ring → Webhook Lambda. Ring delivers subscription and account webhooks; the Lambda verifies the HMAC-SHA256 signature on the raw body before processing.

3. Processing locations at a glance

StepWhereSnapshot stored there?
Snapshot retrieval, storage, all account/check dataAWS us-east-1 (N. Virginia, USA)Yes — encrypted S3, retention per Privacy Policy §7
Door-state classification — primary, entry pointReverse proxy on a Contabo GmbH server, Karlsruhe, Germany (EU) — TLS terminates here, so the frame is handled in plaintext in transit by Contabo infrastructureNot stored by the operator — proxied through. What Contabo's own systems retain in transit is not operator-attested
Door-state classification — primary, inferenceErbacci-owned hardware in the United Arab Emirates, behind the Germany entry pointNo — in memory only, discarded at end of request
Door-state classification — fallbackAmazon Bedrock, AWS us-east-1 (USA)No — not retained beyond the inference call
Email delivery (Resend), push (APNs/FCM)Subprocessors; address + message content, or push token + textNo — never receive media bytes

Full written descriptions of processors, the international transfer, and retention are in the Privacy Policy (§4, §6, §7, §11).