Security
Security & Disclosure Policy
Noddr lets a head gesture approve a coding agent’s tool calls. That means it sits directly in a privileged path: something that says “yes” to commands running on your machine. We would rather hear about weaknesses in that path from you than from a user.
1. Safe Harbour
If you act in good faith and within the scope below:
- We will not pursue legal action against you.Not under the CFAA, not under the DMCA’s anti-circumvention provisions, and not under any contract or computer-misuse statute available to us.
- We will not contact your employer about your report at all, unless you ask us to.
- We will not require an NDA before we will read your report, and we will not make silence a condition of anything.
- You may publish. We will ask you to coordinate timing so users have a fix available first, and we will give you a real date rather than an open-ended request to wait. If we miss that date, that is our problem, not a reason for you to keep waiting.
Two honest limits. We cannot grant safe harbour on behalf of Supabase, Vercel, Google Cloud, or Apple — if you test their infrastructure, their programmes govern that. And safe harbour does not extend to the activities in Section 3 marked out of scope, because those harm people who did not consent to your research.
Noddr is run by one person. There is no security team and no rota. You will get a considered reply, but you will not get one at 3am.
2. Reporting
Email security@noddr.cloud. PGP is not currently offered; if you need an encrypted channel before sending details, say so in a first message containing nothing sensitive and we will arrange one.
Put URGENT in the subject if you believe something is being actively exploited, or if you have found data exposed publicly. That routes past the ordinary queue.
Useful to include, if you have it:
- Which component — see Section 3
- Steps to reproduce, or a proof of concept
- What an attacker gets, and what they need first
- Whether you intend to publish, and roughly when
Please do not send us a Noddr installation identifier or link secret belonging to anyone but yourself. If your report requires demonstrating against a real install, use your own.
2.1 What to expect
| Stage | When |
|---|---|
| Automatic acknowledgement, confirming safe harbour | Immediately |
| Reply from a person | Within 1 business day |
| Triage decision, with reasoning | Within 5 business days |
| Progress updates | On dates we commit to, whether or not there is progress |
If a date slips you will hear it from us on that date, not afterwards.
We do not run a bug bounty and do not pay for reports. Noddr is pre-release software built by one person and there is no budget for it. We would rather tell you that before you invest time than after. Credit is offered on any terms you like, including none.
3. Scope
3.1 In scope
| Component | What it covers |
|---|---|
| iOS app | Gesture recognition, approval UI, Live Activity, widgets, Keychain handling |
| macOS app | Menu-bar app, floating verdict panel, and its local read of the install identifier and link secret. Unsandboxed, and distributed as a direct download rather than through the App Store — so its distribution and update integrity are in scope too |
| Mac helper | Bonjour advertiser, the link handshake, and local state under ~/.noddr/ |
| Entitlement vouching | The signed subscription claim the phone broadcasts to the Mac |
| Agent hook | The hook itself, the destructive-command denylist, and verdict signature verification |
| Backend functions | The speech-synthesis proxy, the push proxy, and database access policies |
| LAN relay | The optional zero-dependency local relay |
| Website | noddr.cloud |
Both apps run the same gesture and approval code, so a finding in one is usually a finding in both — tell us if you have only checked one.
3.2 Out of scope
Not because these are uninteresting, but because they harm people:
- Denial of service, volumetric testing, or anything that degrades the service for other users
- Social engineeringof the maintainer, users, or any provider’s staff
- Physical attacks, or attacks requiring physical access to an unlocked device
- Testing against installs you do not own, or against identifiers you did not generate
- Accessing, modifying, or retaining another person’s data. If you encounter someone else’s data, stop, do not save it, and tell us
- Third-party infrastructure— Supabase, Vercel, Google Cloud, Apple. Report to them. If our configuration of their service is what makes something exploitable, that part is ours and we want it
3.3 Reports we will likely close as informational
We will still read these and still owe you a reasoned reply, but they are unlikely to be treated as vulnerabilities absent an exploitation path:
- Missing SPF, DKIM, or DMARC records
- Absent security headers, or no CSP, on pages with no authenticated state or state-changing actions
- Clickjacking on pages with no sensitive actions
- Software version disclosure, banner grabbing, directory listings
- Missing rate limits, other than on the backend functions
- Output of an automated scanner submitted without an assessment of impact
- Anything already listed under Section 5— though see the note there, because duplicates are still worth reporting
4. Threat Model, Stated Plainly
Noddr has no accounts. There is no password to steal and no session to hijack. The security boundary is a random per-install identifier and a link-time secret, and being clear about what each protects is more useful to you than a generic hardening list.
| Capability | Install ID alone | Install ID + link secret |
|---|---|---|
| Read the approval channel | Yes — see S1 | Yes |
| Forge an “allow” verdict | No — HMAC-verified, fails closed | Yes |
| Inject text into the agent’s reason string | No — covered by the same signature | Yes |
| Grant yourself a paid subscription | No — vouches are signed too | Yes |
Both values are transmitted over mDNS on the local network in a Bonjour TXT record, from the helper’s first run until a phone confirms the link. Neither is ever sent over the internet. Where the macOS app and the hook share a machine, neither goes on the network at all — the app reads them from ~/.noddr.
Attacks we consider most serious, in order:
- Approving a command without the link secret — that is, defeating verdict signing
- Obtaining the link secret remotely, without LAN presence during pairing
- Getting a destructive command approved by gesture that the denylist should have forced on-screen, where the bypass does not require the user’s own agent to construct it — see S7
- Reading approval traffic from outside the LAN without the install ID
- Exfiltrating command content to a party not disclosed in the privacy policy
5. Known Issues
S1 — The install ID grants read access to the approval channel
Approvals ride an ephemeral broadcast channel named after the installation identifier, and the publishable key ships in the app and the hook by design. There is no row-level policy on the underlying message table, so anyone who knows an install ID can subscribe and watch every command an agent proposes— file paths, code fragments, hostnames, and any secret the agent happens to put on a command line.
Disclosed in Section 6, point 4 of the privacy policy. Planned mitigation: a custom-token access policy keyed on the link secret, which is only now possible because that secret exists.
Related, same area: anyone who can broadcast on the link channel can make the Mac stop advertising, which conveniently hides the fact that an ID was captured. Low impact alone; listed because it is a useful step in a chain.
S2 — Announcement text is sent to a third-party speech service
When the enhanced voice is used, the announcement — which for shell commands embeds the raw command — is forwarded to Google Cloud Text-to-Speech. A command containing an API key or a customer name reaches a third party. Disclosed in Section 8.2. There is currently no user-facing toggle to prevent it, on either platform; the planned mitigation is a Settings switch, defaulting on but honestly labelled, and possibly a redacted announcement. The product falls back to the on-device voice whenever cloud synthesis fails, so this is a quality feature rather than a dependency.
S3 — This site loads fonts from third-party origins
The Site loads stylesheets from Fontshare and Google Fonts, disclosing every EU visitor’s IP address without consent. A known GDPR exposure. Planned mitigation: self-host.
S4 — The install ID is written to a cleartext log
The Mac helper logs the installation identifier to a log file under ~/.noddr/, which the system keeps indefinitely — despite a comment elsewhere in the code claiming the ID is never logged. Given S1 that file is credential material and is likely to be swept up by backup tools and support-bundle scripts. The link secret is not logged. Planned mitigation: stop logging the ID, or truncate it.
S5 — Approval content appears on the lock screen
The Live Activity and Dynamic Island show the approval summary without unlocking the phone. Disclosed in Section 6, point 5. We are considering truncating it; the full text is available in-app regardless.
S6 — The synthesis rate limiter fails open
The speech-synthesis proxy treats a rate-limit lookup error as “allowed”, because a broken limiter should not silence an approval flow. The consequence is a billing and availability exposure on an unauthenticated endpoint during a database outage, not a privacy one. A secondary cap at the provider quota level is the planned backstop.
S7 — The destructive-command denylist is not a security boundary
The denylist reads a command as text and forces recognisable destructive shapes onto the screen. Text has infinite ways to say the same thing, and we do not claim it cannot be evaded— a substituted command, a shell alias, a one-line script in another language, or an innocuously named file will all get past it. The threat model is a user nodding by reflex, not an adversary crafting input.
A bypass report is interesting if the destructive command arrives by a route the user’s own agent would plausibly produce, or if you have found public copy of ours implying that destructive commands cannot be approved by a nod. Section 16.5 of the privacy policy is drafted to avoid that claim; if we have broken it somewhere, that is a real problem and we want to know.
6. Disclosure
We prefer coordinated disclosure and will tell you when a fix is available to users rather than asking you to wait indefinitely. If you have a timeline, tell us and we will work to it, and say so plainly if we cannot meet it.
We will not ask you to soften a write-up. If we disagree with a characterisation we will say so and let you decide what to publish.
Credit on any terms you prefer, including anonymity.
7. If You Find Something Exposed Publicly
If you find Noddr data, keys, or user command content exposed somewhere it should not be — a public bucket, a paste site, a search index:
- Do not download or retain it. Note enough to identify it and stop.
- Email security@noddr.cloud with
URGENTin the subject. - Do not publish the location until it is secured.
We will acknowledge that we are investigating without confirming or denying specifics, because a premature confirmation is itself a disclosure. That is not us being evasive with you.