Every security engineering team that runs more than one scanner eventually reaches the same fork in the road. You have findings coming out of Tenable, a DAST tool, maybe a SAST or SCA engine, and a ticketing system that needs to receive the important ones. Someone wraps a script around it. The script grows. Six months later you are quietly maintaining a small platform, and the question on the table is no longer “should we automate this?” but “should we keep building the platform ourselves, or buy one that already exists?”
This is a real decision with real tradeoffs, and it deserves better than a sales pitch. There are narrow situations where building in-house is the correct call. There are also broad ones where teams underestimate the surface area of a production vulnerability management platform until they are deep into year two of maintenance. This article lays out both sides honestly, then walks through the specific components you would have to design, build, and keep alive yourself. We use PMAP as the concrete reference for what a “buy” decision delivers, and every claim here maps to the platform’s documented architecture.
If you want the full architectural deep dive on how a vulnerability management platform is structured internally, that lives in our pillar guide on vulnerability management platform architecture. This article stays focused on the decision itself.
The Build vs Buy Question Most Teams Get Wrong
The mistake is not choosing wrong. The mistake is scoping the question wrong. Teams compare the cost of a vendor license against the cost of a single engineer writing a single ingestion script, and the math looks obvious. Build is cheaper. Build gives us control. Build means no procurement cycle.
That comparison is false because the two things are not the same thing. A script that pulls findings from one scanner into a database is not a vulnerability management platform. A platform is what you get when you add correlation, deduplication, a status workflow, SLA tracking, multi-tenancy, role-based access control, audit trails, async job processing, and a maintenance commitment that does not end. The honest version of the question is this: what is the total cost of owning all of that, for as long as your program needs it, versus the cost of buying a system where those components already exist and are someone else’s responsibility to keep current?
PMAP is positioned as an enterprise vulnerability management platform and multi-vendor scan orchestrator. Underneath that positioning sits a Go modular monolith with roughly 500 REST endpoints spread across 48 backend domains. That number is not a vanity metric. It is the answer to “what would we actually have to build?” Most build projects start by reproducing two or three of those domains and assume the rest are details. They are not details. They are the difference between a script and a platform.
So before comparing dollars, compare scope. The rest of this article makes that scope visible.
What “Build” Actually Means at Platform Scale
When a team says “let’s build it,” the mental picture is usually small. Ingest findings. Store them. Show them in a table. If that were the whole job, buying would rarely make sense. The reason buying often does make sense is that a complete vulnerability management platform is a much larger system than the mental picture suggests.
Consider the shape of PMAP as a reference architecture. It is a single deployable Go binary organized as a modular monolith. Each business concern lives in its own internal domain with a strict separation between HTTP handling, business logic, persistence, and types. There are 48 of these domains. They cover finding lifecycle, asset inventory, correlation, scan orchestration, integrations, reporting, analytics, dashboards, authentication, RBAC, MFA, sessions, API keys, audit, company tenancy, teams, SLA configuration, licensing, runbook automation, notifications, realtime push, an event bus, an admin console, query building, saved views, and more. Together they expose around 500 REST endpoints, all sitting on a shared foundation that handles pagination, response envelopes, authorization, and middleware consistently.
You would not build all 48 domains on day one. But you would discover, domain by domain, that the ones you skipped were load-bearing. Skip a proper status workflow and findings become free-text notes nobody trusts. Skip correlation and your finding counts inflate every time a scan reruns. Skip the scope filter and you have a cross-tenant data leak waiting to happen. The platform scale is not optional padding. It is the minimum surface area required for the system to behave correctly under real data and real users.
This is why the build estimate is almost always wrong at the start. The estimate covers the visible part. The maintenance lives in the part you have not modeled yet.
When Building In-House Makes Sense
A fair comparison admits where the alternative wins, and building in-house genuinely wins in some cases. If your situation matches the profile below, do not let anyone talk you out of a focused internal tool.
Building makes sense when your scope is narrow and likely to stay narrow. If you run exactly one scanner, against one environment, for one team, and you do not foresee that changing, the integration and correlation problems that justify a platform mostly disappear. A thin internal tool that pulls from that single engine and presents findings can be entirely reasonable.
Building makes sense when you have no multi-tenancy requirement. Multi-tenant isolation is one of the heaviest components in a real platform, and if you serve a single organization with no subsidiaries, no client separation, and no need to scope data per business unit, you avoid that weight entirely.
Building makes sense when you have a standing platform engineering team with capacity to own the result for years. The first release is never the expensive part. Ongoing ownership is. If you already staff a team that maintains internal tooling as a permanent commitment, the maintenance curve is something you can absorb.
And building makes sense when your requirements are genuinely unusual, where no vendor model fits your workflow and the cost of bending your process to a product exceeds the cost of writing your own. This is rarer than teams assume, but it is real.
If two or more of these describe you, build is a defensible decision. The sections that follow are not an argument that you are wrong. They are an honest inventory of what you are signing up to own, so that the decision is made with full visibility.
The Hidden Surface Area of a Real VM Platform
Here is where the estimate and the reality diverge. The table below summarizes the components most build projects underestimate. Each one is expanded in the subsections that follow, with the corresponding behavior PMAP already implements.
| Component | What you have to build and maintain | What “buy” gives you on day one |
|---|---|---|
| Scanner integrations | A connector per vendor, kept current as each vendor’s API drifts | 30 vendor connectors across 104 integration endpoints |
| Correlation and dedup | A fingerprinting pipeline that survives rescans and endpoint changes | A 4-case correlation pipeline with SHA-1 fingerprinting |
| Multi-tenancy | Scope enforcement on every list, export, and facet path | A ScopeFilter invariant applied default-deny across every domain |
| Identity and RBAC | Login, MFA, sessions, a permission model, license gating | JWT plus LDAP, MFA, a 10×6 RBAC matrix, an Ed25519 license gate |
| Async and observability | Job processing, eventing, metrics, audit trails | An event bus with 34 types, four consumers, Prometheus metrics |
Scanner Integrations and Their Upkeep
The integration layer is the single largest part of a vulnerability management platform, and it is the part that never stops needing attention. In PMAP, the integration domain alone exposes 104 endpoints and ships connectors for 30 vendors spanning VM scanners, DAST, SAST, SCA, ITSM, CI/CD, container scanning, mobile, and network discovery. That is the breadth a real program eventually needs.
But breadth is only the first cost. Every connector in PMAP is held to a hard set of rules. It must be idempotent, so reimporting the same data does not create duplicates. It must be retry-safe, so a failed import can run again cleanly. It must be dedup-aware, so it participates correctly in correlation. It must be audit-logged and raw-payload-archived, so you can always trace what a scanner actually reported. And it must be resumable, so a large import that fails partway can continue.
If you build this yourself, you are not writing one connector. You are writing a connector framework, then a connector per vendor, then keeping each one current as that vendor changes its API, its severity scheme, and its export format. Vendor API drift is not a one-time integration project. It is a permanent maintenance subscription you pay in engineering hours. The connector that worked last quarter breaks silently when a vendor renames a field, and you find out when your finding counts go wrong. Buying moves that maintenance subscription off your backlog. For a deeper look at how this layer is designed, see our guide on the security integration layer.
Correlation and Deduplication You Have to Get Right
Correlation is the component teams most often skip and most often regret skipping. Without it, a finding that appears in three scans counts as three findings. A vulnerability that gets remediated, then resurfaces on the next scan, looks like a brand new issue. Your metrics become noise.
PMAP runs every importer through a correlation engine built as a 4-case pipeline. It first tries to match on the scanner’s own reference. Failing that, it matches on a SHA-1 fingerprint computed from normalized finding attributes and endpoint identity. From there it decides whether to reopen a previously closed finding or create a new one, with wave accounting that tracks which scan wave a finding appeared in. Endpoint normalization is part of this, so the same host reported under slightly different identifiers still correlates.
Getting this right is genuinely hard. The fingerprint has to be stable enough that the same vulnerability always produces the same fingerprint, and specific enough that two different vulnerabilities never collide. The reopen logic has to distinguish a recurrence from a fresh discovery. Endpoint normalization has to handle the messy reality of how different scanners name the same asset. A build team can produce a first version of this in a sprint. Producing a version that holds up across years of rescans, scanner changes, and edge cases is a different undertaking entirely. This is precisely the kind of component where buying buys you correctness someone else already debugged.
Multi-Tenancy as a Non-Negotiable Invariant
If your platform ever serves more than one isolated group of data, whether subsidiaries of a holding company or separate clients of a service provider, multi-tenancy stops being a feature and becomes a security boundary. And security boundaries are unforgiving. A single missed code path leaks one tenant’s data to another.
In PMAP the tenant boundary is the company, and a holding company with subsidiaries forms the hierarchy. The critical detail is how isolation is enforced. Every list, export, and facet handler applies a ScopeFilter derived from the authenticated user’s access. The default is deny. Only platform admins run unrestricted; every other principal is confined to their assigned company or project scope. Cross-tenant identifier access is rejected explicitly rather than silently allowed. The architecture treats forgetting scope as a non-negotiable invariant, enforced in every domain rather than checked in a few places and assumed elsewhere.
That last point is the one a build team underestimates. Multi-tenancy is not a module you add. It is a discipline you have to apply to every single query that returns data, across every domain, forever, including the ones you write next year. One handler that forgets the filter is a breach. Buying a platform where that invariant is already wired into the foundation removes an entire class of risk you would otherwise have to police on every code review. The operational side of running many tenants is covered in our guide on multi-tenant vulnerability management.
Identity, RBAC and Licensing
Authentication and authorization look like solved problems until you actually have to implement them for an enterprise security tool. Then you discover how many pieces there are.
PMAP handles login through JWT issuance with LDAP/AD bind and auto-provisioning, plus password complexity and reuse history. Step-up authentication uses TOTP MFA with encrypted secrets and recovery codes. Sessions are tracked, with single-use refresh-token rotation and the ability to revoke. Machine access goes through hashed API keys with one-time secret reveal. Authorization runs on a permission matrix of 10 entities by 6 actions, scoped at global, company, or project level, with time-bound grants and cached resolution. And there is a licensing gate, an Ed25519-signed token checked by middleware that blocks writes when a license is expired or revoked.
None of those are exotic. All of them are expected in an enterprise platform, and all of them are yours to build and secure if you go the build route. Identity is also the component where a subtle bug is most dangerous, because the failure mode is unauthorized access rather than a visible error. This is a domain where the value of buying is not just the time saved but the accumulated hardening you inherit. The RBAC and tenancy design is documented further in our identity, RBAC and multi-tenancy datasheet, one of the two heaviest components of any build scope.
Async, Eventing and Observability
The last hidden layer is the one users never see directly, which is exactly why build projects defer it until it hurts. Long operations like scans, imports, exports, and report generation cannot run inside an HTTP request. They have to be async, cancellable, resumable, and progress-aware. The moment you have async jobs, you need a way for the rest of the system to react to what those jobs produce.
PMAP solves this with an in-process event bus carrying 34 event types, dispatched asynchronously per goroutine with panic isolation, fed by 14 producer domains and read by four consumers. Those consumers are the runbook engine for event-triggered automation, the notification system for fan-out to in-app, email, Slack, Teams, and webhooks, the realtime SSE bridge that pushes events to the browser, and the audit bridge. On top of that sits observability, with a Prometheus metrics endpoint and in-process counters, plus a dual audit trail of typed security events and an async activity log.
A build team can ship a feature without any of this. The feature works in a demo. Then it goes to production, a report generation request blocks for ninety seconds, a failed import has no retry path, an automation that should have fired silently did not, and nobody can explain what happened because there is no audit trail. Eventing and observability are not polish. They are what makes the platform diagnosable and automatable, and they are expensive to retrofit after the fact.
Total Cost of Ownership Beyond the First Release
Every section above describes a one-time build cost. The deeper issue is that none of these costs are actually one-time. A vulnerability management platform is a living system that has to keep up with a moving world, and the total cost of ownership is dominated by what happens after the first release ships.
Consider the maintenance vectors. Scanner vendors change their APIs, and every change can break a connector. Severity schemes shift, and your normalization has to follow. New vulnerability classes appear and your taxonomy has to absorb them. Security patches land in your own dependencies and have to be applied. The database schema evolves as the product grows, and every schema change has to be a safe, ordered migration that runs against production data without downtime.
That last point deserves emphasis because it is easy to underestimate. PMAP’s PostgreSQL schema is managed through 435 embedded migrations. That number is evidence of something important: a real platform’s data model is not designed once and frozen. It changes continuously, and every change has to be applied safely and in order across every deployment. A build team owns that migration discipline forever. There is no release where the schema work is finished.
When you tally total cost of ownership honestly, the engineering salary that maintains the build is rarely a single engineer. It is the connector maintenance, the migration discipline, the security patching, the on-call burden when an async job wedges, and the opportunity cost of those engineers not working on your actual security program. A buy decision converts that open-ended, compounding cost into a known, bounded one, and it moves the connector drift and the migration safety into the vendor’s responsibility. Whether that trade is worth it depends entirely on the questions in the next section.
A Decision Framework: Five Questions Before You Build
There is no universal answer. There is a way to reach the right answer for your situation. Work through these five questions honestly, and the decision usually becomes clear.
1. What is the real scope, today and in two years? If you will only ever run one scanner against one environment for one team, the platform-scale costs do not apply and building a focused tool is reasonable. If you already run multiple scanner types, or you expect to, you are signing up for the integration and correlation surface area whether you build or buy. Scope honestly, including the growth you can already see coming.
2. Do you have a team that can own this for years, not months? The first release is the cheap part. Ask whether you have standing capacity to maintain connectors, apply migrations, patch dependencies, and carry the on-call burden indefinitely. If the answer is “we’ll figure that out later,” that is usually the answer to build vs buy.
3. How much maintenance burden are you actually willing to carry? Connector drift and schema migration are permanent subscriptions paid in engineering hours. Decide before you start whether your team should spend those hours on platform plumbing or on your security program. Both are valid choices, but only if you make the choice deliberately.
4. How fast do you need time-to-value? A bought platform delivers correlation, multi-tenancy, RBAC, and 30 connectors on day one. A built platform delivers them when you finish building them, which is later than the estimate. If your program needs results this quarter rather than next year, time-to-value weighs heavily toward buy.
5. Do you need multi-tenancy, now or later? If you serve subsidiaries or clients, multi-tenant isolation is a security boundary you cannot get wrong, applied to every query forever. That single requirement shifts the calculus hard toward buying a platform where the invariant is already enforced across every domain.
If your answers point to narrow scope, a permanent platform team, an appetite for maintenance, a relaxed timeline, and no multi-tenancy, build with confidence. If they point the other way, the build estimate is hiding the costs this article has tried to make visible.
How PMAP Delivers the Platform You Would Otherwise Build
A buy decision is only as good as what it delivers on day one, so here is what PMAP gives you concretely, mapped to the build scope above.
It delivers the integration layer as a finished system: 30 vendor connectors across 104 endpoints, each idempotent, retry-safe, dedup-aware, audit-logged, and raw-payload-archived, with vendor severity preserved as original_severity and never trusted blindly. It delivers correlation as a working 4-case pipeline with SHA-1 fingerprinting and endpoint normalization, so finding counts stay honest across rescans. It delivers multi-tenancy as a default-deny ScopeFilter invariant enforced in every domain, so isolation is structural rather than something every code review has to police. It delivers identity, MFA, sessions, API keys, a 10×6 RBAC matrix, and license enforcement as a hardened, integrated whole. And it delivers the async, eventing, and observability foundation, an event bus of 34 types feeding runbook automation, notifications, realtime push, and audit, with Prometheus metrics, so the platform is automatable and diagnosable from the start.
All of it is built as a single Go modular monolith with roughly 500 REST endpoints across 48 domains, on a shared foundation for pagination, authorization, and middleware, with a schema managed through 435 migrations that the vendor keeps current rather than you. That is the platform you would otherwise be building, available as a decision rather than a project.
If you want to see the architecture in full before you decide, read the vulnerability management platform architecture pillar guide. If you want the detail on the two heaviest build components, the integration platform is covered in the ITSM and CI/CD integration datasheet, and tenancy and access are covered in the identity, RBAC and multi-tenancy datasheet.
External standards worth consulting as you frame the decision include NIST SP 800-160 on systems security engineering, which sets expectations for building secure systems, the Twelve-Factor App methodology for the operational properties a platform of this kind needs, and the OWASP Application Security Verification Standard for the security baseline any identity and access layer has to meet.