tracecathq/tracecat/sublime-phishing-case-lifecycle
- community
Checking that the SKILL.md file is still in the repository.
Load when the prompt's first line is `Phishing message <canonical_id>`, followed by one Sublime message group as JSON. Takes one flagged or user-reported email from Sublime to a triaged case and a published Slack card. You read the group, pull its indicators with MQL, deduplicate it against existing cases, scope the campaign across the tenant, place each recipient in Google Workspace, look for interaction and account abuse in the audit log, score it, write the case and post the card. Also load…
Install
npx vskill@latest install tracecathq/tracecat/sublime-phishing-case-lifecycleSKILL.md
Sublime phishing case lifecycle
One Sublime message group, from the alert to a case a person can act on in under a minute.
A message group is the unit of work, not a message. Sublime groups the messages of one campaign, so a campaign that reached 40 mailboxes is one group, one case and one Slack card. Never open a case per recipient.
Which path you are on
| The first line of the prompt | The path | |
|---|---|---|
Phishing message <canonical_id> | Triage. Section 2. | |
Phishing group to investigate | Triage. Section 2. The workflow uses this first line for the same path. | |
Phishing resolution <canonical_id> | Record an analyst's resolution. Section 5. |
The prompt also carries, as JSON, the values the workflow derived. Use them exactly as given and never recompute them:
canonical_id— the Sublime message group canonical IDcase_tag— the dedupe tag, alwaysphish-<canonical_id>source_line— the line you put in the case description verbatimslack_channel— the only channel you post to on this runsublime_base_url— the API host for every Sublime call on this runcase_url_base— the base for a case link, with a trailing slash. Append the case ID after you create the case. Without it there is no case link and no working Open case button, so never leave the Case field as plain text when this value is present.sublime_console_urlandgoogle_admin_url— the targets for two of the three link buttons
Load email-evidence-core before your first read. It says which tools you may call and what each indicator proves. This skill says what order to do things in and what to produce.
Two constraints to set for your tenant
Both describe a tenant where the Autonomous Security Analyst is off and Sublime cannot quarantine. They shape every case you write. Change them before you publish the skill if your tenant differs.
- The Autonomous Security Analyst does not run here.
asa_verdictis always null. Never wait for it, never ask for its report, and never describe an analyst verdict in a case. Sublime's analysis reaches you as the flagged rules and the attack score verdict. - Sublime cannot contain anything here. No quarantine, no release, no warning banner. Containment happens in Google Workspace and a person decides it. Your job on every path is to make that person's decision easy, never to take it.
1. Before you read anything
Load email-evidence-core, business-context and hypothesis-driven-triage.
The triage method is the one in hypothesis-driven-triage: state what you would expect to see if the message were a real attack, state what you would expect if it were benign, then read for the difference. The hypotheses for this family are:
- A real attack that reached a person. The message was delivered, it has a credential-harvesting URL or a macro-enabled attachment, and the recipient's account did something new afterwards.
- A real attack that was stopped. The recipient reported it without acting, or the message was never delivered.
- A broad campaign. The same URL or attachment hash reached several mailboxes, and at least one of them is privileged.
- A legitimate message that failed a check. Authentication failed because of forwarding or a configuration fault, and nothing else is wrong.
- A known pattern.
business-contextalready describes this sender, this vendor or this notification as expected.
Hypothesis 5 is checked against the business context, never assumed. Hypothesis 4 is the most common and the easiest to get wrong in the alarming direction.
2. Triage
Do these in order. Do not write anything for a reader until step 7.
2.1 Read the group, then pull its indicators
Call get_message_group with canonical_id, even when the prompt already holds the group. The prompt is a snapshot and the record may have moved.
Note, from the record:
- Sender address, sender display name, sender domain
- Subject, delivery time, message count
- Every recipient mailbox, and each message's Sublime message ID
- Delivery state, and
message_links_clicked - Flagged rules, each with its severity
- The attack score verdict
review_status, which tells you whether a verdict has already been pushed to Sublime- Whether anybody reported it, and who
Then take one message ID from the group and call analyze_message_by_id once, asking for every field you need in a single queries list. email-evidence-core section 2.1.1 gives the query set and what each one returns. Always include `headers.message_id`: it is the only exact handle on this mail in Google Workspace, a person needs it to quarantine, and it must reach the case.
Call get_rule only when a flagged rule's name does not tell you what it detects.
Always establish the sender domain's age. Call tools.virustotal.lookup_domain on the registered domain and read the creation date, on every case, including one with no links. A domain registered days or hours before the message is among the strongest signals phishing offers, it costs one call, and it is the fact a reader acts on. When the lookup returns nothing usable, say so in the indicator table rather than leaving the row blank.
2.2 Deduplicate, and verify the tag
Search cases for case_tag.
A non-empty result is not a match. core.cases.search_cases silently drops a tag filter whose ref does not resolve to a tag that already exists, and then returns the newest case in the workspace instead. A new phishing message has no phish-<canonical_id> tag yet, so this is the normal case, and the result arrives looking like a clean hit.
Therefore, for every case the search returns:
- Read that case's own tag list.
- Confirm
case_tagis in it. - Treat only a confirmed tag as a match.
If no returned case carries the tag, the group is new. Go to 2.3.
If a case carries the tag:
- If it is open, add one comment saying what is new since the case was last written: new recipients, a higher message count, a new flagged rule, a change in delivery state. Then stop. Do not post a new Slack card, and do not rewrite the case description.
- If a person has already decided it, resolved it or closed it, add one comment recording that the group was seen again, and stop. Never reopen it and never remove a tag.
- If nothing has changed at all, add no comment. Say so in your closing line.
This step is the only thing that stops a repeated poll from duplicating work, so never skip it, and never skip the tag readback.
Then search the sender domain and each attachment SHA256 across cases from the last 7 days. A hit here is a related case, not the same case. Note it as context and keep going.
2.3 Scope the campaign, then hunt the technique
This step has two halves. The first finds the campaign Sublime already flagged. The second finds the part it did not. Do both on a malicious verdict.
2.3.1 The flagged campaign
Sublime can see the whole tenant, so this is where the first answer comes from. Search message groups from the last 7 days by, in order:
- Attachment SHA256, when the group has one. This is the strongest link.
- Each URL, or its registered domain.
- Sender email, then sender domain.
- The flagged rule ID.
Use search_message_groups or list_message_groups with the matching filter. Do not search on the subject; a subject is trivial for an attacker to change and it produces false links.
Record:
- How many distinct mailboxes received the campaign
- How many messages in total
- Which indicator links them, named exactly
- Whether the newest message is recent enough that the campaign is still arriving
- How many were delivered
Then stop and read the limit of what you just did. Every one of those searches reads flagged groups. An attacker who changed the sender, the link or the subject is not in that result, and the count you recorded is therefore a floor.
2.3.2 The technique hunt
When the prompt says a later step runs the hunt, do not start one here. The workflow's investigate step says this. On that run, skip the rest of this subsection, write not run in the Hunt field, and say the result will arrive in the thread. On any other run, including a person asking in chat, run the hunt below.
Run a hunt job. email-evidence-core section 2.4 holds the full contract: the three tools, the base_url every call needs, the rule that you hunt the technique and not the indicator, the validate_rule pre-check, the three-call polling limit, and what a match does and does not prove.
Two rules belong to this path specifically:
- A malicious verdict without a hunt is an incomplete triage. The hunt is not optional and it is not a nice extra.
- The hunt runs over 90 days and reads every message, flagged or not. Therefore a group it returns with
flagged_rules: nullis mail that matches the attacker's method and that Sublime took no action on. That is the most valuable sentence you will write in the case. Name the mailbox, the subject and the sender, and say that no rule fired.
Carry forward from the hunt: the technique in one sentence, the window, the matched group count, how many were already flagged, how many were not, and the interaction evidence on each unflagged match.
2.4 Place each recipient
For each distinct recipient, call tools.google_directory.get_user. Record the admin role, the 2-Step Verification state, the org unit and whether the account is suspended.
If there are more than ten distinct recipients, read every recipient that holds an admin role first, then a sample of the rest, and say in the case how many you read and how many you did not.
An address Directory does not know is a finding. Report it; do not drop it.
2.5 Look for interaction and account abuse
For each recipient, call tools.google_reports.list_activities from the delivery time to now. Read login, token, drive, admin and user_accounts.
Look for:
- A sign-in from an address or location the account has not used before
- Failed sign-in attempts clustered after delivery
- A new OAuth grant
- A sudden wide share in Drive
- A change to recovery details, to 2-Step Verification or to a password
Check every candidate finding against business-context before you call it abnormal. A pattern the context already describes is not evidence of compromise.
Sublime's message_links_clicked is the one positive click signal you have. When it is non-empty, say which recipient clicked and when; that is a fact, not an inference. When it is empty, the finding is "no interaction evidence is available", not "the user did not click". This path assumes no proxy logs, no DNS logs and no endpoint platform. If you have one of those sources, name it and use it.
2.6 Score it
You set two fields on the case and they are not the same thing. Severity is how bad the mail is. Priority is how soon a person must act on it. Set both, every time. A case created with severity but no priority shows unknown in the first column a reviewer reads, which says nothing to the person deciding what to pick up next.
Priority follows one rule, and it is about reach and exposure rather than the attack itself:
| Priority | When | |
|---|---|---|
critical | The message is still in a mailbox and a recipient holds an admin role, or any recipient clicked, replied or forwarded. | |
high | The message is still in a mailbox and the verdict is malicious. This is the normal case under these constraints, because nothing removes mail automatically. | |
medium | The verdict is malicious but no copy remains in any mailbox, or the verdict is spam with a delivered copy. | |
low | Graymail, or a simulation. |
Do not reason past the table. Severity and priority often match, and when they differ it is usually because an admin mailbox is involved, which raises priority without changing how dangerous the mail itself is.
Severity
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingexamples/003-sublime-phishing-triage/skills/sublime-phishing-case-lifecycle/SKILL.md
Popularity
- Repository stars
- 3,853
- Repository forks
- 436
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/tracecathq/tracecat/sublime-phishing-case-lifecycle)