Email gets filtered. Teams usually does not — and it is where people now paste the links they were told to click. This watches every link shared in chats and channels, checks each one against two independent threat feeds, reads the message around it for phishing language, and shows when the same bad link is spreading across several people. It is in production, monitoring a live Microsoft 365 workspace every day.
Your email is filtered. Your chat is not.
Twenty years of investment went into email security, and it worked — the obvious phishing message mostly does not reach an inbox any more. So the message moved.A link arriving in a Teams chat from a colleague's compromised account carries the one thing an email never had: it looks like it came from someone you already trust, in a window you already had open.
Microsoft's own protection does block known-bad URLs in Teams, and it should be the first thing you turn on. But blocking answers exactly one question — was this specific link on a list? — and a security team has several others. Who received it. Whether it went to one person or nine. What was said around it. Whether the domain was registered last week. What was done about it, and by whom.
Those answers exist; they are just scattered across conversations nobody can query. That is the gap this closes: not another blocker, but the layer that lets a person understand and evidence what is actually landing in the workspace.
“Is this URL on a known-bad list?” — instantly, automatically, and it should stay switched on.
“Who else got this?” “Is it spreading?” “How old is that domain?” “What did the message actually say?” “What did we do about it, and can I show someone?”
Every one of those spans conversations rather than sitting inside one link — and nothing in the box spans conversations. Closing that is the whole product.
A link in chat is trusted more than a link in email.
That is not a failure of training. It is what a chat window is for: fast, informal, between people who already know each other. Which is precisely why an attacker who gets one account prefers it.
Nobody is reading the links
Hundreds a week across channels and DMs. Nobody has ever looked at them as a set, so nobody knows what normal looks like.
One report, no picture
Someone flags a suspicious message. Whether four other people got the same one is a question nobody can answer without asking around.
Attempts with no link at all
The message asking finance to confirm a changed payment account contains no URL, so nothing that scans URLs will ever see it.
Nothing to show a reviewer
"We investigated and blocked it" is a sentence. An audit log with times, actions and the analyst's own note is evidence.
Six screens, and what each one is for.
Every number, name and URL below is invented. The product carries a “DEMO · sample data” badge whenever it is running on sample data, and it is left visible here for the same reason it exists in the product: so nobody has to wonder whether they are looking at a real company's traffic.
Four malicious links this week, up from one last week — three of them the same shortened URL shared by four different people, now grouped as a campaign. Suspicious volume is flat. Two newly-registered domains appeared for the first time.
- Malicious4
- Suspicious5
- Clean11
- Unknown4
The week, in one screen
Counts across the top, the verdict split beside a fourteen-day trend, and an AI-written paragraph narrating what actually changed since last week — generated on a local model from the same numbers shown on the page, not from a template.
- R. Okonkwo
- P. Lindqvist
- S. Adeyemi
- M. Duarte
One bad link, four people
A single malicious URL is an incident. The same one arriving in four different conversations is a campaign, and it is the difference between closing a ticket and warning the company. It surfaces automatically on a rolling window rather than waiting for someone to notice the pattern.
…urgent, please verify your payment details before 5pm or access will be suspended…
…the supplier changed their payment account, can you confirm this is expected?
…invoice attached, payment due within 7 days as usual…
Search what was said, not just the link
The search index covers message text, sender and channel — so a phishing attempt containing no link at all is still findable. Results show a snippet centred on the actual match rather than the opening words of the message.
| github.com | Developer Tools | Clean |
| Local IPs (10.0.0.0/24) | Internal | Internal |
| dropbox.com | File Sharing | Clean |
| secure-payment-verify.top | Uncategorised | Malicious |
Every domain, categorised
Fourteen content categories across every domain seen. Well-known domains resolve instantly from a curated list; anything unrecognised is classified by the local model. Internal traffic groups under a synthetic entry with its own subnet breakdown.
| 09:14 | analyst@… | Escalated | URL 8f2a… — campaign confirmed |
| 09:02 | analyst@… | Note added | URL 8f2a… — blocked at gateway |
| 08:47 | analyst@… | Signed in | session opened |
| 17:31 | admin@… | Marked false positive | URL 41c7… — internal tool |
| 17:28 | admin@… | Assigned | URL 41c7… → analyst |
Who did what, and when
Every login and every case-management action is recorded — the part that turns a useful dashboard into something a compliance review can accept. Multi-tenant queries are filtered structurally rather than by convention, so one organisation's rows cannot appear in another's view even if a route forgets to ask.
Out of the dashboard, into your tooling
CEF for SIEM ingestion, as both a bulk pull and a tailable real-time log. CSV and a colour-coded Excel workbook for people who live in spreadsheets. And a NotebookLM-ready brief that turns the current filtered view into one dense document with the conversational context around each link.
These are drawn reconstructions of the interface rather than screenshots. The real deployment watches a live corporate workspace, and no part of it — no name, no domain, no message, no link — appears on this site or in the repository behind it. A public demo seeded entirely with fiction is being prepared; it will be linked from this page when it is up.
It started as a link scanner. It did not stay one.
Detection first, then everything a person needs in order to act on what was detected and prove afterwards that they did.
Two independent threat feeds, cross-checked
Every URL is looked up in VirusTotal and URLhaus separately, and the two answers are shown side by side rather than merged into one confident verdict. Two sources disagreeing is information, and collapsing it into a single score throws that away.
Domain age as a signal in its own right
A WHOIS lookup on every domain seen. A link to a domain registered four days ago is worth a second look even when no feed has caught up with it yet — newly-registered domains are one of the strongest phishing signals available, and the one that fires earliest.
Shorteners resolved before they are judged
A bit.ly link is not a destination, it is a redirect to one. Shortened URLs are followed to where they actually land, and the destination is what gets scanned — so hiding behind a shortener stops working.
Phishing language, not just phishing links
Message text is scored for urgency, credential-harvest phrasing and impersonation patterns. This is the part that catches the attempt with no link in it at all — the message asking someone to confirm a payment account, which no URL scanner would ever see.
Campaign detection
One bad link is an incident. The same one arriving in several people's conversations inside a rolling window is a campaign, and that is the difference between closing a ticket and warning the company. It surfaces on its own rather than waiting for somebody to notice the pattern by eye.
Case management on every URL
New, reviewed, false positive or escalated; assigned to a person; with a running note log underneath. Without this a dashboard is a list of things nobody has agreed to own, which is how findings quietly go stale.
Sender and domain profiles
Every link one person has ever shared, on one page — and the same for every domain, including a synthetic grouping for internal traffic with its own subnet breakdown, so private addresses do not clutter the external picture.
Domain categorisation across fourteen categories
Developer tools, collaboration, file sharing, social media and ten more. Well-known domains resolve instantly from a curated list; anything unrecognised is classified by the local model. It turns "what is being shared here?" from a scroll into a chart.
Message-content search
The index covers message text, sender and channel, not just the URL string — and results show a snippet centred on the actual match rather than the opening words of the message, which is the difference between a search result and a search result you can read.
Audit log over every action
Every sign-in and every case-management action, with who, what and when. This is the part that lets a dashboard be used as evidence rather than just as a view.
Alerting that can be tuned down without being turned off
Email, generic webhook and Slack, each toggled independently — so a channel that has become noisy can be muted without losing the other two, which is what usually happens when alerting is all-or-nothing.
Export into whatever you already run
CEF for SIEM ingestion, both as a bulk pull and a tailable real-time log. CSV and a colour-coded Excel workbook for people who work in spreadsheets. And a NotebookLM-ready brief that turns the current filtered view into one document with the conversation around each link intact.
A tool that reads your messages has to earn it.
Every decision below trades some convenience for the ability to answer “where does our message content go?” with a short, checkable sentence.
The stack, and why each piece is there.
Teams that would be asked what happened, and by whom.
Organisations that live in Teams
Where chat has quietly replaced email as the place work is coordinated, and the security attention has not followed it across.
Small security functions
One or two people covering everything, who need the estate to surface its own problems rather than being interrogated for them.
Regulated and audited environments
Where "we handled it" has to be demonstrable, with times, actions and the person who took them.
Anyone who cannot send content to a cloud AI
Legal, healthcare, finance, defence — the local-model architecture is the reason this can be used at all in places where a cloud API is simply not permitted.
Common questions.
Does it read our Teams messages?
It reads the messages in the chats and channels you point it at, through the Microsoft Graph API, because that is where the links are. It is read-only — it never posts, deletes, quarantines or changes anything in your tenant. What it stores is the link, the verdict and enough message context to make the finding readable.
Does our message content get sent to an AI company?
No. All three AI features run on a model hosted on your own machine through Ollama. There is no OpenAI, Anthropic or other cloud LLM API in the product at any point. That was a deliberate architectural decision made separately for each feature, and it is the main reason the tool is safe to point at internal conversations at all.
How is this different from what Microsoft Defender already does?
Defender blocks. This explains. Defender is doing the enforcement, and should be — this sits alongside it and answers the questions enforcement does not: which people are receiving this, is the same link spreading, what was actually said around it, what does our link traffic look like as a whole, and can I hand a reviewer an audit trail of what we did about it. If you have neither, buy the blocking first.
Does it need VirusTotal and URLhaus subscriptions?
URLhaus is free and open. VirusTotal has a free tier with a rate limit, which the tool tracks and shows on the dashboard as quota usage; a paid key raises it. If you already hold an enterprise key, it uses that.
Where does it run, and where does the data live?
On your own infrastructure — a VM or container you control, with PostgreSQL behind it. Nothing is hosted by us, no message content passes through anything of ours, and there is no shared multi-tenant instance holding other companies' data next to yours.
Can it watch more than one organisation?
Yes. The data model is multi-tenant, and the isolation is enforced in the database layer rather than by each route remembering to filter — which is what makes it safe for a managed service provider to run one instance across several client tenants.
Can you build something like this for us?
Yes — this is client work rather than a shrink-wrapped product, and it was shaped around how one security-conscious team actually works. We scope your environment, your feeds and your reporting needs first, then quote a fixed price before any work starts.
Want to know what is being shared in your Teams?
Most of the software we build starts as a question nobody can currently answer. Book a free 30-minute call — we'll scope it honestly, including telling you if the thing you already pay for covers it.
- 01Your workspace — how many people, how much of the work happens in chat
- 02What you need to see — detection, investigation, reporting, evidence
- 03Where it can run — your infrastructure, your data, your constraints
- 04A fixed price — in writing, within 24 hours of the call