Real-time detection
We use Sentry for real-time error detection, configured not to collect personally identifiable information by default.
How we watch the platform, and how each change is traced.
Every change goes through a vulnerability-audit, static-analysis and safety-check pipeline before it can reach production. Sentry watches for errors in real time with PII stripped before events leave the server. Our Git history is public for open-source components and traced internally for private ones — every change is attributable, and every attribution is verifiable.
We use Sentry for real-time error detection, configured not to collect personally identifiable information by default.
Our CI chain runs on every change: dependency vulnerability audit (bundler-audit), application-level static analysis (brakeman), and soft-deletion filter consistency checks.
Our Git history is public for open-source components and traced internally for private components — every change is attributable.
Every pull request is checked against bundler-audit's CVE database; any known-vulnerable gem version blocks merge. GitHub's Dependabot opens pull requests for new security updates automatically — we don't wait to hear about CVEs the slow way.
Brakeman runs on every change with warning level 2. SQL injection, mass assignment, unsafe redirects, weak crypto — all surfaced at review time rather than at runtime.
A custom CI step greps for the NULL-unsafe where.not(status: "deleted") pattern. This is how we caught the login-for-users-with-NULL-status bug once; it now guards every future PR.
GitHub secret scanning watches the repo for accidentally committed API keys, webhook secrets and tokens. Matches trigger a page immediately, and any provider that GitHub knows about is also notified to revoke the key upstream.
Every production commit is reviewed through a pull request, attributed to a named author, and tagged against a specific release. There is no anonymous pathway from code to production.
Every pull request triggers a GitHub Actions workflow that runs — in order:
bundle-audit — CVE scan against the Gemfile.lockbrakeman — application static analysis (SQL injection, unsafe redirects, weak crypto, mass assignment, etc.)bin/null-safe-check — a custom grep that catches where.not(status: "deleted") patterns that would accidentally exclude NULL rows in Postgresrubocop --parallel — style and safety lintsAny step failing blocks merge. The order matters: dependency vulnerabilities are surfaced first because they're the cheapest to fix and the most common vector; style lints run last because they're the least load-bearing.
We explicitly set send_default_pii = false. On top of that, a before_send filter walks the event payload and strips any field matching config.filter_parameters before the event is serialized. The two safeguards are redundant on purpose: if Sentry's docs ever change the default, our before_send still holds the line.
The DSN only lives in production; staging and dev use a no-op initializer. A local stack trace never accidentally ships errors containing synthetic test data.
Every production change maps to a reviewed pull request and a signed commit. The GitHub security tab is actively monitored: Dependabot alerts, code scanning findings and secret scanning alerts all page us via email.
For the open-source components (device firmware, app), the Git history is public — anyone can audit the firmware that runs in their home, verify that our release tags match our source, and report discrepancies through the responsible-disclosure channel.