Case Study Tech audit

Technical Due Diligence Without Full Access

Mad Devs assessed a revenue-generating digital platform for a potential buyer without access to its source code or production systems. Through structured interviews, guided demonstrations, and AI-assisted analysis using our Enji Fleet, we identified 7 critical-priority issues and found that some of the deal's most serious risks lay outside the codebase.

Overview

A potential buyer asked Mad Devs to assess a software platform before an acquisition. The platform had been in production for about three years, processed user payments through roughly 30 payment providers, and handled around 1.7 million API requests a day. A team of about 30 people supported it, including six core engineers and a 12-person support team working around the clock.

The main constraint was access. Until the deal closed, the buyer did not control the platform, and the company being acquired did not give external auditors access to its repositories or production environments. It did open its knowledge base, task tracker, and team chats for review, and its engineers agreed to walk us through code and infrastructure in live sessions.

The buyer approved 18 key questions across seven assessment areas.

In short, they asked:

  • Is the code maintainable, and how much technical debt needs immediate investment?
  • Is the architecture modular enough to grow, and which components fail first under 5–10x load?
  • Are there critical security vulnerabilities, and how is sensitive data protected?
  • Which external services and internal components are single points of failure?
  • How dependent is the product on individual engineers, and how mature are the team’s processes?
  • What would it cost to fix the platform, and what would it cost to rebuild it?

The platform had a solid engineering foundation. The most consequential finding was organizational: critical knowledge about the system lived with a few people, and the processes that would let a new owner keep it running were largely undocumented.

Project at a glance

7

Assessment areas, from code to team processes

4

Codebases reviewed: Go, Node.js, PHP, and Vue.js

2-3 months

Estimated time to fix priority issues

$400–680K

Estimated cost to rebuild comparable functionality

Challenges and solutions

Two challenges shaped this audit: gathering reliable evidence without access to the code, and making the results useful for an acquisition decision.

Challenge 1: Auditing a platform without access to its code

A typical technical due diligence gives auditors read-only access to repositories, infrastructure configuration, monitoring, and development tools. Here, the target company kept its code and production environment closed to outsiders until the deal was signed. This is common in acquisitions, and organizations with strict security requirements often impose the same limits.

Without direct access, an audit risks describing how the team says the system works instead of how it actually works. We needed enough first-hand evidence to test engineering decisions, challenge assumptions, and find risks the team itself might not see.

Solution: A four-stage audit built on observable evidence

icon

Preparation and scope definition

We agreed on the audit objectives and the 18 key questions with the buyer, then met the product team to clarify scope, constraints, and schedule. A separate session covered the high-level architecture, technology stack, development history, and current processes. From this context, we built tailored checklists, interview questions, and a plan for demo sessions, and assembled auditors across backend, frontend, infrastructure, security, and QA.

Icon

Structured interviews with the product team

We interviewed founders, technical leads, and key developers about development and quality processes, monitoring and incident management, security, disaster recovery, onboarding, and third-party dependencies. The interviews showed where knowledge existed only in people’s experience and gave us claims to verify at the next stage.

Icon

Guided demonstrations of code and infrastructure

The core of the audit was a series of focused 60–90-minute online sessions, each led by the engineer who owned the area. Engineers walked us through key repositories, cloud consoles, CI/CD output, Grafana dashboards, and Terraform configuration. When we needed code-level data, the product team ran dependency scanners and linters on screen (Trivy, golangci-lint, npm audit, composer audit), and we recorded the results. Auditors compared what the demos showed with what the interviews claimed and followed up on every inconsistency.

Icon

Validation and reporting

We consolidated the evidence into a report section by section, then shared the draft with the product team for fact-checking before the final presentation to the buyer. Under restricted access, this step matters most: it is where missing context surfaces before it turns into a wrong conclusion.

Restricted access has a cost, and we accounted for it. Code-level numbers in the report cover the repositories and checks the product team showed us, not an independent scan of everything. Cross-checking demos against interviews and artifacts, and fact-checking the draft with the people who built the system, kept that gap as small as possible.

How Enji Fleet supported the audit

Alongside the manual review, we used Enji Fleet, one of our own AI tools from the Enji platform. Fleet did not scan the client’s code. Its job was to make the human part of the audit faster and more systematic.

Enji Fleet runs recurring engineering work with specialized AI agents. Instead of handing a complex assessment to one general-purpose assistant, Fleet splits it into focused tasks and runs each one through a predefined procedure, or runbook. In this audit, Fleet agents:

  • Turned the 18 key questions and the system context into tailored checklists, interview questions, and a demo-session plan for each area.
  • Processed the artifacts the target company opened for review (knowledge base, task tracker, team chats) and flagged contradictions with interview answers for auditors to raise in the next session.
  • Consolidated findings from four codebases and seven assessment areas into one report structure, mapped to the 18 questions and ranked by priority.

Automated checks still cover only part of a due diligence. No tool can tell whether a team can recover from a major incident, whether key decisions are written down, or whether the product survives the departure of two engineers. Those answers came from interviews and engineering judgment, and they led to the audit’s most important finding.

Image

What the audit found

The platform was a working, revenue-generating product with a modern core. Its main backend ran as Go microservices in Kubernetes, deployments went through a GitOps pipeline built on ArgoCD and Terraform, and the team shipped backend releases five to six times a week. The API averaged 100 ms per request at current load. About 70% of the server-side functionality had already been migrated from a legacy Node.js backend to Go, with a clear strategy for the rest. Against this foundation, the audit identified five groups of risks:

Finding 1: Critical knowledge was concentrated in a few people

A small, fast team with little documentation: efficient today, fragile under a new owner.

What we found

  • One frontend developer and one QA engineer.
  • Legacy Node.js modules and the balance-locking service understood by only a few engineers.
  • Requirements and architecture decisions passed on verbally or kept in chats.
  • No onboarding checklists; new developers needed 2–4 weeks of close mentoring.
  • Part of the team also worked on another product.

Risk: buying the code would not guarantee the ability to maintain it.

Recommended: a knowledge base with named owners, documented decisions, onboarding and offboarding checklists, a RACI matrix, and agreement on key engineers’ involvement at the deal stage.

Image

Finding 2: Code-level risks to transaction integrity

Two critical issues could cost money directly.

What we found

  • User balances stored as floating-point numbers, causing rounding errors.
  • No graceful shutdown in the Go API, schedulers, and lock service, so a deployment could interrupt a financial operation.
  • 1,057 linter warnings, 277 panic calls, and 272 unhandled errors in the Go code.
  • No backend unit tests; QA automation covered 39% of key scenarios, outside CI/CD.
  • The legacy Node.js backend had 613 linter errors and was no longer being improved.

Risk: financial losses and growing maintenance costs.

Recommended: exact types for balances, SIGTERM handling in every service, linters and tests in CI/CD, and 15–20% of each sprint for technical debt.

Finding 3: A single database limited growth and resilience

What we found

  • One Percona (MySQL) instance for all services, vertical scaling only.
  • Years of archived data kept alongside live data, with no replication or partitioning.
  • The balance-locking service as a second single point of failure.
  • No disaster recovery plan and no RTO or RPO.
  • No distributed tracing or business metrics in monitoring.

Risk: a database failure with unpredictable downtime and data loss, made worse by recovery knowledge held by a few engineers.

Recommended: partitioning and archiving, replication, a tested recovery plan with defined RTO and RPO, and tracing with structured logs.

Image

Finding 4: Security stopped at the perimeter

Strong: Vault for secrets, SSO with role-based access, separate staging and production clusters.

What we found

  • Unencrypted traffic between services, the database, the cache, and the message broker.
  • No security scanning in CI/CD pipelines.
  • Pods running as root, no network policies, Vault audit logs disabled.
  • No incident response plan.
  • 3 critical and 20 high-severity vulnerabilities in Node.js, 26 in the admin panel, critical ones in the frontend.

Risk: one compromised service exposes all internal data.

Recommended: now patch critical dependencies, move tokens to HTTP-only cookies, enable internal TLS. Next: mTLS, pipeline scanning, network policies, an incident response process.

Turning findings into an acquisition decision

Technical audits often end with a long list of issues and leave the buyer to work out what matters. We built the final report around the decisions the buyer had to make.

Challenge 2: Making technical risks actionable for the buyer

A list of vulnerabilities does not tell a buyer what to do. The client needed to know which risks required action before or right after the deal, how long the fixes would take, and whether the platform was worth building on.

Solution: Prioritized recommendations, direct answers, and a rebuild estimate

Each finding in the report came with its consequences, a priority level from critical to low, concrete remediation steps, and a business justification. The report answered each of the 18 approved questions directly and gave the buyer the timelines needed for planning:

  • Priority fixes: about 2–3 months of team work.
  • Longer-term debt (data layer, completing the Node.js migration, typing): another 6–9 months.
  • Process formalization and documentation: an investment for the first 6–12 months after the acquisition.
  • Integration into the buyer’s organization: a phased transition of at least 12 months.
Image

We also estimated what it would take to recreate comparable functionality from scratch: a team of nine engineers working for about 20 months, at $400,000–$680,000. The estimate covered development only and excluded requirements analysis, marketing, licenses and infrastructure, hiring costs, and the existing user base and brand. It was a reference point for the engineering effort behind the platform, not its market value.

Key results

  • Acquisition risks made concrete. The buyer received 7 critical-priority issues, each with a fix, a priority, and a time estimate, separated from improvements that could wait for longer-term planning.
  • A continuity risk that code analysis alone would miss. The audit showed that the platform’s sustainability depended on a few people and gave the buyer a plan to reduce that dependency, along with terms to agree on at the deal stage.
  • A clear picture of what to invest and when. Fix timelines, the transition period, and the rebuild estimate gave the buyer inputs for budgeting and negotiation.
  • A balanced view of the asset. The report confirmed the platform’s strengths (a modern Go core, GitOps infrastructure, frequent releases, stable performance) alongside its risks, so the buyer could weigh both.
  • Delivered ahead of schedule without code access. Close collaboration with the product team let us finish early while working only through interviews, guided sessions, and the artifacts the target company opened.

Audit scope

This engagement assessed the platform’s existing technology, team, and processes rather than building new software.

Image

Planning an acquisition
or investment?

Get an independent view of the technology, team, and risks behind the product, even when full access isn’t possible.

Technical due diligence beyond the codebase

A technical audit asks whether the technology, infrastructure, processes, and people behind a product can keep it running and growing under a new owner. Code quality is one input to that answer.

Mad Devs adapts the audit method to these constraints: controlled evidence collection, experienced engineers, and AI-assisted analysis with Enji Fleet.

When a client can grant repository access, we also run Enji Guard, our AI code auditing tool. Guard checks repositories for security issues, outdated dependencies, test quality, CI/CD gaps, and dead code. It connects through scoped, revocable GitHub App access and reads the code in a temporary workspace that is removed afterward. For stricter environments, it runs self-hosted, inside the client’s own infrastructure. After a deal, the same tool can keep auditing the codebase on a recurring schedule, so new risks surface before they reach production.

The result shows what needs fixing, what the organization depends on, and what it will take to make the product ready for its next owner.

From findings to fixes:
related case studies

FAQ