Share code between services as versioned libraries pulled through the dependency manager, not by copying files or linking repos. Twelve-factor says multiple apps sharing the same code is a violation, and the security reason is that a library has a version you can track, scan and update.
What the codebase rule says
The methodology says there is one codebase per app, tracked in version control, with many deploys of it: production, staging and each developer's copy. If there are multiple codebases, it is a distributed system, and each component can be an app on its own. It then states that the fix for shared code is to factor it into libraries included through the dependency manager.
The security problem with copy and paste sharing
When two services share code by copying a directory, a script or a git submodule pinned to nobody's attention, the shared code has no clear version. That causes familiar problems.
- Silent forks. A fix is applied in one copy and forgotten in the other.
- Invisible to scanners. Copied files carry no package metadata, so they never show up in an SBOM or advisory match.
- Unclear ownership. Nobody is responsible for updating the shared code, so it ages.
- Inconsistent security behavior. One service validates input with the fixed version and another with the old one.
A published internal library fixes each of these. It has a version number, a changelog and a place in the manifest. When a flaw is found, you search manifests for that name and version.
What a library does not fix
Libraries create their own risks, so manage them on purpose.
- Dependency confusion. An internal package name that also exists on a public registry can be hijacked. Reserve names or scope them to your own registry.
- Version spread. Ten services on ten versions of the same library is hard to patch. Measure the spread; see dependency version drift across services.
- Blast radius. A flaw in a shared auth library affects every service that uses it, which is also the argument for fixing it once.
- Monorepo confusion. Many packages in one repository are fine, but each deployed app should still have a clear unit of build and release.
A rollout plan
- Find shared code today: duplicated directories, submodules and vendored copies.
- Move each into a package with a version and an owner.
- Publish to a private registry and configure clients to prefer it for your names.
- Replace copies with a dependency declaration and a lockfile entry.
- Add the library to your SBOM process and your advisory watch.
- Set a policy for how quickly consumers must adopt security releases.
Try it yourself
Click through it at your own pace, or open it full screen.
Click through the demo and see how reachability separates the findings that matter from the rest, which is useful when one shared library affects many services.
Quick check
Is a monorepo a violation of one codebase per app?
Not necessarily. The point is that each deployable app has its own build and release unit, with shared code coming in as libraries rather than copied files.
Why can scanners miss copied code?
Copied files have no package name or version, so there is nothing to match against an advisory database.
How should I update a shared internal library after a security fix?
Publish a new version, then update each consuming service's manifest and lockfile. Track which services still use the old version.
Where Safeguard fits
Safeguard scans dependencies and builds SBOMs, and its reachability analysis helps you separate vulnerable packages your code actually calls from those it does not. You can try a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.