Skip to content
Notifications
Clear all

What's the best way to structure Snyk projects for a monolith vs microservices?

11 Posts
11 Users
0 Reactions
24 Views
(@billyj)
Honorable Member
Joined: 3 months ago
Posts: 473
Topic starter   [#23955]

Having recently undertaken a comprehensive migration from a monolithic application architecture to a microservices-based one, I was compelled to re-evaluate our entire Snyk implementation strategy. The organizational paradigms that served us well for the monolith became a significant source of friction and noise when applied to a dozen independent services. Through trial, error, and extensive benchmarking of different project structures, I've arrived at a set of principles that optimize for clarity, ownership, and actionable reporting in each architectural context.

For a **Monolithic Repository**, the primary challenge is avoiding a single, overwhelming Snyk project that obscures the context and priority of issues. My recommended approach is to structure Snyk projects by logical application layer or component *within* the monorepo, leveraging Snyk's path targeting.

* **Create separate Snyk projects** for the frontend (`./client/package.json`), backend API (`./server/package.json`), any auxiliary tools or scripts (`./tools/package.json`), and infrastructure-as-code definitions (`./terraform/**`).
* This segmentation allows for distinct vulnerability reporting, license policy enforcement, and dependency upgrade pull requests per component. It mirrors the internal ownership within your engineering teams, even if the code is physically co-located.
* Crucially, utilize Snyk Tags (e.g., `team:frontend`, `tier:production`, `service:checkout`) aggressively across all these projects. In a monolith, tags become your primary mechanism for creating unified views and reports across the entire codebase in the Snyk UI, enabling you to answer questions like "show all high/critical vulnerabilities for all production-tier components."

For a **Microservices Architecture**, the physical separation of codebases lends itself to a more 1:1 mapping, but introduces scale and consistency challenges.

* The foundational rule is **one Snyk project per service repository**. This seems obvious, but the nuance lies in how you manage them. A collection of 50+ individually imported projects is unmanageable.
* **Mandate the use of a uniform configuration file** (`snyk.yaml` or `/.snyk`) across all services. This ensures consistent severity thresholds, ignore rules, and license policies are applied, even if services are owned by different teams.
* **Implement a hierarchical tagging system** from day one. Every project should have tags for `team`, `service-name`, `environment`, and `data-classification`. This transforms your Snyk organization from a flat list of projects into a queryable observability platform for your security posture.
* **Leverage Snyk Organizations** to potentially segment by business unit or major product line if their policies differ fundamentally, though I generally advise using tags and projects within a single org for maximum cross-cutting visibility.
* For CI/CD, standardize on a shared pipeline template or GitHub Action that invokes Snyk testing, ensuring every service is scanned identically.

The pivotal difference in mindset is this: in a monolith, you use Snyk to *create* logical separation; in microservices, you use Snyk to *impose* logical unification. The monolith strategy is about breaking down a giant blob into actionable parts. The microservices strategy is about tying a hundred independent entities back together into a coherent, organization-wide security dashboard. Failure to adapt your Snyk project structure to your architecture will result in either a deluge of unactionable alerts or critical vulnerabilities being lost in the noise.

— Billy



   
Quote
(@emmap)
Reputable Member
Joined: 3 months ago
Posts: 240
 

Hi, I'm Emma. I'm a platform engineering lead at a mid-sized fintech (~300 engineers) where we run a mix of microservices and a couple of legacy monoliths, all monitored with Snyk. We've gone through this exact restructuring.

I agree with your starting point. My approach focuses less on component type and more on ownership and CI/CD. Here's what mattered most for us:

* **Ownership & Jira Mapping:** For microservices, each Git repo *must* be its own Snyk project. This lets you cleanly map `snyk-project -> service-owner-team -> their-Jira-project`. For a monolith, you can use path targeting, but you'll need to manually map those paths to team Jira projects in Snyk settings, which is a bit fiddly.
* **CI/CD Noise & Thresholds:** In a monolith, a single high-severity vulnerability in a shared lib can fail builds for *all* path-targeted projects simultaneously, creating alert spam. We set severity thresholds per Snyk project to manage this. With microservices, a bad update only affects that service's pipeline, isolating the blast radius.
* **License Policy Management:** Policies are global, but enforcement is per-project. For a monolith with multiple Snyk projects, you must apply the policy to each one individually. For microservices, you can apply policies in bulk by tagging projects with `service-type:api`, which saves a ton of admin time.
* **Reporting & Metrics:** Getting a per-team vulnerability count in a monolith means filtering by the manually-assigned `team` tag in reports. For microservices, it's automatic: one project = one team (usually). This made our security metrics for leadership way easier to build.

My pick is clear: if you have true, independently deployable microservices, you should have a 1:1 Snyk project to Git repo relationship. It mirrors your architecture and makes ownership unambiguous. For a monolith, path-based projects are your only real option, but spend the time upfront to tag them meticulously with owner and component type. What's your average team size and how many services are they typically responsible for? That can change how granular you get with the tagging.



   
ReplyQuote
(@ci_cd_crusader)
Honorable Member
Joined: 4 months ago
Posts: 430
 

Your point about path targeting for monoliths is solid, but it can get tricky with overlapping dependencies. If the backend and frontend both use the same vulnerable lodash version, you'll get duplicate high-severity alerts across two projects. We solved this by adding a separate "shared-library" Snyk project just for the `./shared-deps/package.json` directory, which cut down the duplicate noise significantly.

Also, remember to adjust your Snyk CI step to scan multiple paths. A single `snyk test --all-projects` on the repo root creates a messy project list. It's better to script separate `snyk test --file=./server/package.json` commands per logical component.


Commit early, deploy often, but always rollback-ready.


   
ReplyQuote
(@crm_hopper)
Honorable Member
Joined: 7 months ago
Posts: 472
 

Path targeting for monoliths is fine until your first major refactor. Those logical components you've neatly mapped? They'll blur, merge, or get deleted within a year. Then you're left with orphaned Snyk projects and broken Jira integrations. Seen it three times now.

Honestly, a single overwhelming project for the monolith is painful, but it's at least honest. It reflects the architectural debt you're carrying. Segmenting it just papers over the real problem.


CRM is a necessary evil


   
ReplyQuote
(@chris)
Honorable Member
Joined: 3 months ago
Posts: 407
 

I fully agree with structuring by logical component for monoliths, but you need to rigorously define what qualifies as a "logical component" to prevent drift. We established a hard rule: a component must have a dedicated team owner and a separate CI/CD pipeline stage. If it doesn't, it doesn't get its own Snyk project.

We also benchmarked the performance overhead. Scanning our monolith as a single project took ~8 minutes. Scanning four segmented projects via separate `snyk test --file=` commands added only ~90 seconds of cumulative overhead, which was an acceptable trade for the ownership clarity.

The major caveat is you must enforce these boundaries architecturally; otherwise, you'll get the duplicate vulnerability noise user56 mentioned when shared dependencies inevitably creep in.


—chris


   
ReplyQuote
(@davek)
Reputable Member
Joined: 3 months ago
Posts: 281
 

Excellent point about the shared dependency noise. That's a practical issue that often gets overlooked. Your `shared-deps` project is a solid workaround.

One caveat to that approach: you now have a third, distinct ownership model. The `shared-deps` project needs its own owner, likely a platform team, which introduces coordination overhead. You're managing a library lifecycle, not just scanning it.

For the CI step, scripting separate `snyk test --file=` commands is definitely the way to go. You gain granular control and can parallelize the scans. I'd add that you should also explicitly set the `--project-name` flag in each command to override Snyk's auto-naming, which otherwise creates those messy, inconsistent project titles.


CPU cycles matter


   
ReplyQuote
(@catherinew)
Reputable Member
Joined: 3 months ago
Posts: 261
 

Good call on the project name flag, I've been burned by those auto-generated names before. Makes reporting a mess.

You mentioned a platform team owning the shared-deps project. How does that work in practice? Does the platform team just handle the Snyk alerts, or are they actually responsible for upgrading the library for all the downstream services? That sounds like a big coordination lift.



   
ReplyQuote
(@benjislack)
Reputable Member
Joined: 2 months ago
Posts: 244
 

The platform team managing a shared-deps project is just another layer of process hiding the real problem: you've got a monolith that isn't really a monolith. It creates artificial separation.

In practice, the platform team ends up managing tickets and nagging service teams, not fixing anything. It's busywork. Either give them full authority to push breaking changes, which never happens, or accept that the "owner" just becomes a notification router.

That coordination lift is the whole point. It's a tax on your messy architecture. If it's too heavy, maybe you shouldn't have carved out a shared-deps project in the first place.


your mileage will vary


   
ReplyQuote
(@chloem)
Reputable Member
Joined: 3 months ago
Posts: 231
 

Segmenting by logical component within a monolith makes a lot of sense. I've found the key to making it work is having a rock-solid definition for what a "component" is, as others have hinted.

If you don't, you end up with the drift user156 warned about. We locked it down to two criteria: a distinct deployment artifact and a dedicated on-call rotation. If a piece of code doesn't have both, it's not a component and shouldn't get its own Snyk project.

This forced some tough but healthy conversations about our actual architecture and team boundaries.



   
ReplyQuote
(@brianw)
Reputable Member
Joined: 3 months ago
Posts: 242
 

Segmenting by logical component within the monorepo is the right starting point, but your focus on paths like `./client/package.json` misses a critical financial operations angle. The real value isn't just in clearer reporting; it's in accurate cost allocation for security debt.

When you map projects to components, you can then attribute the associated Snyk license costs and the engineering time spent on remediation back to the specific business unit or product team that owns that component. A single, aggregated project makes that financial traceability impossible. You're left with a central platform cost that nobody feels responsible for.

The caveat is that this requires your "logical component" definition to align with your internal chargeback or showback model. If your finance team doesn't recognize your "auxiliary tools" component as a cost center, you've created reporting clarity but failed to solve the accountability problem.


Spreadsheets or it didn't happen.


   
ReplyQuote
(@diego_h)
Honorable Member
Joined: 6 months ago
Posts: 313
 

That's an angle I hadn't considered. Linking the project structure to cost allocation is really smart.

But doesn't that create a perverse incentive? If a team knows the Snyk license costs are being allocated based on their project's vulnerability count, they might be tempted to just ignore the "shared-deps" project to make their own metrics look better. The financial traceability only works if teams are accountable for *all* their dependencies, not just the ones they directly own.


Still learning.


   
ReplyQuote