A vulnerability is only as actionable as the answer to one question. Who owns the asset it lives on? In a single-team environment that answer is trivial. Everything routes to the one team that exists. In a holding group with a dozen subsidiaries, hundreds of asset groups, overlapping IP ranges and a steady churn of newly discovered hosts, that same question turns into a routing problem that has to be solved automatically, deterministically and without leaking findings across tenant lines.
This article walks through how a vulnerability management platform answers that question at scale. It uses PMAP as a concrete reference, because its behavior here is well defined. PMAP models a tenant hierarchy of holdings and subsidiaries, and it resolves asset ownership through a fixed six-branch chain that returns the first match it finds. If you are designing asset ownership for a multi-entity organization, or evaluating how a platform will behave when nobody has explicitly assigned an owner yet, the mechanics below are the part that decides whether your routing is predictable or chaotic.
This is a piece about resolution mechanics. It deliberately stays out of the role and permission matrix that governs who is allowed to do what with an asset once it is owned. That access-control layer is a separate concern, covered in its own dedicated piece on the RBAC permission matrix. Here the focus is narrower and more concrete. Given an asset that nobody has hand-assigned, which team should it route to, and why.
The Problem: Who Owns This Asset
Start with what a team actually is in this context. A team is a named group of users, security engineers, network operations staff, an application squad, that owns assets, receives finding assignments and routes tickets and notifications. When a scanner discovers a host and the platform produces findings against it, those findings need an assignee. That assignee is almost always a team rather than an individual, because teams carry the routing metadata that makes downstream automation work. A team can hold a Jira project key, a ServiceNow assignment group, a ManageEngine queue identifier and incoming webhook URLs for Slack and Microsoft Teams. Assigning a finding to a team is therefore not a label. It is the decision that determines where the ticket lands and who gets pinged.
The catch is that most assets are never hand-assigned to a team. Discovery is continuous. New hosts appear on the network faster than any analyst can curate ownership for each one. If the platform waited for a human to assign every asset before it could route a finding, the queue of unrouted findings would grow without bound and the SLA clock would tick on items nobody had been told to fix.
So the platform needs a function. Given an asset, return the team that should own it, even when no person ever said so. That function has to be deterministic, so the same asset always resolves the same way. It has to be tenant-safe, so a subsidiary’s asset never gets handed to a team in a different subsidiary. And it has to terminate, so there is always an answer rather than a dead end. PMAP implements exactly this as a priority chain with a guaranteed terminal branch. Before the chain makes sense, though, the tenant model underneath it has to be clear.
Tenant Hierarchy: Holding and Subsidiaries
PMAP’s multi-tenancy root is the company. Every tenant is a row in the companies table, whether that tenant is a holding group or one of its subsidiaries. Almost every other part of the platform, assets, projects, scans, findings, teams, treats company_id as its tenant key. That single column is the effective boundary across the whole system. When a repository lists records, it filters them to the set of company identifiers the requesting user is allowed to see. A company with no allowed companies and no platform-wide override sees nothing, because the default posture is deny.
Hierarchy rides on one nullable column. A company carries an optional parent_id that points to its holding company. A company whose parent_id is null is treated as a holding company, the root of its tree. A company whose parent_id is non-null is a subsidiary, a child of the holding it points to. There is nothing more exotic than that. The whole holding-and-subsidiary structure is expressed as a self-referencing foreign key, and the platform reads it through a helper that lists the direct children of any given company.
This matters for ownership because ownership questions are nearly always asked inside the context of a tenant. When the resolver needs a fallback owner or a company default, it looks them up against the asset’s own company. When a team is allowed to span more than one entity, the set of entities it can reach is derived from this same parent-child structure. The hierarchy is not decoration. It is the coordinate system that every ownership lookup runs inside.
Why Self-Parenting Is Blocked
A self-referencing parent column invites one obvious failure. What stops a company from pointing its parent_id at its own identifier and becoming its own parent? PMAP blocks this at the service layer. When an update request tries to set a company’s parent to its own id, the service rejects it before the write ever reaches the database. The reason is structural integrity. A company that is its own parent would create a one-node cycle, and any logic that walks the tree upward or enumerates children would have to special-case it. By refusing the write up front, the platform keeps the hierarchy a clean tree with well-defined roots and leaves.
The same defensive instinct shows up elsewhere in the hierarchy logic. Listing the subsidiaries of a parent first checks that the parent actually exists, returning a not-found result rather than an empty list when the parent id is bogus. These are small guards, but together they keep the tree honest, and a clean tree is what lets the resolver reason about scope without ambiguity.
Subsidiary Roll-Up Without Crossing Lines
A holding-group security function usually wants two things that pull in opposite directions. It wants a roll-up view, so leadership can see posture across every subsidiary at once. And it wants strict separation, so one subsidiary’s operators cannot see or touch another’s assets. The tenant model supports both because the boundary and the roll-up are expressed through the same structure rather than fighting each other.
The boundary comes from company_id filtering. Every list query a repository runs is constrained to the set of companies the caller is entitled to. The roll-up comes from how that allowed set is built. A platform administrator or a multi-tenant operator can be entitled to a holding plus all of its children, which lets them see the whole tree. A subsidiary-scoped operator is entitled only to their own company, which keeps them inside their lane. Crucially, the asset itself never changes tenant. An asset belongs to exactly one company, and resolution always runs against that company. So even when a person can see across the tree, the ownership of any single asset stays anchored to its own subsidiary. That anchoring is the property the resolver depends on to stay tenant-safe.
Team Scope Modes Across the Tree
Teams are not always confined to a single company. The reason is practical. A central security operations group in a holding company often owns assets that physically live inside several subsidiaries. To support this without forcing one team per entity, PMAP gives every team a scope mode that controls which companies it can own assets across.
There are three modes. The default is company, where a team operates within its own company_id only. This is the right setting for a team that belongs to a single subsidiary and never reaches outside it. The second mode is multi_company, where the team is bound to an explicit list of subsidiary identifiers held in a separate scope table. This fits a shared services team that covers a curated handful of entities but not the entire group. The third mode is all_subsidiaries, where the team operates across the company’s entire recursive child hierarchy. This is the mode for a true holding-wide function that should reach every entity under the root.
Scope mode and the resolution chain are complementary. Scope mode answers the eligibility question, which companies a team is even allowed to own assets in. The resolution chain answers the selection question, which eligible team actually gets a given asset. A team set to company scope will never be selected for an asset in a sibling subsidiary, no matter how the chain runs, because it is not eligible there. So the scope mode is the first quiet filter on the whole process, and the six branches operate inside whatever eligibility it permits.
The Six-Branch Owner Resolution Chain
Now the core mechanism. When an asset has no explicit owner and the platform needs one, the owner resolver walks a fixed priority chain of six branches. It evaluates them in order and returns on the first branch that yields a team. Higher branches express stronger, more specific signals of intent. Lower branches are progressively broader fallbacks. The last branch is guaranteed to produce an answer, so the chain can never fail to terminate.
The ordering is the whole design. Explicit human intent beats automated inference. A precise network match beats a broad organizational default. And a guaranteed queue catches everything that falls through. Reading the chain top to bottom is reading a statement of which signals the platform trusts most. The six branches, in order, are explicit ownership, group default, IP scope, tag rule, company default and the fallback queue. Each carries a resolution method label so that anyone reading a resolved owner later can see exactly which branch produced it.
Branch 1, Explicit Ownership
The first and strongest branch is explicit ownership. If a human or a prior process has directly attached the asset to a team, that assignment wins outright and the chain stops. PMAP records explicit ownership through a polymorphic junction table that links assets to owners, and it also honors legacy owner columns kept for backward compatibility. Either source counts as explicit.
The reason this branch sits at the top is intent. When someone has gone to the trouble of saying this team owns this asset, no inferred signal should override that decision. The resolution method recorded for this branch is explicit, which gives downstream readers an unambiguous marker that a deliberate assignment, not a guess, decided the owner. Everything below this branch only runs when nobody made that deliberate choice.
Branch 2, Group Default
If there is no explicit owner, the resolver looks at asset groups. Assets can belong to groups, and a group can carry a default owner team. When the asset belongs to a group that names a default owner, that team is selected and the chain stops with the resolution method group_default.
The intent signal here is weaker than an explicit per-asset assignment but still meaningful. Someone curated a group and declared who looks after it, so any asset that joins the group inherits that ownership by default. There is one practical wrinkle worth knowing. The group-default branch is skipped during bulk resolution batches for performance, because evaluating group membership for every unowned asset at once is expensive. In the normal per-asset flow it participates fully, but the bulk path leans on the cheaper branches below it. This is a deliberate trade between completeness and throughput on a mass operation.
Branch 3, IP Scope and CIDR
When neither explicit nor group ownership applies, the resolver turns to the network. Locations within a company can carry IP CIDR scopes, and those scopes can be associated with an owner team. If the asset has at least one IP address that falls inside a location’s CIDR, the matching team is selected with the resolution method location_cidr.
The interesting part is conflict handling. An asset’s address might fall inside more than one configured CIDR, for example a broad 10.0.0.0/8 and a narrower 10.4.2.0/24 that both contain it. The resolver picks the most specific match, the one with the longest prefix length. Longest-prefix-wins is the same rule routers use, and it is the right one here. The narrower a CIDR is, the more deliberately someone carved it out, so the more specific scope reflects a more precise ownership statement. This branch lets an organization express ownership by network topology, which is powerful when subnets already map cleanly to teams.
Branch 4, Tag-Based Rule
The fourth branch is tag-based ownership. The intent is to let an asset’s tags drive ownership through a configured mapping from a tag to a team, so that labeling an asset a certain way would automatically route it. In PMAP this branch is reserved. It has a defined place in the chain and a resolution method name, tag_rule, but the underlying mapping table is not yet implemented.
It earns a mention rather than silence for two reasons. First, honesty about the chain. The position exists, so anyone reading the resolution order should know what sits at slot four and that it is presently a pass-through. Second, design intent. The fact that tag-based routing has a reserved slot between network matching and the organizational default tells you where it is meant to land in priority, more specific than a company-wide default but less specific than an explicit network carve-out. For now, an asset that reaches this branch simply falls through to the next one.
Branch 5, Company Default
If nothing more specific has matched, the resolver falls back to the company itself. A company can name a default owner team, and that default is set deliberately through a dedicated endpoint. When the asset’s company has a default owner team configured, that team is selected with the resolution method company_default.
This is the broadest branch that still reflects a human choice. Somebody decided that, absent any more specific signal, this is the team that should pick up assets in this entity. In a multi-entity organization the company default is also the natural place where the tenant boundary expresses itself in ownership. Because resolution runs against the asset’s own company, the company default that gets consulted is always that subsidiary’s own default, never a sibling’s. So even this catch-most branch stays inside the tenant lines.
Branch 6, Fallback SecOps Queue
The final branch guarantees an answer. If every branch above has yielded nothing, the resolver routes the asset to a per-company fallback queue, recorded with the resolution method fallback. PMAP creates this queue automatically. When the chain reaches the bottom and no default exists, the platform ensures a per-company SecOps default queue team exists and assigns the asset to it.
Two properties make this safe. The queue is created per company, so a holding’s fallback assets and a subsidiary’s fallback assets land in separate, tenant-correct queues rather than a shared bucket that would cross lines. And the creation is idempotent, guarded by an advisory lock so that concurrent resolutions racing to create the same company’s queue produce exactly one queue rather than duplicates. The practical effect is that no asset is ever orphaned. Whatever falls through every more-specific branch still ends up somewhere a human can find it, in the right tenant, ready to be triaged or reassigned. A guaranteed terminal branch is what turns the chain from a best-effort heuristic into a function that always returns.
Picking the Primary Owner When Several Match
A branch can produce more than one owner. The most common case is explicit ownership, where several rows in the owners junction attach multiple teams or users to a single asset. Notifications can fan out to all of them, but some downstream actions, ITSM ticket routing in particular, need exactly one destination. So the resolver distinguishes between the full set of effective owners and the single primary owner.
When multiple explicit owners exist, the primary is chosen by a clear rule. The resolver takes the first owner whose notify flag is set, preferring teams over individual users. The preference for teams is not arbitrary. Teams are the entities that carry ITSM routing keys and webhook URLs, so picking a team as primary keeps automated ticket assignment deterministic and gives it the metadata it needs. An individual user, by contrast, has no Jira project key or assignment group attached.
This is also where two related resolution paths diverge. One path returns the single primary owner reference, used for ITSM ticket routing where there can be only one destination. The other returns the full list of effective owners filtered by their notify flags, which is the canonical entry point for assigning a finding or issue, where several teams may legitimately need to know. Both walk the same six-branch chain. The multi-owner path only has extra work to do at branch one, where explicit assignments can be plural. For branches two through six the answer is a single team, so the multi-owner result is simply that one team wrapped as a one-element list. The chain is shared. Only the shape of the answer differs.
How Routing Stays Tenant-Safe
Everything above only holds value if it cannot leak across tenants. A resolver that occasionally handed a subsidiary’s asset to another subsidiary’s team would be worse than no resolver at all, because the failure would be silent and the wrong people would receive sensitive findings. PMAP enforces tenant safety at the point where an asset and a team are linked.
The guard is a company-match check. When an asset is attached to a team, the platform verifies that the asset and the team belong to the same company. If they do not, the link is rejected with a dedicated mismatch error rather than being written. That single check is what stops a cross-tenant assignment from ever being persisted, whether the assignment comes from a human action or from automated resolution. Combined with the fact that resolution always runs against the asset’s own company, and that company-default and fallback branches consult only that company’s records, the result is a routing system that cannot quietly cross lines.
The access controls around teams reinforce this from another angle. Team listings and activity logs are scoped so that an operator can only enumerate teams and audit history within companies they belong to. Cross-company enumeration is blocked, which prevents one tenant from even discovering the team structure of another. Scope mode adds the eligibility filter discussed earlier, so a single-company team is never a candidate outside its company in the first place. The tenant boundary is therefore not one feature but a property that several mechanisms maintain together, from the company_id filter on every query, to the scope mode on every team, to the mismatch check on every link. For the wider picture of how this boundary shapes a vulnerability program across many entities, the pillar guide to multi-tenant vulnerability management sets the context that this resolution chain plugs into.
A note on where this fits the broader platform. Owner resolution decides routing. It does not decide permission. Once an asset has an owner, what a given user is allowed to do with it, view it, update it, export it, approve a change, is governed by a separate scoped access model. That model, including its entity-and-action permission matrix and its scope types, is covered on its own in the RBAC permission matrix piece. The clean separation is deliberate. Resolution answers who should act. Access control answers who may act. Keeping them apart is what lets each one stay simple.
Why the Chain Order Is the Real Design
It is worth stepping back to see why a six-branch ordered chain, rather than a single rule or a scoring system, is the right shape for this problem. Asset ownership in a large organization is governed by signals of very different strength. A direct human assignment is a strong signal. A network subnet that happens to contain the asset is a weaker, more circumstantial one. A company-wide default is weaker still. A scoring system that blended these would produce results that are hard to explain and hard to trust, because nobody could say with confidence why a particular asset landed where it did.
An ordered chain that returns on first match avoids that entirely. Every resolved owner carries the resolution method that produced it, so the answer to why this team comes for free. The method label is the explanation. It says this asset was assigned explicitly, or matched a CIDR, or fell to the company default, or hit the fallback queue. That transparency is what makes the system auditable and what lets an operator reason about routing without reverse-engineering a weighted formula. In a domain where the wrong routing decision sends sensitive findings to the wrong people, an explainable answer beats a clever one.
The ordering also encodes a sensible governance default. By placing explicit assignment at the top and the guaranteed queue at the bottom, the chain rewards deliberate curation while never punishing its absence with an orphaned asset. Teams that invest in explicit ownership, asset groups and network scopes get precise routing. Teams that have not gotten there yet still get every asset routed to a real, tenant-correct queue. The chain meets an organization wherever it is on its ownership maturity curve, which is exactly what a multi-tenant platform serving many differently-organized entities needs to do.
Putting It Together
For an architect designing asset ownership across a holding group, the practical takeaways are concrete. Model your structure with a holding company at the root and subsidiaries hanging off it through the parent relationship, knowing the platform will keep that tree clean by refusing self-parenting and verifying parents exist. Decide each team’s reach with a scope mode, single company, a curated set of subsidiaries, or the whole tree, because that eligibility filter runs before any branch does. Then invest in the branches that match how your organization actually thinks about ownership. If subnets map to teams, lean on IP scopes. If you organize by asset group, set group defaults. Always set a company default per subsidiary, so most assets resolve to a deliberate human choice rather than to the queue. And trust the fallback to catch the rest in the correct tenant.
The deeper point is that owner resolution is where a multi-tenant vulnerability platform earns its keep or fails quietly. Get it right and findings route themselves to the correct team, in the correct entity, with an explanation attached, the moment they are discovered. Get it wrong and sensitive work either piles up unrouted or, worse, crosses tenant lines. PMAP’s answer is a fixed six-branch chain that prefers human intent, falls back through progressively broader signals, guarantees a tenant-correct terminal queue and refuses to ever link an asset to a team in the wrong company. That combination is what makes automatic ownership safe enough to rely on.
To see how this resolution behavior is packaged alongside the identity and tenancy model it lives in, read the identity and multi-tenancy datasheet and see how PMAP resolves the right owner across every subsidiary.
Frequently Asked Questions
What is the difference between a holding and a subsidiary tenant?
It comes down to one column. Every tenant is a row in the companies table, and each row carries an optional parent reference. A company with a null parent is treated as a holding company, the root of its tree. A company with a non-null parent is a subsidiary, a child of the holding it points to. The whole hierarchy is that single self-referencing relationship, and the platform reads it by listing the direct children of any company.
What happens when no owner is explicitly assigned to an asset?
The owner resolver walks a fixed six-branch chain and returns the first match. It checks explicit ownership, then an asset group default, then an IP CIDR scope, then a tag rule, then the company default, and finally a guaranteed fallback queue. If every more-specific branch yields nothing, the asset routes to a per-company SecOps fallback queue that the platform creates automatically. No asset is ever left without an owner.
How does IP-based ownership resolve conflicts when an address matches several CIDRs?
The most specific match wins. If an asset’s address falls inside more than one configured CIDR scope, the resolver selects the one with the longest prefix length. This is the same longest-prefix-match rule that network routers use. A narrower CIDR reflects a more deliberate ownership carve-out, so the more specific scope is treated as the more authoritative ownership statement.
Can a single team own assets across multiple subsidiaries?
Yes, through scope modes. A team in the default company mode operates within its own company only. A team in multi_company mode is bound to an explicit list of subsidiary identifiers. A team in all_subsidiaries mode operates across the company’s entire recursive child hierarchy. Scope mode controls eligibility, which companies a team can own assets in, before the resolution chain ever selects it for a specific asset.
Why is a team chosen as the primary owner over an individual user when both are assigned?
When several explicit owners exist, the resolver takes the first owner whose notify flag is set and prefers teams over individual users. Teams carry the routing metadata that downstream automation needs, such as a Jira project key, a ServiceNow assignment group and webhook URLs. Choosing a team as the single primary owner keeps ITSM ticket routing deterministic, because the destination has the keys it needs attached.
How does owner resolution avoid leaking findings across tenants?
Several mechanisms maintain the boundary together. Resolution always runs against the asset’s own company, so company-default and fallback lookups only ever consult that tenant’s records. When an asset is linked to a team, the platform verifies both belong to the same company and rejects the link with a mismatch error if they do not. Scope mode prevents a single-company team from being a candidate elsewhere. And every list query is filtered to the companies the caller is entitled to see.
Does owner resolution control what users are allowed to do with an asset?
No. Owner resolution decides routing, which team an asset and its findings should go to. It does not decide permission. What a user may view, update, export or approve on an asset is governed by a separate scoped access-control model with its own entity-and-action permission matrix. That access layer is covered in the dedicated piece on the RBAC permission matrix. Resolution answers who should act, while access control answers who may act.