This document is not yet in force. Cluebase is not incorporated at the time of writing, so the legal entity, registered address and governing law are marked below as pending rather than stated. Everything else describes how the service actually operates today. This notice is removed when those three values are filled in.
Full-stack layer audit
A second assessment, taken deliberately into the areas the launch-week audit did not reach: billing and payment handling, the plan limits that meter usage, the public marketing site, and the email infrastructure. The layers covered in August were re-verified against current code at the same time.
1. What was audited
The launch-week audit concentrated on the isolation boundary and the widget. This one covers the money path and everything around it:
- the payment webhook, checkout, overage packs and billing portal, traced end to end from signature verification to entitlement;
- plan usage limits: how a monthly allowance is counted, reserved, refunded and reset, including the arithmetic itself;
- all 61 API routes, each re-traced for authentication and authorization;
- the dashboard assistant and the rescue agent, for prompt injection, cost ceilings and data disclosure;
- the marketing site and its waitlist endpoint, audited here for the first time;
- the data layer: row-level security across every table, and every database migration;
- account, team, role and invitation flows, re-verified against current code.
2. How it was tested
These are internal reviews. Cluebase has not yet commissioned a third-party penetration test, and this page will say so plainly until it has.
2.1 Full source review
Every route’s authorization logic read rather than sampled, and the shared helpers behind them checked for how they behave when a database read fails, not only when it succeeds. The failing-by-default guard that classifies each route’s authorization model passed 61 of 61 routes.
2.2 Arithmetic and semantics verification
Where the same rule is implemented twice, in application code and in the database, the two were executed against each other rather than read for agreement. This is what surfaced the one metering finding below, and the check is now a permanent test.
2.3 Automated scanning
An open-source scanner was run against both repositories and the public site. It produced eight findings, all eight of which were false positives on inspection, and contributed nothing to the results below. Recorded here because a methodology section that lists only the techniques that worked is not a methodology section.
3. Results at a glance
| Severity | Count | Meaning |
|---|---|---|
| Critical | 0 | cross-tenant data access or account takeover |
| High | 2 | one billing reliability defect, one caught before release |
| Medium | 4 | metering accuracy, a rate limit, and two in unreleased code |
| Low | 1 | migration hygiene |
| Informational | 0 | — |
Two things belong alongside that table. No finding exposed customer data, and none permitted access to another workspace: the isolation properties tested in August held throughout. And four of the seven were in code written during the audit window itself, caught in review before it was released. Only one of the two high-severity findings had ever run in production, and its effect was that a paid plan change could fail to apply, which costs us revenue rather than exposing anyone.
All seven were fixed the same day.
4. Findings
Every finding from the assessment, in full, on the same terms as the report below it.
| ID | Finding | Severity | Status |
|---|---|---|---|
| CB-LW-11 | The payment webhook could not distinguish a temporary database read failure from an unrecognised customer, and in that case acknowledged the event without applying it. A paid plan change could silently fail to take effect, with no retry. No data exposure. Fixed so the provider retries instead. | High | Fixed |
| CB-LW-14 | New email code, if deployed ahead of its database migration, would have skipped the list that suppresses mail to addresses which have bounced or complained. Never released. The check now refuses to send rather than continuing when it cannot be performed. | High | Fixed before release |
| CB-LW-09 | Application code and the database computed a monthly cycle boundary by different rules, so on a small number of month-end dates a conversation allowance could reset earlier than intended. Metering accuracy only. Fixed with one shared calculation matching the database, and covered by permanent tests. | Medium | Fixed |
| CB-LW-10 | On the marketing site, the waitlist rate limit identified callers from a header the caller controls, so it could be bypassed. The corrected implementation already existed in the main application and had not been carried across. It now is. | Medium | Fixed |
| CB-LW-12 | A new unsubscribe link acted on an ordinary page load, so automated mail scanners could unsubscribe a recipient who never clicked it. Never released. Now requires explicit confirmation. | Medium | Fixed before release |
| CB-LW-13 | A new internal endpoint reused an existing shared secret instead of holding its own, widening what that credential authorised. Never released. Given a dedicated credential. | Medium | Fixed before release |
| CB-LW-15 | A database migration was not safely re-runnable: a repeat run would have skipped a value constraint. Never released. Made idempotent. | Low | Fixed before release |
The areas probed hardest and came back clean: cross-project data reads, key material in API responses, payment signature forgery and replay, pack fulfilment for amount tampering, prompt injection in both assistants, and privilege escalation through team and invitation flows.
5. Controls the tests verified
What held under this round:
- Database isolation: row-level security is enabled on all 22 tables, each with service-role-only policies, verified by enumeration rather than assumption.
- No browser database access: the dashboard has no client-side database connection at all. Every read passes through an authorized server route, which removes an entire class of misconfiguration rather than defending against it.
- Authorization fails closed: when a permission lookup itself fails, access is denied rather than granted, and the shared helpers are used in place of hand-rolled checks throughout.
- Key material: secret key hashes and per-project salts are stripped from every API response, and the project ingest key is withheld from teammates who are not the owner. Key rotation stays owner-only.
- Payment integrity: webhook signatures are constant-time compared inside a five-minute replay window and fail closed without a secret; pack pricing and quantities are resolved server-side from a catalogue and checked against the amount actually collected, never taken from the request.
- Prompt-injection discipline: every untrusted field reaching either assistant is sanitised and structurally fenced from instructions, with hard conversation-length limits enforced before any model call.
- Rate limiting: edge limits identify callers from a value the caller cannot set, and the single place that decides this is shared by every route that depends on it.
6. What was fixed
All seven findings were remediated within the assessment window:
- the payment webhook now retries on an ambiguous failure instead of acknowledging it;
- one shared cycle calculation replaces six separate copies, matching the database exactly, with tests asserting the agreement across every month-end;
- the corrected caller-identification logic carried across to the marketing site;
- suppression checks now refuse to send when they cannot be performed;
- the marketing site gained the full security header set the dashboard already carried, including framing and content-type protections;
- the build guard that keeps both SDK packages in step was extended to understand which modules are legitimately framework-specific, so it can no longer be satisfied by simply deleting a file.
Launch-week audit
Before launch, Cluebase went through a full security assessment of its own source code and running endpoints: every API route, the multi-tenant isolation boundary, the AI conversation endpoint, and the browser widget customers install.
1. What was audited
The assessment covered the application that receives, stores and shows error data, the part of the system where a flaw would matter most. Specifically:
- all 56 API routes, each individually traced for authentication and authorization;
- the multi-tenant isolation boundary between projects and teams, the single most important property of the product;
- the error ingestion endpoints and their origin restrictions;
- the AI rescue-conversation endpoint: token scoping, message handling, cost ceilings, prompt-injection resistance;
- the browser widget exactly as customers install it from npm, byte-for-byte from the shipped bundle;
- the billing and integration webhooks for forgery and replay resistance;
- account, team, role and invitation flows for takeover or privilege escalation.
2. How it was tested
Three layers, each catching what the others cannot:
2.1 Full source review
Every route’s authorization logic read line by line, not sampled. The codebase enforces access through shared helpers rather than copy-pasted checks, which means one review covers the pattern, and a failing-by-default guard script breaks the build if any new route ships without its authorization model classified. That guard passed 56 of 56 routes.
2.2 Live endpoint testing
Against a running instance: missing credentials, forged keys, fabricated incident tokens, wrong methods, cross-origin preflights, and direct attempts to read another project’s data without a session. Every probe was required to fail closed with a clean error, never a stack trace, never partial data.
2.3 Adversarial unit tests
Thirty-four tests run against the real implementations, not reimplementations: seventeen hostile cases against the origin allow-list (lookalike domains, encoding tricks, userinfo spoofing), ten forgery and replay attacks against payment webhook signatures, and collision properties of the error grouping logic. These tests stay in the build so the guarantees they check cannot silently regress.
3. Results at a glance
| Severity | Count | Meaning |
|---|---|---|
| Critical | 0 | cross-tenant data access or account takeover |
| High | 0 | privilege escalation, token abuse, or data exposure |
| Medium | 1 | a race condition allowing an org to be linked to two projects |
| Low | 4 | hardening opportunities and product-quality issues |
| Informational | 2 | documented design trade-offs |
The one medium finding was fixed during the assessment itself, with a database constraint making the vulnerable state impossible rather than merely unlikely. Everything else is low-severity by any practical scale, and each entry below states its status honestly, two remain open because they are quality issues, not exposures.
4. Findings
Every finding from the assessment, in full. None are omitted, including the embarrassing-to-explain ones.
| ID | Finding | Severity | Status |
|---|---|---|---|
| CB-LW-01 | Two simultaneous requests could link one organization to two projects, extending team access across both. Fixed with a unique database index plus graceful conflict handling. | Medium | Fixed |
| CB-LW-02 | Origin restrictions compare hostnames only, ignoring scheme and port (documented, deliberate granularity for widget serving). | Low | Accepted trade-off |
| CB-LW-03 | A deactivated project’s public key can validate for up to ~10 seconds from cached lookups before revocation takes full effect. | Low | Accepted trade-off, bounded |
| CB-LW-07 | Documentation said non-standard ports were permitted by origin restrictions; the implementation rejects them. Fails closed, confusing, not unsafe. | Low | Open (documentation fix) |
| CB-LW-08 | Some error-message formats fragment into separate groups instead of merging, creating duplicate dashboard entries and alerts. Quality issue, not a data issue. | Low | Open |
| CB-LW-04 | A workspace’s own support email can surface in agent conversations by design, since the field is public-facing contact info. | Informational | Documented |
| CB-LW-05/06 | Repository hygiene and CORS preflight details with no runtime impact. | Informational | Noted |
For comparison, the areas probed hardest and came back clean: cross-project data reads, incident-token forgery and reuse after closure, privilege escalation between roles, webhook signature forgery and replay, and cross-site scripting in the widget.
5. Controls the tests verified
The claims on the security page were put under load. These held:
- Project isolation: unauthenticated requests for another workspace’s incidents, errors and team roster were denied on every route probed; the shared authorization helper is used everywhere instead of hand-rolled checks.
- Incident tokens: 256-bit random, scoped to exactly one conversation, rejected once closed, with hard turn limits, pacing floors and concurrency caps enforced server-side before any model call.
- Widget safety: all eleven HTML-insertion points in the shipped bundle inspected, none passes untrusted text to an HTML sink; messages render as plain text nodes inside an isolated shadow root; conversation tokens never touch persistent storage.
- Webhook integrity: forged payloads, attacker-signed deliveries, stale replays and malformed signatures all rejected without exception, using constant-time comparison.
- Cost containment: conversation quotas, hourly ingest ceilings and alert budgets are enforced atomically in the database, so a leaked publishable key burns quota only up to the same ceilings an honest surge would hit.
- Prompt-injection discipline: untrusted content is structurally separated from instructions, extraction outputs are schema-validated, and the recovery agent has zero tools, it cannot send email, browse, or reach other incidents even if manipulated.
6. What was fixed
Fixes landed during the assessment window itself, not deferred to a backlog:
- database-level uniqueness on organization links, closing the race condition end-to-end (the one medium finding);
- an automated authorization regression suite added to the build, asserting thirteen deny paths on every run;
- the thirty-four adversarial unit tests wired in as a permanent gate;
- notification link-stripping, request-size caps and outbound timeouts from the earlier internal audit round confirmed present and re-verified in current code.
Ongoing assurance
One audit is a snapshot. The standing controls are what make it more than that: the failing-by-default route guard, the authorization regression suite, and the adversarial unit tests all run on every build, so the properties each audit verifies are re-checked continuously rather than annually. Findings that stay open appear above with honest statuses and will move to fixed there when they close.
Contact
Questions about any assessment, requests to see specific evidence under NDA, or a vulnerability you have found yourself: write to hello@cluebase.dev. Our disclosure rules are in section 10 of the security page.