Copy page
Privacy and credentials
Review collection and filtering in Bicho SDKs, the Astro integration, and Sentry clients, plus credentials, storage, source maps, and agent access.
This guide covers error data sent to a self-hosted Bicho instance, whether it comes from a Bicho SDK, an existing Sentry SDK, or an OpenTelemetry logs exporter. For this documentation website’s analytics, preferences, and hosting, read the separate website privacy notice.
Error reports can contain private information in messages, stacks, paths, breadcrumbs, and custom context. Choose what to capture before sending it. Bicho filters recognized credentials, but that does not make arbitrary application data safe to store or share with an agent.
Credential boundaries
Project registration returns OTLP configuration and a Sentry DSN. Use the configuration for your chosen integration, not example credentials.
| Credential | Where it belongs | What it authorizes |
|---|---|---|
| Public ingest key | Browser, desktop, or backend SDK/exporter configuration. Sent as X-Bicho-Key over OTLP or embedded in the Sentry DSN. |
Selects a project and permits ingestion, subject to any required ingest secret. It grants no reads or administration. |
Optional ingest secret, X-Bicho-Secret |
Trusted backend configuration only. Never a browser bundle or distributed desktop application. | Required alongside the public key for a secret-enabled project. It grants ingestion only. |
Admin bearer token, BICHO_ADMIN_TOKEN |
Cloudflare Worker secret and trusted API/MCP clients. Never SDK capture configuration. | Reads across projects, project creation, issue-status changes, source-map uploads, and investigation MCP access. |
A public ingest key is expected to be visible in client applications. It is not a password, read credential, or abuse-protection mechanism. A distributed Tauri application cannot keep an embedded ingest secret confidential any more than a browser application can.
The Bicho JavaScript SDK supports public-key-only projects, including in Node.js. The PHP, Rust, and Python SDKs can also supply an ingest secret for trusted backend services. Sentry SDKs need the generated sentry.headers through a transport that supports custom headers when a project requires a secret; a DSN alone cannot bypass that requirement.
Save generated credentials securely. Project listings omit them, and the server stores only a hash of an ingest secret. D1 stores the public ingest key, not the admin token. Admin comparisons use constant-time digest comparison; an absent or empty admin token makes admin routes fail closed with HTTP 503.
SDKs
Collection depends on the client and its configuration. The Bicho SDKs use OTLP/HTTP JSON; Sentry SDKs use a separate ingestion format. Changing the destination does not make their collection behavior identical. See SDKs and integrations for setup and delivery limits.
JavaScript and Node.js
The Bicho JavaScript SDK installs browser listeners for uncaught errors and unhandled promise rejections after initialization. Node.js reporting is explicit. Caught exceptions and custom messages require capture calls; console.error(), failed HTTP requests, and resource failures without JavaScript error data are not automatic captures.
It does not automatically collect cookies, browser storage, page URLs, DOM content, user identity, console output, or network activity. It does not record sessions, breadcrumbs, replay, page views, Web Vitals, or traces. Application-supplied messages, stacks, tags, and contexts can still contain those details.
The SDK filters common sensitive keys in tags and contexts and strips credentials, query strings, and fragments from HTTP(S) URLs in captured strings. Use a synchronous beforeSend hook for application-specific filtering or return null to drop an event. The SDK filters the final event after the hook.
Set autoCapture: false for explicit capture only, or delay initialization if your application needs a consent decision first. These options do not decide your legal obligations. Browser transport omits cookies and referrers; it does not hide the network connection from the collector or hosting platform.
Events are queued in memory with size, age, and retry limits. A capture UID means queued, not delivered. Follow the delivery guidance for flush and close behavior.
PHP
The PHP SDK reports exceptions and messages your application explicitly captures. It does not install global exception, error, or shutdown handlers or framework and WordPress hooks.
Exception capture includes the native class, message, failure and trace locations, and up to eight previous exception messages. Stack frames omit function arguments and object values. Requests, headers, cookies, sessions, user identities, and environment variables are not collected automatically.
Tags and contexts are bounded and filtered for credential-like keys and common credential strings. Arbitrary objects in context become class labels without invoking custom serialization. Messages, paths, and explicit stack text can still contain sensitive information.
Delivery is synchronous. Each call waits for acknowledgment or failure; there is no background queue or flush method. Handle delivery failures separately from the application’s original exception.
Rust
The Rust SDK explicitly captures errors, messages, and event fields supplied by your application. It does not install panic hooks or automatically collect logs, console output, network requests, tracing spans, panic data, or user identity.
Error capture records the Rust type name, display message, and up to eight source messages. Rust errors do not generally carry a backtrace; the SDK does not invent one. If you attach stack text captured at the failure site, review it as part of the event.
Tags and contexts are bounded and filtered for credential-like keys and common credential strings. That filtering does not guarantee private information is absent from messages, source text, or custom fields. The same limits apply when using the SDK on the Rust side of a Tauri application; webview reporting uses its own JavaScript configuration.
Delivery must be awaited on a Tokio runtime. There is no background queue or flush method. An application can exit before a separately spawned reporting task completes.
Python
The Python SDK reports exceptions and messages your application explicitly captures. It installs no global exception hooks, logging handlers, framework integrations, or shutdown handlers. It does not automatically collect requests, headers, cookies, sessions, user identities, or environment variables.
Exception capture records the native type, bounded message, up to 32 traceback locations, and up to eight cause/context messages. It does not read frame locals, source lines, or function arguments. Converting an exception message can execute the exception’s custom __str__ method.
Context normalization accepts only exact built-in dictionaries, lists, tuples, and scalar types. Other objects become [Unsupported object] without invoking their string, representation, iteration, or serialization methods. Tags and contexts are bounded and filtered for credential-like keys and common credential strings. Filtering is best effort, not a guarantee that personal information or secrets are absent from messages, filenames, explicit stack text, or custom fields.
Delivery is synchronous and blocks the calling thread until acknowledgment or failure. There is no background delivery queue or flush method. In async applications, the caller can use asyncio.to_thread() to avoid blocking the event loop; this does not make the SDK asynchronous, and cancelling the await does not cancel delivery already running in that thread. Keep optional ingest secrets in trusted server configuration only, and handle delivery failures separately from the original exception.
Astro
The Astro integration initializes the JavaScript SDK only for explicitly enabled browser/server modes. Browser options are bundled into public client code. Server options stay in server modules; both transports use public ingest keys and cannot authenticate secret-enabled projects.
Server middleware reports the original exception escaping a request handler, with a fresh client and bounded delivery. It does not collect the request URL, headers, cookies, or body. Error messages and stacks can still contain application data. Prerenders, explicit HTTP error responses, and failures after streaming starts are not automatically reported. It installs no process handlers.
For consent-controlled browser initialization or custom SDK filtering hooks, omit the integration’s browser mode and initialize the JavaScript SDK in your own client entry. Do not enable duplicate browser clients or overlapping server error boundaries.
Sentry SDKs
An existing Sentry SDK may capture breadcrumbs, request details, user data, and other context depending on its integrations and settings. Replacing the DSN does not change those capture defaults. Review the SDK’s collection settings and filtering hooks before sending events to Bicho; the Bicho JavaScript SDK’s exclusions and options do not apply to it.
Bicho stores supported error and message events after core credential filtering. Unsupported envelope items, including sessions, replay, profiling, transactions, and attachments, are discarded without storing their payloads. They still reach the ingestion endpoint, so disable unnecessary integrations at the client rather than relying on server-side discard.
OpenTelemetry exporters and logging bridges
An exporter sends the records your application or instrumentation emits. Configuring an endpoint does not install exception capture or restrict which fields a logging bridge includes. Review resource attributes, scope attributes, structured bodies, exception text, and custom log attributes before enabling export.
Service names, versions, environments, stack filenames, tags, and correlation IDs become captured evidence. Some scalar resource and log attributes also become searchable D1 tags. Correlation IDs can link an error to data outside Bicho even though Bicho does not ingest traces.
Prefer route templates and operation names over complete requests. Avoid raw headers, bodies, query strings, user records, access tokens, and customer-provided text unless you have a specific reason and suitable filtering. See the OTLP guide for accepted records and transport limits.
Event filtering before persistence
Both OTLP and Sentry ingestion pass through core credential filtering before indexed event fields and captured evidence are stored. Filtering covers nested event data and captured strings. OTLP filtering also covers resources, instrumentation scopes, log attributes, structured bodies, and nested AnyValues. Sensitive typed attribute values become the string [Filtered], including values originally supplied as arrays.
Recognized patterns include:
- Credential keys such as authorization, cookies, passwords, secrets, token names, API keys, access keys, and private keys, including common hyphen/underscore forms.
- Sensitive OTLP HTTP header attributes such as
http.request.header.authorization,http.request.header.cookie,http.response.header.set-cookie, andhttp.request.header.x-api-key. - Basic/Bearer credential strings and HTTP(S) URL user information.
- Credential-named query parameters, including percent-encoded names and a sensitive first parameter in a bare query string.
Core filtering is narrower than the Bicho SDKs’ removal of HTTP(S) query strings and fragments. It retains safe metadata rather than removing every header or query value. Neither client nor server filtering reliably removes arbitrary personal information, unknown secret formats, or sensitive text embedded in prose, stacks, labels, and source code. A harmless-looking key can still hold a password or customer record.
Filtering happens at ingestion. Updating its rules does not rewrite historical append-only evidence. For OTLP, occurrence identity uses the original bounded log.record.uid before its stored representation is redacted, so credential-like UIDs do not collapse distinct occurrences. Do not put credentials or personal data in occurrence UIDs or event IDs.
Bicho retains sanitized event evidence as well as derived indexed fields. A field absent from search results can still appear in a full event read. API/MCP projections can truncate output; truncation is not deletion or a privacy boundary.
Source maps have a separate boundary
Uploaded source-map JSON is structurally validated and normalized, then stored without credential filtering. Embedded sourcesContent can contain complete source files, comments, configuration, and secrets. Review maps before uploading them. Omitting sourcesContent avoids uploading those source bodies but leaves source context explicitly missing.
Derived source context is bounded and passed through credential-string filtering. That does not sanitize the original map in R2 or reliably remove secrets written as source code. Source names and URLs are labels only; the Worker never fetches remote maps or source files. See source maps for supported formats and upload access.
CORS is not authentication
OTLP and Sentry ingest endpoints permit cross-origin requests and preflight from any origin while still checking project ingest credentials and any required secret. API CORS uses CORS_ORIGINS. MCP permits absent Origin headers and same-origin requests, and rejects opaque or unexpected browser origins unless allowed by configuration.
CORS controls browser access; it does not prevent non-browser requests or make exposed credentials safe. Prefer explicit trusted admin origins over * and keep any custom dashboard’s admin token on its server. Use edge rate limits and WAF rules for request abuse without interactive challenges that SDKs, exporters, or MCP clients cannot complete.
The collector, Cloudflare, and any configured proxy still receive connection information and HTTP headers. Omitting an IP address or header from a stored event does not hide the connection itself. Core failure logs use request IDs and error names rather than raw event bodies or credentials; review additional platform logging separately.
Storage ownership and agent access
D1 and R2 belong to the Cloudflare account running your instance. Keep R2 private and protect account access, backups, and deployment credentials separately from ingest keys. The core serves evidence through authenticated APIs, not public bucket URLs. Gzip compression is not encryption or access control.
Events are append-only, with no automatic retention deletion or event/issue DELETE endpoints. Changing an issue’s status does not erase its evidence, and new occurrences do not automatically reopen hidden issues. Storage growth, backups, and recovery remain your responsibility. See operations.
The core uses one shared admin credential, not individual accounts or project-scoped admin tokens. Project-scoped lookups keep resource IDs within the requested project, but the same token can access other projects. There are no scoped read-only tokens or OAuth login. Issue-history actor admin identifies the shared credential, not a named person.
Your instance’s MCP exposes project creation and issue-status updates as well as investigation reads. Connecting an agent with the admin token is not read-only access; tool annotations do not reduce the token’s authority. The public documentation MCP on this website is separate and cannot access your instance.
A connected agent may send retrieved evidence to its LLM provider. Review that provider and your client’s data handling before granting access. Treat captured messages, stacks, tags, and source context as untrusted evidence, never as permission to execute code, change state, or disclose credentials. Provenance and truncation flags describe scope and completeness, not trustworthiness.