All case studies

Case study · Cybersecurity · Digital risk protection

Designing a multi-tenant platform to monitor an organization’s external threats

AEGIS DRP · Cybersecurity · External attack surface and brand protection · Canada

A digital risk protection platform built from the data model up: thirty-five tables isolated by organization, four deterministic detection engines that return their results to the analyst, and a response chain of alerts, cases and takedown drafts.

  • 35 tables in five domains, isolated by organization with row-level security
  • 4 detection engines: typosquatting, attack surface, brand mentions, leaked credentials
  • 5 server-side functions — four scans and one AI copilot

Status In production

Context

Digital risk protection — watching what appears outside an organization’s perimeter: look-alike domains, forgotten subdomains, weak certificates, brand impersonation and credentials indexed on the public web — is a category dominated by large vendors with opaque pricing. I wanted a platform of that kind that a Canadian security team could run for itself, or that a managed security provider could operate for several clients. AEGIS DRP is that platform: designed as the external counterpart of the internal security tooling my team builds, with the same stack and the same discipline, and specified as a complete product from the first day rather than as a collection of scripts.

Challenge

Three problems had to be solved together. Detection had to rely only on public lookups — DNS, web search, certificate checks — so that scanning a domain never touches the target and never looks like an attack. Every detection had to become a workable object: an alert with a severity, a case with a status pipeline, a takedown request against a real registrar or platform. And the whole thing had to be multi-tenant from the first migration, because a security platform that mixes two organizations’ findings is worse than no platform at all. On top of that, the AI component had to be useful to an analyst without ever pretending to be the detector.

My role

Founder, architect and product designer. I defined the threat model — which external signals matter and which can be collected without touching the target —, the data model that turns those signals into findings, cases and takedown requests, and the phased functional specification that ordered the build. I chose the stack and the isolation model, set the rule that AI advises but never detects, and directed the technical work from the first migration to the live platform. The platform was built and is operated with my team at SOFT M POWER CANADA.

Architecture / approach

The data model came first, laid out in four thematic migrations — multi-tenant foundation, then attack surface with findings and cases, then takedown and evidence, then threat intelligence and brand — for thirty-five tables, eight enumerations, twenty-one finding types and twelve indicator types. Isolation is enforced in the database: a single security-definer function resolves the caller’s organization and row-level security policies apply it to every tenant-scoped table, so no page can forget it. The four scan engines are stateless server-side functions that return their results to the browser; the analyst reviews them and decides which become alerts. Detection and human qualification are separated on purpose.

Technology

React and TypeScript single-page application with a component library and query caching; PostgreSQL with row-level security, database scheduling and outbound HTTP for daily scan runs; five server-side functions in TypeScript on a serverless runtime: a home-grown typosquatting generator (seven permutation techniques, a cap of 200 candidates, DNS-over-HTTPS resolution in batches of 20), an attack-surface scan combining DNS records, a TLS check and a web crawl with screenshots, two search-based monitors for brand mentions and leaked credentials, and a streaming copilot relayed to a cloud-hosted large language model through a gateway so that no provider key reaches the client.

Execution

The build followed the specification phase by phase, with my team working on an AI-assisted development platform from a detailed functional brief: foundation and authentication, then findings, cases and the Command Center, then takedown drafting and the threat-intelligence model. Two corrections visible in the history mattered more than any feature. The dashboard initially rendered placeholder numbers; it was rewritten to compute its risk score, trend and breakdowns from the tenant’s real data only. And importing discovered assets from a scan created duplicates until a unique index on organization, type and value made the import idempotent. The user-provisioning function was also hardened with a locked search path.

Constraints

No active scanning: only public DNS, public web search, a certificate lookup and a crawl of the public site, which keeps the platform on the right side of the line but limits what it can see — no social networks, app stores or dark-web sources today. Third-party services are used for web search and certificate checks, and the copilot sends conversations to a cloud model provider; none of this is hidden from the user. Remediation is drafted, not executed: a takedown request is written against the target’s abuse channel and tracked with the case, and sending it remains a human step. Results of scheduled scans are not yet retained, which is the next item on the roadmap.

Business impact

What the platform delivers today: an attack-surface inventory across eleven asset types with deduplicated imports, four detection engines that turn public lookups into typed and scored findings, an alert queue with false-positive handling, a six-step case pipeline with comments, takedown drafts against a catalogue of twelve target categories, a Command Center and an eight-week reporting view computed from real data, indicator records and a hunting search — all isolated per organization so that a provider can run it for several clients. The same foundation is designed to receive persisted scheduled scans, direct takedown submission and outbound notifications without touching the data model.

Key takeaways

  1. Put isolation in the database, not in the pages: one function that resolves the tenant and policies on every table is the only design that survives feature growth.
  2. Separate detection from qualification. Stateless engines that return candidates, and a human who decides what becomes an alert, give a cleaner product than automatic persistence.
  3. A dashboard that shows placeholder numbers is a liability; computing from real data from the first version is cheaper than removing fakes later.
  4. Make imports idempotent before making them fast: a unique index solved more support problems than any feature.
  5. Say exactly what the AI does. A copilot that advises an analyst is valuable; a copilot presented as the detector is a promise the code cannot keep.