You are days from signing. The demo works, the revenue numbers look real, and the seller's engineer has answered every question confidently. Then someone asks the obvious question nobody wants to hear: what is actually inside the repository? A custom software code audit answers that before the money moves, not after.
Inherited and acquired codebases fail buyers in predictable ways. The system runs, so it looks healthy — but the tests are decorative, the deployment is one person's laptop, and a single dependency is holding the whole product together. None of that appears in a data room unless you go looking.
This is the process we use when clients bring us code they are about to buy, license, or take over from an outsourced team. It is deliberately evidence-based: every finding maps to a file, a commit, or a runnable observation, so it holds up in negotiation instead of sounding like opinion.
Key takeaways
- A custom software code audit is a risk-pricing exercise, not a code beauty contest. You are estimating the cost and time to make the asset safe to own.
- Start with build and test reproducibility. If you cannot build and run the system from a clean checkout, everything else is speculation.
- Weight findings by business impact: security, data integrity, and single-person dependencies outrank style and structure every time.
- Convert each material finding into a number — remediation cost, delayed roadmap, or added headcount — and use that to renegotiate price or terms.
- Time-box the audit. Two focused weeks of inspection usually surfaces the risks that matter; perfection is not the goal.
Scope the audit before you open the repository
The most common mistake is treating the audit as an open-ended exploration. Without scope, you get a long list of observations and no decision. Define three things first: what the software must do for your business, what you intend to change in the next twelve months, and what you can live with.
That framing turns a technical review into a risk assessment. A messy admin panel you plan to replace does not matter. A payment module you plan to extend absolutely does.
What the audit should cover
- Build and runtime: can a new engineer clone, build, configure, and run the system from documented steps?
- Test reality: do tests exist, do they pass, and do they actually assert behavior rather than just execute code?
- Security posture: dependency vulnerabilities, secret handling, authentication and authorization boundaries, and data exposure paths.
- Architecture fit: whether the design supports the roadmap you have in mind, or fights it.
- Operability: deployment, monitoring, backups, and what happens when something breaks at 2 a.m.
- Ownership and licensing: third-party components, license compatibility, and whether the seller actually owns what they are selling.
What to leave out
Skip line-by-line style critiques, personal preferences about frameworks, and refactors that have no bearing on risk or cost. They dilute the report and give the seller easy things to argue about. A due diligence code review checklist should be short enough that every item can change a decision.
Run the audit in five passes
Sequence matters. Each pass builds on evidence from the previous one, and you stop early if the codebase fails a fundamental check.
Pass 1: Reproducibility
Ask for a clean environment build. Watch how long it takes and how many undocumented steps appear. If the answer is "only Dave knows how to deploy it," you have found your first material risk before reading a single function.
Pass 2: History and ownership
Read the commit history, not just the current state. Look for long periods of single-author activity, large unreviewed commits, and the ratio of authors to modules. This is where a legacy code audit for acquisition earns its keep: the shape of the history tells you how the team actually worked.
Pass 3: Tests and coverage of critical paths
Coverage percentages are weak signals. Instead, ask which tests would catch a regression in your highest-value flows — signup, checkout, billing, data export. If those paths have no automated protection, every future change is a gamble.
Pass 4: Dependencies and security
Run an automated dependency scan, then verify manually. Check how secrets are stored, whether credentials appear in history, how authentication tokens are validated, and whether authorization is enforced server-side. Automated tools find known issues; they do not find a missing permission check.
Pass 5: Architecture against your roadmap
Map the top three things you want to build next onto the existing design. If each one requires rewriting a core service, that is a cost, not a criticism. Write it down as a number.
How to audit outsourced code quality without insulting anyone
When the code came from an agency or offshore team, the audit often becomes emotionally charged. Keep it factual. You are not grading the previous team; you are pricing risk.
- Ask for architecture documentation and compare it with the code. Gaps are normal; total absence is a signal.
- Check whether the repository reflects production. Divergence between what runs and what is committed is one of the most expensive findings you can make.
- Look for environment-specific hacks, hardcoded endpoints, and commented-out logic that suggests rushed releases.
- Confirm that infrastructure configuration is version-controlled, not living in a console someone clicked through.
If you do not have the internal capacity for this, bringing in an outside team that ships similar systems is usually faster and cheaper than training your own people mid-deal. That is the kind of work we do at our software development practice, and we have run it on codebases of very different vintages — you can see the shape of that work in our project history.
Apply a technical debt assessment framework that produces numbers
A finding without a cost is an opinion. Score each issue on three axes and multiply the impact:
- Likelihood of biting you — will this cause an incident in the next year under normal growth?
- Blast radius — does it affect revenue, customer data, or compliance, or is it contained?
- Remediation effort — engineer-weeks to fix properly, plus the cost of doing it while the product keeps running.
Then sort into three buckets: blockers (do not proceed without a remedy), priced risks (proceed with a price adjustment or warranty), and noted items (track, do not negotiate). This is the entire value of a technical debt assessment framework — it converts a pile of code observations into a short list of decisions.
Red flags that genuinely matter
- No reproducible build or deployment process.
- Production credentials or customer data exposed in the repository or logs.
- No automated tests on revenue-critical paths.
- A single person who understands a core subsystem, with no documentation.
- Unpatched dependencies with known critical vulnerabilities.
- Unclear or incompatible third-party licensing.
- Production and source control out of sync.
Red flags that are usually noise
- Unfashionable framework or language choices that work reliably.
- Inconsistent formatting and naming conventions.
- Missing comments on readable code.
- Architectural patterns you would not have chosen but that function correctly.
Turn the audit into negotiation leverage
The report is not the deliverable. The revised deal is. For each blocker and priced risk, decide which of four levers you will pull:
- Price reduction equal to remediation cost, with a documented estimate behind it.
- Holdback or escrow released when agreed fixes are verified.
- Seller-funded remediation before closing, with acceptance criteria you define.
- Warranties and indemnities covering security, licensing, and ownership claims.
Bring the findings to the table as evidence, not accusation: file paths, reproduction steps, and effort estimates. Sellers push back on adjectives and fold on specifics. If you need a second opinion on the estimates before you negotiate, talk to our team — a short review of your draft findings often sharpens the numbers considerably.
A short pre-signature checklist
- Clean-environment build completed and timed.
- Critical-path tests identified and run.
- Dependency and secret scan completed and manually verified.
- Repository compared against production.
- Licensing and ownership confirmed in writing.
- Every material finding assigned a cost and a negotiation lever.
Avaton builds and reviews custom software, including inherited and acquisition-stage codebases, so this process is one we run in practice rather than describe from theory. If you want to go deeper on how these decisions play out over time, our engineering blog covers the tradeoffs we see most often.
Frequently Asked Questions
How long should a custom software code audit take?
For a typical mid-sized product, two to three weeks of focused effort is enough to surface the risks that affect deal value. Larger or older systems with many integrations can take longer, but the goal is decision-grade evidence, not exhaustive review. Time-box the audit and prioritize build reproducibility, security, and critical-path tests first.
Can I audit code without the seller giving full repository access?
You can get partial signal from a read-only repository snapshot, architecture documents, and a live staging environment, but you cannot verify deployment, history, or secrets handling without access. Treat restricted access as a risk in itself and price it accordingly, or require escrow-style verification before closing.
What is the difference between a code audit and technical due diligence?
A code audit examines the software itself: quality, security, tests, dependencies, and maintainability. Technical due diligence is broader and includes team capacity, infrastructure costs, vendor contracts, and roadmap feasibility. The code audit is one input into technical due diligence, and usually the most concrete one.
Which findings should stop a deal outright?
Unverifiable ownership or licensing, exposed customer data or credentials, and the absence of any reproducible way to build and deploy the system are the findings most likely to justify walking away or demanding a full remedy before closing. Most other issues are negotiable if you can estimate their cost.
How do I use audit findings to renegotiate the price?
Translate each material finding into engineer-weeks and a dollar estimate, then present it as a remediation budget rather than a complaint. Ask for a price reduction, a holdback released on verified fixes, seller-funded remediation, or warranties. Specifics with file paths and reproduction steps are far harder to dismiss than general concerns.
Cover: Photo by Godfrey Atima on Pexels
