Safeguard
Developer Tools•

Should I use mavenLocal() or flatDir in a Gradle build?

Avoid mavenLocal and flatDir in shared or release builds. Gradle bypasses its cache for local repositories and says they make reproducible builds harder.

Safeguard Security Team
3 min read

Avoid mavenLocal() and flatDir in shared or release builds. Gradle's docs say it bypasses its dependency cache for local Maven and Ivy repositories, that these repositories make reproducible builds harder, and that they should be limited to prototyping. A file on one laptop is not a dependency your team or your auditors can see.

What they do

mavenLocal() points at the Maven repository on your own machine, and flatDir points at a folder of files. Both are local repositories. They are common because they are the quick way to test a library change before publishing it.

What the docs say

Gradle's repository documentation states two things. First, Gradle bypasses its dependency cache for local Maven and Ivy repositories. Second, these repositories make reproducible builds harder, so the page recommends limiting them to prototyping.

Why this matters for security

ProblemEffect
Not reproducibleAnother machine or CI cannot rebuild the same thing
No provenanceA file in a folder has no registry record or publisher
No checksums from a repositoryVerification has nothing authoritative to compare to
Invisible to reviewThe artifact is not in version control
Poor for inventoryScanners may see a coordinate with no source

A local repository entry can also mask a problem: the build works on your machine because a stale artifact sits in your home directory, and fails on CI. Worse, it can work on CI only if an image carries a leftover file.

Better patterns

  1. Publish internally. Use an internal repository for work in progress modules, with a SNAPSHOT or a dated pre-release version.
  2. Use included builds. Gradle composite builds let you develop a library and an app together without publishing.
  3. Use project dependencies inside one repository.
  4. For vendor jars, host them in your internal repository with a checksum and an owner, instead of a flatDir.

Steps to find and remove them

  1. Search every build and settings file for mavenLocal and flatDir.
  2. Check init scripts too, since they can add a local repository. See Gradle init scripts.
  3. For each hit, decide: temporary experiment or real dependency.
  4. Move real dependencies to a proper repository.
  5. Add a CI check that fails if either appears in a release build.

A note on Android

Android's docs show mavenLocal() among the ways to declare a local repository. That is a statement of what is possible, not a recommendation for release builds.

Try it yourself

Click through it at your own pace, or open it full screen.

Check how a component with no clear origin appears. Those entries are hard to defend in an audit.

Safeguard's SBOM and dependency scanning record every component a repository resolves, and the free scan at gold.safeguard.sh/scan can show you what your build lists.

Quick check

Is mavenLocal fine for quick local testing?

Yes, that is the use the Gradle docs call out: prototyping. Keep it out of shared and release builds.

Does Gradle cache artifacts from local repositories?

No. The docs say Gradle bypasses its dependency cache for local Maven and Ivy repositories.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.