Skip to content

Use Cases & Examples

This page demonstrates practical usage scenarios for the Open Asset Model. It covers asset creation, relationship validation, data serialization, and integration patterns with discovery tools like OWASP Amass. These examples illustrate how the model serves as a specification for building asset graphs with enforced integrity constraints.


Asset Creation and Validation

The primary workflow involves creating asset instances that implement the Asset interface. Each asset must provide three methods: Key() for unique identification, AssetType() for type classification, and JSON() for serialization.

Asset Type Classification

The model defines 21 asset type constants that enable type-safe routing and validation. When an asset is created, its AssetType() method returns one of these constants, allowing validation functions to query the relationship taxonomy.

Asset Category Types Use Case
Network Infrastructure FQDN, IPAddress, Netblock, AutonomousSystem Internet reconnaissance
Organizational Organization, Person, Location, Phone, ContactRecord Entity attribution
Digital Artifacts File, URL, Service, TLSCertificate Web infrastructure
Registration Records DomainRecord, AutnumRecord, IPNetRecord WHOIS/RDAP data
Financial Account, FundsTransfer Transaction tracking
Identity Identifier Universal identifiers (LEI, DUNS, etc.)
Product Product, ProductRelease Technology inventory

Workflow: Creating and Identifying Assets

graph TD
    Start["Discovery Tool Creates Asset"]
    Instantiate["Instantiate Concrete Type<br/>(e.g., File, FQDN, IPAddress)"]
    SetFields["Set Required Fields<br/>(URL, Name, Type, etc.)"]
    GetKey["Call Key() Method"]
    KeyReturned["Unique Key String Returned"]
    GetType["Call AssetType() Method"]
    TypeReturned["AssetType Constant Returned<br/>(e.g., model.FQDN)"]
    Store["Store in Asset Graph/Database"]

    Start --> Instantiate
    Instantiate --> SetFields
    SetFields --> GetKey
    GetKey --> KeyReturned
    KeyReturned --> GetType
    GetType --> TypeReturned
    TypeReturned --> Store

Relationship Validation Workflows

The relationship system enforces which connections are valid between asset types through the ValidRelationship function. This prevents invalid graph edges from being created.

Core Validation Functions

Three primary functions enable relationship validation and discovery:

Function Parameters Return Value Use Case
GetAssetOutgoingRelations subject AssetType []string (labels) Discover valid outgoing labels for asset type
GetTransformAssetTypes subject AssetType, label string, rtype RelationType []AssetType Get valid destination types for specific relationship
ValidRelationship src AssetType, label string, rtype RelationType, destination AssetType bool Validate specific relationship instance

Relationship Validation Decision Tree

graph TD
    Start["Validate Relationship Request"]
    CallValid["ValidRelationship(src, label, rtype, dest)"]
    CallTransform["GetTransformAssetTypes(src, label, rtype)"]
    LookupRelations["assetTypeRelations(src)"]
    CheckExists["relations[label][rtype] exists?"]
    GetTypes["Extract []AssetType from map"]
    CheckDest["destination in []AssetType?"]
    ReturnTrue["Return true"]
    ReturnFalse["Return false"]

    Start --> CallValid
    CallValid --> CallTransform
    CallTransform --> LookupRelations
    LookupRelations --> CheckExists
    CheckExists -->|No| ReturnFalse
    CheckExists -->|Yes| GetTypes
    GetTypes --> CheckDest
    CheckDest -->|Yes| ReturnTrue
    CheckDest -->|No| ReturnFalse

DNS Resolution Example

This example demonstrates a complete workflow for validating DNS A record relationships between FQDN and IPAddress assets.

DNS A Record Validation Workflow

sequenceDiagram
    participant Tool as "Discovery Tool"
    participant API as "Validation API"
    participant Taxonomy as "fqdnRels Map"

    Tool->>Tool: "Resolve owasp.org DNS A record"
    Tool->>Tool: "Found IP: 104.21.34.12"

    Note over Tool: "Create Asset Instances"
    Tool->>Tool: "fqdn = FQDN{Name: 'owasp.org'}"
    Tool->>Tool: "ip = IPAddress{Address: '104.21.34.12'}"

    Note over Tool: "Validate Before Storing"
    Tool->>API: "ValidRelationship(FQDN, 'dns_record', BasicDNSRelation, IPAddress)"
    API->>Taxonomy: "assetTypeRelations(FQDN)"
    Taxonomy-->>API: "fqdnRels map"
    API->>Taxonomy: "fqdnRels['dns_record'][BasicDNSRelation]"
    Taxonomy-->>API: "[FQDN, IPAddress]"
    API->>API: "IPAddress in [FQDN, IPAddress]?"
    API-->>Tool: "true"

    Tool->>Tool: "Store relationship: owasp.org --dns_record(A)--> 104.21.34.12"

Invalid relationship example

Attempting ValidRelationship(FQDN, "dns_record", BasicDNSRelation, Organization) returns false because Organization is not in the fqdnRels["dns_record"][BasicDNSRelation] allowed types ([FQDN, IPAddress]).


Data Serialization and Transport

All assets implement the JSON() method for serialization, enabling data exchange between discovery tools and storage systems.

graph LR
    Discovery["Discovery Tool<br/>(OWASP Amass)"]
    Asset["Asset Instance<br/>(FQDN, IPAddress, etc.)"]
    JSON["JSON Bytes"]
    Transport["Network/File Transport"]
    Store["Storage System<br/>(Database, Graph DB)"]
    Consumer["Consumer Tool<br/>(Visualization, Analysis)"]

    Discovery --> Asset
    Asset -->|"JSON()"| JSON
    JSON --> Transport
    Transport --> Store
    Store --> Consumer

Multi-Asset Discovery Pipeline

This example shows a complete discovery pipeline that validates relationships as assets are discovered.

Discovery Statistics Example

Metric Count
Assets Created 847
FQDN Assets 312
IPAddress Assets 156
Relationships Validated 1,203
Valid Relationships Stored 1,189
Invalid Relationships Rejected 14

WHOIS / Registration Data Integration

The model supports comprehensive WHOIS/RDAP data through registration record assets and contact records.

graph TB
    Domain["FQDN Asset<br/>'example.com'"]
    Registration["DomainRecord Asset<br/>Created/Updated/Expiry Dates"]
    Registrar["ContactRecord<br/>(Registrar Contact)"]
    Admin["ContactRecord<br/>(Admin Contact)"]
    Tech["ContactRecord<br/>(Technical Contact)"]
    Org["Organization Asset<br/>'Example Corp'"]
    Person["Person Asset<br/>'John Doe'"]
    Location["Location Asset<br/>'123 Main St, City, State'"]
    Phone["Phone Asset<br/>'+1-555-0123'"]
    NS1["FQDN Asset<br/>'ns1.example.com'"]
    NS2["FQDN Asset<br/>'ns2.example.com'"]

    Domain -->|"registration<br/>(SimpleRelation)"| Registration
    Registration -->|"registrar_contact<br/>(SimpleRelation)"| Registrar
    Registration -->|"admin_contact<br/>(SimpleRelation)"| Admin
    Registration -->|"technical_contact<br/>(SimpleRelation)"| Tech
    Registration -->|"name_server<br/>(SimpleRelation)"| NS1
    Registration -->|"name_server<br/>(SimpleRelation)"| NS2

    Admin -->|"organization<br/>(SimpleRelation)"| Org
    Admin -->|"person<br/>(SimpleRelation)"| Person
    Admin -->|"location<br/>(SimpleRelation)"| Location
    Admin -->|"phone<br/>(SimpleRelation)"| Phone

WHOIS Relationship Taxonomy

Valid relationships for DomainRecord assets:

Label RelationType Destination AssetType
name_server SimpleRelation FQDN
whois_server SimpleRelation FQDN
registrar_contact SimpleRelation ContactRecord
registrant_contact SimpleRelation ContactRecord
admin_contact SimpleRelation ContactRecord
technical_contact SimpleRelation ContactRecord
billing_contact SimpleRelation ContactRecord

TLS Certificate Discovery

Certificate discovery creates interconnected asset graphs spanning multiple domains, organizations, and IP addresses.

sequenceDiagram
    participant Scanner as "TLS Scanner"
    participant IP as "IPAddress Asset"
    participant Service as "Service Asset"
    participant Cert as "TLSCertificate Asset"
    participant FQDN as "FQDN Assets"
    participant Org as "Organization Asset"
    participant Validator as "ValidRelationship"

    Scanner->>IP: "Scan 104.21.34.12:443"
    Scanner->>Service: "Create Service{Port: 443, Protocol: 'TCP'}"
    Scanner->>Validator: "ValidRelationship(IPAddress, 'port', PortRelation, Service)"
    Validator-->>Scanner: "true"
    Scanner->>Scanner: "Store: IP --port--> Service"

    Scanner->>Cert: "Extract TLS Certificate"
    Scanner->>Cert: "TLSCertificate{CommonName: '*.owasp.org', ...}"
    Scanner->>Validator: "ValidRelationship(Service, 'certificate', SimpleRelation, TLSCertificate)"
    Validator-->>Scanner: "true"
    Scanner->>Scanner: "Store: Service --certificate--> Cert"

    Scanner->>FQDN: "Create FQDN{Name: '*.owasp.org'}"
    Scanner->>Validator: "ValidRelationship(TLSCertificate, 'common_name', SimpleRelation, FQDN)"
    Validator-->>Scanner: "true"
    Scanner->>Scanner: "Store: Cert --common_name--> FQDN"

    Scanner->>FQDN: "Create FQDN{Name: 'owasp.org'} (SAN)"
    Scanner->>Validator: "ValidRelationship(TLSCertificate, 'san_dns_name', SimpleRelation, FQDN)"
    Validator-->>Scanner: "true"
    Scanner->>Scanner: "Store: Cert --san_dns_name--> FQDN"

    Scanner->>Org: "Create Organization{OrgName: 'OWASP Foundation'}"
    Scanner->>Validator: "ValidRelationship(TLSCertificate, 'subject_contact', SimpleRelation, ContactRecord)"
    Validator-->>Scanner: "true (via ContactRecord)"
    Scanner->>Scanner: "Store: Cert --subject_contact--> ContactRecord --organization--> Org"

Certificate Relationship Taxonomy

TLSCertificate supports 10 outgoing relationship labels:

Label Destination Types Example
common_name FQDN *.example.com
san_dns_name FQDN www.example.com, api.example.com
san_email_address Identifier admin@example.com
san_ip_address IPAddress 192.0.2.1
san_url URL https://example.com
subject_contact ContactRecord Subject organization details
issuer_contact ContactRecord CA organization details
issuing_certificate TLSCertificate Parent certificate in chain
issuing_certificate_url URL CA certificate URL
ocsp_server URL OCSP responder endpoint

Integration with OWASP Amass

OWASP Amass uses the Open Asset Model as its internal data structure and export format.

graph TB
    subgraph "OWASP Amass"
        Seeds["Seed Domains<br/>(Configuration)"]
        Enum["Enumeration Engine"]
        Sources["Data Sources<br/>(DNS, APIs, Web Scraping)"]
    end

    subgraph "Open Asset Model Integration"
        CreateAssets["Asset Factory<br/>Creates FQDN, IPAddress, etc."]
        Validate["ValidRelationship<br/>Checks Taxonomy"]
        Store["Asset Graph<br/>(In-Memory/Database)"]
    end

    subgraph "Outputs"
        JSON["JSON Export<br/>asset.JSON()"]
        Graph["Graph Export<br/>(Neo4j, etc.)"]
        Report["Text Reports"]
    end

    Seeds --> Enum
    Enum --> Sources
    Sources --> CreateAssets
    CreateAssets --> Validate
    Validate -->|"Valid"| Store
    Validate -->|"Invalid"| CreateAssets
    Store --> JSON
    Store --> Graph
    Store --> Report

Common Patterns and Anti-Patterns

Pattern: Query Before Creating Relationships

1. Create source asset (e.g., FQDN)
2. Call GetAssetOutgoingRelations(FQDN) to discover valid labels
3. For each label, call GetTransformAssetTypes(FQDN, label, rtype)
4. Create destination assets only if types match expected discovery
5. Validate with ValidRelationship before storing

Pattern: Interface Compliance Testing

func TestAssetInterface(t *testing.T) {
    var _ model.Asset = File{}       // Value receiver check
    var _ model.Asset = (*File)(nil) // Pointer receiver check
}

Pattern: Batch Validation

1. Collect discovered relationships in memory
2. Batch validate using ValidRelationship
3. Filter invalid relationships (log for debugging)
4. Bulk insert valid relationships to storage
5. Generate validation statistics

Pattern: Relationship Label Discovery

// Given an Organization asset, discover what relationships can be created:

labels := GetAssetOutgoingRelations(Organization)
// Returns: ["id", "location", "parent", "subsidiary", "sister",
//           "account", "website", "social_media_profile", "funding_source"]

// For each label, query valid destination types:
destTypes := GetTransformAssetTypes(Organization, "location", SimpleRelation)
// Returns: [Location]

Anti-Pattern: Skipping Validation

Never skip validation

Assuming a relationship is valid and storing directly to the database creates invalid graph structures that break queries and analysis.


Summary

Use Case Primary Functions Output
Asset Creation Key(), AssetType(), JSON() Unique, typed, serializable assets
Relationship Validation ValidRelationship() Boolean validation result
Discovery Planning GetAssetOutgoingRelations(), GetTransformAssetTypes() Valid labels and destination types
Data Transport JSON() Portable asset data
Graph Construction All validation functions + storage Valid, queryable asset graph