Email colton@futurebuild.ai.
Do not open a public issue, discussion, or pull request for a suspected vulnerability. This module is a plug-in seam: hosts embed it in their own servers, so a public report is a public exploit against every deployment that has not upgraded yet. Report privately, and we will coordinate disclosure with you.
If you would rather not use email, use GitHub's private vulnerability reporting on this repository. Both routes reach the same people.
Whatever you have. A useful report usually has:
- the version or commit you tested;
- what an attacker gains — read access, a bypassed gate, a crash, a leak;
- the smallest reproduction you can manage (a failing Go test is ideal, since the SDK has no dependencies and runs anywhere);
- anything you already know about a fix.
You do not need a CVSS score, a CVE, or a polished write-up. Send the rough version rather than sitting on it.
| Stage | Target |
|---|---|
| Acknowledgement that a human has read it | 3 business days |
| Initial assessment — is it a vulnerability, and how bad | 10 business days |
| Fix released, or a dated plan if the fix is large | 90 days from the report |
If we go quiet past those windows, escalate by replying to your own thread. We would rather be nagged than have a report rot.
We will credit you in the advisory and the changelog under whatever name you choose, or keep you anonymous. There is no bug bounty.
We ask for the usual 90 days before public disclosure, and we will move faster than that whenever we can. If a vulnerability is already being exploited, tell us and we will drop the embargo — an in-the-wild bug is better published than kept quiet.
In scope — anything in this repository:
apps— the SDK, its registry, its enablement gate, and its HTTP handler.memstore— the in-memoryapps.Store.examples/hello-app— the example host and app.- The repository's own CI and release tooling.
Things that are genuinely this module's problem, and that we want to hear about:
- A gate bypass — a request reaching a disabled app's route.
- A dependency-validation bypass — a toggle that leaves the catalog in a
state
Registry.Validatewould reject. - Enablement corruption — anything that makes
Syncoverwrite the operator-ownedEnabledcolumn, or delete a record. - Leakage through the error path —
JSONErrorResponderor theapp_disabled/app_core/app_dependency_conflictenvelopes revealing more than the machine-readable code and a generic message. - A panic reachable from a request.
AddandAddStaticpanic by design, but only during startup wiring; a panic on a served request is a bug. - Resource exhaustion — unbounded allocation or a deadlock reachable through the SDK's public API.
- A supply-chain regression — anything that adds a third-party dependency
to
go.mod. The zero-dependency guarantee is a security property here, not just a licensing one.
Out of scope:
- Vulnerabilities in a host that embeds the SDK, including its
Storeimplementation, its authentication, and its admin guard. Report those to that project. If the SDK's contract led a host into the mistake, that is in scope — tell us and we will fix the contract or the documentation. - Vulnerabilities in a third-party app built against the SDK.
memstorelosing data on restart. It is documented as unfit for deployment and is not a persistence guarantee.- Fail-open enablement.
IsEnableddeliberately reports enabled when the store is unreachable, when the key is unknown, and when there is no store at all: a catalog that cannot be read must not take a working deployment offline. This is a documented design decision, not an authorization mechanism — enablement is an operator's install/uninstall switch, and access control is the host's job. If you can make the store fail on demand in order to turn an app back on, that is interesting; say so. AddStaticandAddpanicking, on their documented conditions.
Pre-1.0, only the latest tagged release is supported. Fixes land on main and
in the next tag; there are no backports to earlier v0.x tags. See the
stability policy in the README.
Two properties are worth stating plainly, because they are what a reviewer should check first:
- Zero third-party dependencies.
go.modhas norequireblock, so this module contributes no transitive supply-chain surface to anything that imports it.go list -m allprints exactly one line. Any pull request that changes that is a breaking change and is treated as one. - No I/O of its own. The SDK opens no sockets, reads no files, and issues
no queries. Everything that touches the outside world arrives through a
host-supplied port (
Store,AuditSink,ErrorResponder) or through thenet/httphandlers the host mounts.