The first line to ship, what the result has to carry, where the card can live, how it learns the case has moved on, and where the analyst’s decisions go. Written for whoever maintains the integration.
Before any widget, one string.
When the analysis action succeeds, it writes one line, which the Case Wall shows: “Successfully returned Blue Agent analysis for threat … in Wiz.” That line is the integration’s own, and it reaches every tenant, with a widget or without one. It could say the verdict instead:
That is rule 7 of the checklist, degrade to text, and the first half of step 1. It needs no admin and nothing new from the agent except the data cut-off; without one, the line stops at the time the agent ran. What a line of text can’t carry is the age, which grows while the line stands still. The age is the widget’s job.
The card reads the result of Get Blue Agent Analysis exactly as it arrives today, and says more as the result carries more. Every field below is optional, and each one reaches the analyst as a sentence.
| Field | Added by | What the analyst reads |
|---|---|---|
aiAnalysis.dataCutoffAt | The agent | “using data to 13:14 UTC” |
aiAnalysis.sourcesRead, sourcesNotRead | The agent | “Read: Wiz Defend cloud telemetry, Cloud audit log. Not read: Network flow logs.” |
aiAnalysis.claims | The agent | Each claim, and where to check it: “In this case · alert A2”, or “Only in Wiz” |
aiAnalysis.missingEvidence | The agent | When present: “No recommendation.”, and the gap in the agent’s words. Low confidence alone does the same |
aiAnalysis.url | The agent | A link to the analysis in Wiz, in a new tab, https only |
aiAnalysis.revisedFrom | The integration, which keeps the verdict it replaces and the analyst’s decision | “Revised. It said Benign as of 13:16 UTC; you overrode it to Malicious at 14:04 UTC.”, and the earlier conclusion |
caseContext.coveredAlerts | The action | “About alert A1 in this case.” |
caseContext.casePriority | The action | Both ratings, each with its owner, and whether they differ |
caseContext.fetchedAt | The action | “Added to this case 13:18 UTC” |
caseContext.alertsAfterCutoff, checkedAt | The check in section 04 | “Outdated. Alert A3 happened at 13:57 UTC, 43 minutes after the data this verdict used. The agent hasn’t seen it. Checked 13:58 UTC.” |
Without the check, the card doesn’t guess: it says “Can’t tell whether the case has moved on: nothing checked it.” And an alert counts as newer when its events came after the cut-off, the same clock the cut-off is on, not when it joined the case.
The admin decides what goes on screen, so the card has three possible homes, and the integration controls only the last.
Google’s revamped case view adds one step: its new default views don’t include custom widgets from the legacy views on their own (Google’s docs), so an admin adds them back. Quick Actions work in both.
Drawing Outdated is easy. Knowing when to say it is the work.
The card reads the result of the step that ran for alert A1. Playbooks are attached to alerts, so when alert A3 joins the case, A1’s result stays as it was unless someone reruns A1’s playbook. Nothing in that result can know about A3. Two routes fit what the integration already has.
The job’s lookup of the other cases Wiz links to a threat is also the start of the check this study didn’t design: evidence that lands in another case, where a card inside one case can’t see it.
An HTML widget displays. Its one documented exception, an approval link, only approves or declines a playbook step that is waiting. So every decision is one of the console’s own action types.
Each of these decides how the card is installed, and none can be checked without a tenant. They are printed here rather than guessed.
The card is one HTML file and its definition, in the content hub’s own format, open source under Apache-2.0. To ship it, replace the two widget files in the Wiz integration’s folder; the action, scope, height and default width stay the same. Reusing it for another agent means changing its two names, the action it is bound to, and where it finds the analysis in the result.
The harness runs Google’s widget and the card side by side, the way the console runs a widget: the result substituted into the placeholder, a sandboxed frame of the widget’s height, and the host’s theme message. Every example state has its own link.
The tests cover every result shape Google’s widget reads, the age arithmetic (including the 49 days on Wiz’s launch screenshot), the outdated rule with “not checked” kept apart from “fresh”, low confidence, revisions with the analyst’s decision, escaping and https-only links, and that the card draws no control that could change the case. A separate script checks the widget against the method’s gates, G2 and G3, and runs the study’s earlier checks on Option 0, which fails most of them.