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.
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.
| Store | System | Contents | Protection / retention |
|---|---|---|---|
| Accounts | Amazon DynamoDB | User 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 |
| Garages | Amazon DynamoDB | User-entered garage config: name, selected camera id, time zone, nightly check time, preferences | Encrypted at rest; deleted on garage removal / account deletion |
| Check events | Amazon DynamoDB | Derived door-state result, scenario, timestamps, frame freshness (no identity data, no plates) | Encrypted at rest; TTL 30/90 days by tier |
| Check snapshots | Amazon S3 (private bucket) | Single still frame per check + SHA-256 hash of the image bytes | Encrypted 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 here | Not 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 data | Not 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 |
| Secrets | AWS Secrets Manager / AWS SSM Parameter Store | Ring client credentials, HMAC key, JWT signing secret, Resend API key; vision-node bearer token (SSM SecureString) | KMS-encrypted; least-privilege IAM access |
| Logs | Amazon CloudWatch / CloudTrail | Diagnostic and audit logs (no media) | 30-day retention (diagnostics) |
vision.erbacciltd.com. That endpoint is a reverse proxy on a Contabo GmbH server
in Karlsruhe, Germany (EU) which terminates TLS — Contabo therefore handles
the frame in plaintext in transit and is declared as an infrastructure sub-processor — and
the request is carried on from there to the inference node on Erbacci-owned hardware
in the United Arab Emirates, where qwen3.5 9B (Q8) reads it on the node's GPU.
Inference only; the operator persists nothing on either hop (see §1 — what Contabo's own
layer retains in transit is not operator-attested). Net effect for a US customer
frame: US → Germany → UAE, with only the derived result returning to
AWS.us.anthropic.claude-haiku-4-5-20251001-v1:0), auto-escalating to Claude
Sonnet 4.5 (us.anthropic.claude-sonnet-4-5-20250929-v1:0) on any result that is
not a confident “closed”; inference-only, no training.backend/shared/local-gate): a hard
timeout on the node call, and an unconditional fall-back to the Bedrock path on error,
timeout, empty body, non-JSON body, or an unresolvable token. A circuit breaker opens after
5 consecutive failures (~45 s), then half-opens behind a /healthz probe. A check
is never dropped because the node is unavailable.| Step | Where | Snapshot stored there? |
|---|---|---|
| Snapshot retrieval, storage, all account/check data | AWS us-east-1 (N. Virginia, USA) | Yes — encrypted S3, retention per Privacy Policy §7 |
| Door-state classification — primary, entry point | Reverse proxy on a Contabo GmbH server, Karlsruhe, Germany (EU) — TLS terminates here, so the frame is handled in plaintext in transit by Contabo infrastructure | Not stored by the operator — proxied through. What Contabo's own systems retain in transit is not operator-attested |
| Door-state classification — primary, inference | Erbacci-owned hardware in the United Arab Emirates, behind the Germany entry point | No — in memory only, discarded at end of request |
| Door-state classification — fallback | Amazon 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 + text | No — never receive media bytes |
Full written descriptions of processors, the international transfer, and retention are in the Privacy Policy (§4, §6, §7, §11).