Diagnostics bundle
Download diagnostics on the Integration Health card (Stores › Configuration › Conviro › AI Chat) downloads one JSON file, conviro-diagnostics-<UTC time>.json, to attach to a Conviro support ticket. It answers "why does the integration misbehave?" without SSH access and without handing over anything sensitive. Plan §14. Code: AiChat/Service/Diagnostics/DiagnosticsBundle.php, Redactor.php, AiChat/Controller/Adminhtml/Diagnostics/Download.php.
Access: admin session with Conviro_AiChat::config; served as an attachment with no-store caching (measured: not served without an admin session).
What is in it
bundleVersion: 1, generatedAt, then:
| Key | Contents |
|---|---|
module | Module name, installed / setup / schema / data versions, enabled, version status and latest version from Conviro. |
platform | Magento version and edition, deploy mode, PHP version and SAPI, cURL version. |
health | The Integration Health verdict and every row (state, summary, remediation). |
connection | API URL, whether an API key / webhook secret is configured (booleans), signature enforcement, tenant id, chatbot id, auth mode, OAuth error text, store URL. |
conviro | Conviro's last answer to tenant-info: measured / ok, HTTP status, error, when, latency, and an allow-listed copy of the answer. |
integration | The "Conviro AI Chat" integration: exists, active, granted ACL resources, missing resources, the permissions in plain words. |
cron | Recent runs of every Conviro cron job in etc/crontab.xml — nine in 1.5.0: conviro_deliver_events, conviro_catalog_resync, conviro_sync_jobs, conviro_connection_maintenance, conviro_purge_outbox, conviro_purge_webhook_log, conviro_purge_sync_jobs, conviro_purge_inbound_events, conviro_purge_identity_bindings (1.5.0). (Corrected 2026-09-27: this row said "six" and listed six; a unit test keeps the bundle's list equal to crontab.xml.) |
outbox | Queue health (pending, retrying, blocked, dead, sent in 24 h, last delivery, last error), counts per event type and status, per last HTTP status, and 2xx / 4xx / 5xx / no-response categories. |
inboundWebhooks | Counts of webhooks Conviro sent the store, by HTTP status. |
sync | Last delivery per kind (product, order, …), the catalog re-sync job, every sync job (counts, times, last error — no item data). |
storeViews / websites | Id, code, name, active, default, website, locale, base and display currency, base URLs, whether the widget is enabled; sync toggles per website. |
capabilities | The AI capability toggles and trust policy as sent to Conviro. |
setup | Wizard facts: app URL, store-view selection (mode, ids, saved at), initial sync plan, cart / payment confirmation state, connection state, a queued disconnect (since, attempts, last error — not its key), OAuth migration status. |
identity | 1.5.0 (unreleased) — signed customer identity, states and counts only: per website whether identity, My orders and guest verification are on and the order scope; signing — switched on anywhere, the key registration state (registered, not_registered, refused, …), the first 8 characters of the key id (public), the previous key id's first 8, registered / rotated / created times, age in days, rotation due, a closed-set class of the last registration error (auth, server, network, …), whether an installation id exists (not the id); clock — this server's clock against Conviro's in seconds and when it was read (from the Date header of Conviro's answers; null without a reading in 24 hours); the order-listing permission state (myOrdersAcl); verified-identity bindings created in the last 24 hours, revoked in the last 24 hours per reason (customer_logout, customer_deleted, account_switched, password_changed, other), live and stored rows; the last successful run of the binding purge. |
What is never in it
Collected from allow-listed aggregates only. Not collected: the Conviro API key, the webhook secret, OAuth consumer or token values, customer names, e-mails or phones, order or cart contents, event payloads, event subjects (order numbers, customer ids), cron messages. 1.5.0: not the identity signing key in any form (no class that builds the bundle reads its configuration path — a unit test fails if one does), not the full key id, the public key, the installation or integration id, a binding id, a session hash or a customer id; the binding figures are COUNT(*) queries, so no row is ever read.
Redaction
After the bundle is built, Redactor walks it:
- values under field names that look like credentials are replaced by
[redacted]: the name is split into words (accessTokenSecret,oauth_consumer_key,X-API-Key) and any wordkey,auth,authorization,bearer,hmac,secret,token,password,passwd,signature,credential(s),cookie,otpmarks it; phone fields (phone,telephone,mobile,fax) become[phone]. Booleans such asapiKeyConfiguredsurvive, and so doauthMode(oauth1/bearer) and health-row ids (key: "connection"); - every known secret value (API key, webhook secret, the integration's OAuth values; values shorter than 6 characters are ignored) is replaced anywhere it appears, in any letter case — 1.5.0: also the identity signing key in every spelling a leak could take (its stored encrypted value, and the secret key and its 32-byte seed in base64, unpadded base64, base64url and hex), handed to the redactor by the key store so that a field added carelessly later is still masked;
- in every string (and every array key): Conviro API keys
cvr_live_…/cvr_test_…(also truncated),Bearer <token>, credential query parameters (access_token=,token=,code=,api_key=,oauth_*=…),secret=…/password: "…"pairs and"apiKey":"…"inside embedded JSON, and an opaque value right afterkey/token/secret(consumer key abcdef01…); - every e-mail address is replaced by
[email]— ASCII or not (jöhn@exämple.de), with a quoted local part, URL-encoded (%40), JSON-escaped (\u0040) or writtenjohn(at)example.com; - phone numbers (
+31 6 1234 5678,06-12345678) are replaced by[phone]; dates, times, versions, counts and zero-padded order numbers are not. (Security review R3 M7, 1.4.0.)
The bundle reports redactions, the number of values masked — 0 on a correct build; anything higher means something slipped into a free-text field (for example an error message quoting an e-mail) and was caught.
Measured (diagnostics.sh 19/19, local stack): with an API key, webhook secret, OAuth credentials, a customer, a guest order and a PII-carrying event in the database, none of 6 secret values and none of 30 PII values appeared in the served bundle or before redaction, no e-mail at all, redactions 0; a planted error text containing an e-mail and the API key was masked (redactions 4).
1.5.0 (2026-09-27, threat T19): unit-tested only — with the Phase 1 test vector's key seeded, none of its 8 spellings, the full key id, the public key, the installation / integration id, a binding id, a session hash or a customer id is in the identity section; the section passes the redactor unchanged (redactions 0); every spelling planted in a field is masked (Test/Unit/Service/Diagnostics/DiagnosticsIdentityTest). diagnostics.sh now switches identity on, creates the key and repeats every leak check with its spellings plus a planted error text holding the key's hex — passed on Magento 2.4.7-p4 (2026-09-27, 32 checks, 0 failures).