Skip to content

Asset model

Everything a scan discovers lands in a structured asset database. Understanding its shape is how you query a target and how you read scan results.

Targets: programs and scopes

  • A Program is a target — a bug-bounty program (e.g. a hackerone handle). It's the top of the tree.
  • A Scope is a sub-target within a program (e.g. *.acme.com), carrying its own in/out-of-scope rules. Assets attach to a program through its scopes.

There is no entity literally called "target" — in practice a target is a program, optionally narrowed to one scope.

Assets

AssetKey fieldsNotes
Domainvalue (globally unique)Hostnames.
IpAddressvalue, type (ipv4/ipv6)
Portvalue, service (http/https/null)Belongs to an IP.
HttpPathvalue, statusCode, length, toolBelongs to a domain. The richest signal.
Technologyname, categoriesDetected on an http_path or port.
Mobile / Wildcard / CidrvalueMobile apps and scope boundaries.

Assets are globally de-duplicated — one Domain row per value, no matter how many scopes reference it. The link between an asset and a scope lives in a join table (DomainScope, IpAddressScope, …). So "all domains for program X" means "domains whose scope chain leads back to X."

Program ──< Scope ──< (join) ──< Domain ──< HttpPath ──< Technology
                   ──< (join) ──< IpAddress ──< Port ──< Technology

Why http_paths are special

Each HttpPath records not just a URL but its statusCode and length and the tool that found it. For a pentester that's the first place to look: live 200s, unusual response sizes, and interesting paths are your entry points. The recon-target skill walks through using them.

Fast aggregates

Counting assets across millions of rows on every page load would be slow, so Sonar keeps materialized views (asset_scope_facts, asset_counts_agg) rebuilt on a ~15-minute cadence (so counts can lag reality by up to that long). asset_scope_facts is the denormalized "which asset belongs to which program/scope" fact table; asset_counts_agg is the rollup that powers the counts you see in get_target_overview.