Skip to content
security

How we lock things down.

Last updated: May 20, 2026

The short version

Found a vulnerability? Email security@pittwater.co. We respond within 72 hours, fix what's fixable, and credit you in the changelog if you'd like the credit.

We don't store payment data on our infrastructure. We don't store customer audio/video on our infrastructure. The data we do have — your name, your email, the message you wrote us — travels over TLS, sits with vetted processors, and gets accessed by a small team that all has 2FA on.

Our Privacy Policy covers the data side in detail. This page covers the engineering side: how we lock things down and how to tell us when we haven't.

Reporting a vulnerability

Email security@pittwater.co with as much detail as you can share — affected URL, reproduction steps, what you observed, what you expected. Screenshots and PoCs help.

What we promise: - First response within 72 hours of receipt - Status update at least every 7 days until the issue is resolved - No legal action against good-faith researchers (i.e. you didn't exfiltrate user data, didn't degrade service for others, gave us reasonable time to fix before disclosing) - Public acknowledgment in the changelog if you want it; private handling if you don't

What we don't do yet: a paid bug bounty. If we ship one in the future, we'll announce it here first.

For the machine-readable version, see /.well-known/security.txt (RFC 9116).

What's in scope

In scope:

- pittwater.co — this website and its API endpoints (including /api/monitoring/pulse which feeds the public monitoring readout) - pitth2o.com — the live-control demo subdomain - pittwater.sanity.studio — our hosted CMS (login required; the auth flow itself is in scope)

Out of scope:

- Social engineering of our team - Physical access to the Brookfield office - Denial-of-service findings ("I can flood the rate limiter" — yes, that's its job) - Vulnerabilities in third-party services we use (Vercel, Sanity, Upstash, Cloudflare, Resend, XYTE) — report those to the vendor directly; we'll happily co-coordinate if relevant

How we encrypt things

In transit: every request to pittwater.co and pitth2o.com uses TLS 1.2+. HSTS is on. HTTP requests are 301'd to HTTPS at the edge. The live-demo bridge between Vercel and our office runs over a Cloudflare Tunnel using QUIC + TLS — no inbound ports open on our office firewall, ever.

At rest: the data our processors hold is encrypted at rest per each processor's standards. Sanity, Vercel, Upstash, Cloudflare, and Resend all encrypt at rest by default; their security pages cover the specifics. We don't run our own storage outside of those.

Secrets: API tokens for the third-party services — Sanity write token, Upstash Redis credentials, Resend key, the office bridge shared secret, and the XYTE monitoring API key — live as encrypted environment variables in Vercel. The browser never receives any of them. The bridge shared secret is rotated when a team member with access leaves. We don't commit secrets to the repository.

Who can access your data

Internal access is limited to the Pittwater team. Every team member with access to our email, Slack, Sanity, Vercel, or the production bridge has 2FA enforced on their account. We don't share credentials.

External access:

- Engineering vendors — none. We don't grant external developers production access. - Processors — exactly the set listed in our Privacy Policy. Each one only sees the data it needs to do its job (e.g. Resend sees the email being sent; Slack sees the message body; Cloudflare Stream sees the camera bytes). - Law enforcement — we comply with valid US legal process. We require a subpoena for non-content records, and a warrant for content. We notify the affected party where we are legally permitted to do so.

Incident response

If something happens that affects user data — accidental disclosure, unauthorized access, processor breach — we'll:

1. Contain the scope as fast as we can (rotate credentials, isolate the affected component) 2. Determine the affected data set 3. Notify affected users within 72 hours of confirmation where personal data was involved, regardless of jurisdiction 4. Publish a public post-mortem if the incident affected the public website or a non-trivial number of users 5. File regulatory notifications where required (CT, EU, etc.)

We have not yet had an incident requiring user notification. If this section ever needs to point to a post-mortem instead of describing the process, we'll update accordingly.

Live demo specifics

The live-control demo on the homepage is engineered to fail safely:

- No persistent state about visitors — session IDs are random 16-byte tokens, IP addresses are SHA-256 hashed, everything is deleted within ~1 hour - Rate-limited at the API gate (120 req/min per IP) so a scripted abuser can't burn out a relay - One controller at a time — the queue enforces serialization so commands can't race - Idle safe-state — if no one drives the room for 5 minutes, the bridge fires "lights off" + "wall off" so the room doesn't stay in a weird state overnight - Authenticated bridge — Vercel and the office bridge share a rotating secret; without it the bridge rejects every request

The hardware itself (Q-SYS Core, displays, switchable glass) is on an isolated VLAN with no inbound internet access. The bridge is the only path in or out.

Monitoring page specifics

The /monitoring page is engineered so the visitor's browser never touches our monitoring backend directly:

- API key never leaves the server. The XYTE Organization API token lives as an encrypted environment variable in Vercel. The browser never sees it. Every XYTE fetch happens server-side, from Vercel. - Anonymization at the boundary. Customer, site, and device identifiers from XYTE are run through HMAC-SHA256 with a project-specific salt before they hit the page. The codes are stable (same input → same output) so users can follow an entity across the feed, but the hash is one-way and cannot be reversed without the salt. - Public poll endpoint. /api/monitoring/pulse is the only browser-callable endpoint. It returns counters, the top of the activity feed, and the office-bridge ping result — all already anonymized. The route is cached server-side for 30 seconds so a hundred concurrent visitors don't multiply backend load. - Visibility-aware polling. The browser only polls /api/monitoring/pulse while the tab is visible. Hidden tabs stop polling immediately and resume on return. - Bridge ping is HEAD-only. The server reaches the Brookfield bridge with a 2.5-second-timeout HEAD request to measure round-trip latency. The bridge's authentication secret is not used or exposed; any HTTP response (including 4xx) confirms reachability. - noindex. The /monitoring page sends robots: noindex, nofollow until we're explicitly ready to launch it publicly. The route is also excluded in robots.txt during this window.

Contact

Vulnerability reports: security@pittwater.co Everything else: hello@pittwater.co Mail: Pittwater, 487 Federal Rd, Brookfield CT 06804, USA