Skip to main content

What is an Event?

An event in Garnet represents a specific security-related occurrence detected by an agent. Events are the raw telemetry data that power Garnet’s security monitoring, capturing everything from network flows to suspicious process executions. Events use the jibril-ashkaal format (v2), a structured event format designed for efficient security event representation.

Event Structure

type Event struct {
    ID        string       `json:"id"`
    Agent     Agent        `json:"agent"`
    Data      ongoing.Base `json:"data"`
    Kind      kind.Kind    `json:"kind"`
    CreatedAt time.Time    `json:"created_at"`
    UpdatedAt time.Time    `json:"updated_at"`
}

Core Fields

Event ID

Unique identifier for the event. Used for querying and associating events with issues.

Agent

Full agent details including context, location, and configuration.

Data

Event payload in ashkaal format containing detection details and metadata.

Kind

Event category: flows, detections, infos, or network policy events.

Event Kinds

Events are categorized into high-level kinds:
const (
    KindFlows      Kind = "flows"       // Network flow events
    KindDetections Kind = "detections"  // Security detections
    KindInfos      Kind = "infos"       // Informational events
    KindNetPolicy  Kind = "netpolicy"   // Network policy events
)

Event Types

Within each kind, events have specific types identified by metadata names:
Drop Events:
  • EventKindDropIP - IP address was blocked
  • EventKindDropDomain - Domain was blocked
  • EventKindFlow - Network flow information
Domain Access Events:
  • EventKindAdultDomainAccess - Adult content domain
  • EventKindBadwareDomainAccess - Known malicious domain
  • EventKindDynDNSDomainAccess - Dynamic DNS domain
  • EventKindFakeDomainAccess - Impersonating domain
  • EventKindGamblingDomainAccess - Gambling domain
  • EventKindPiracyDomainAccess - Piracy-related domain
  • EventKindThreatDomainAccess - Threat intelligence domain
  • EventKindTrackingDomainAccess - Tracking/analytics domain
  • EventKindVPNLikeDomainAccess - VPN/proxy domain
  • EventKindPlaintextCommunication - Unencrypted network traffic
Fingerprinting Events:
  • EventKindCPUFingerprint - CPU characteristics detection
  • EventKindFilesystemFingerprint - Filesystem enumeration
  • EventKindMachineFingerprint - Machine identification
  • EventKindOSFingerprint - OS detection
  • EventKindOSNetworkFingerprint - Network-based OS detection
  • EventKindOSStatusFingerprint - OS status enumeration
  • EventKindCapabilitiesModification - Linux capabilities changes
  • EventKindSudoersModification - Sudoers file modification
  • EventKindPAMConfigModification - PAM configuration changes
  • EventKindShellConfigModification - Shell config modification
  • EventKindPackageRepoConfigModification - Package repo tampering
  • EventKindCredentialsFilesAccess - Credential file access
  • EventKindSSLCertificateAccess - SSL certificate access
  • EventKindAuthLogsTamper - Authentication log tampering
  • EventKindEnvironReadFromProcfs - Environment variable reading
  • EventKindCodeModificationThroughProcfs - Code modification via /proc
  • EventKindBinaryExecutedByLoader - Custom loader execution
  • EventKindCodeOnTheFly - JIT/dynamic code execution
  • EventKindHiddenELFExec - Hidden binary execution
  • EventKindBinarySelfDeletion - Binary self-deletion
  • EventKindJavaDebugLibLoad - Java debug library loading
  • EventKindJavaInstrumentLibLoad - Java instrumentation
  • EventKindCryptoMinerFiles - Crypto miner files detected
  • EventKindCryptoMinerExecution - Crypto miner execution
  • EventKindDenialOfServiceTools - DoS tool usage
  • EventKindNetScanToolExec - Network scanning tool
  • EventKindNetSniffToolExec - Network sniffing tool
  • EventKindNetMITMToolExec - Man-in-the-middle tool
  • EventKindNetFilecopyToolExec - Network file copy tool
  • EventKindDataEncoderExec - Data encoding tool
  • EventKindExecFromUnusualDir - Execution from unusual directory
  • EventKindInterpreterShellSpawn - Shell spawned by interpreter
  • EventKindWebserverExec - Binary executed by webserver
  • EventKindWebserverShellExec - Shell spawned by webserver
  • EventKindRuncSuspiciousExec - Suspicious runc execution
  • EventKindNetSuspiciousToolExec - Suspicious network tool
  • EventKindNetSuspiciousToolShell - Suspicious network tool shell
  • EventKindGlobalShlibModification - Shared library modification
  • EventKindFileAttributeChange - File attribute changes
  • EventKindCorePatternAccess - Core pattern access
  • EventKindSchedDebugAccess - Scheduler debug access
  • EventKindSysrqAccess - SysRq trigger access
  • EventKindUnprivilegedBPFConfigAccess - BPF config access

Event Data Structure

Events contain rich contextual information:
type EventData struct {
    Dropped     *DroppedIP `json:"dropped,omitempty"`
    Flow        *Flow      `json:"flow,omitempty"`
    FullInfo    *FullInfo  `json:"full_info,omitempty"`
    Parent      *Process   `json:"parent,omitempty"`
    Process     *Process   `json:"process,omitempty"`
    Resolve     *string    `json:"resolve,omitempty"`
    ResolveFlow *Flow      `json:"resolve_flow,omitempty"`
    Note        *string    `json:"note,omitempty"`
    Head        *EventHead `json:"head,omitempty"`
}

Network Flow Information

type Flow struct {
    Icmp        *ICMP       `json:"icmp,omitempty"`
    IPVersion   *int        `json:"ip_version,omitempty"`
    Local       *Node       `json:"local,omitempty"`
    Proto       *string     `json:"proto,omitempty"`
    Remote      *Node       `json:"remote,omitempty"`
    ServicePort *int        `json:"service_port,omitempty"`
    Settings    *Settings   `json:"settings,omitempty"`
    Properties  *Properties `json:"properties,omitempty"`
}

type Node struct {
    Address *string   `json:"address,omitempty"`
    Name    *string   `json:"name,omitempty"`
    Names   *[]string `json:"names,omitempty"`
    Port    *int      `json:"port,omitempty"`
}
The Names array in network flows contains the DNS resolution chain from resolved IP to original domain: [IP, CNAME_N, ..., CNAME_1, original_domain]

Process Information

type Process struct {
    Args       *string    `json:"args,omitempty"`
    Cmd        *string    `json:"cmd,omitempty"`
    Comm       *string    `json:"comm,omitempty"`
    Exe        *string    `json:"exe,omitempty"`
    Exit       *string    `json:"exit,omitempty"`
    Loader     *string    `json:"loader,omitempty"`
    PID        *int       `json:"pid,omitempty"`
    PpID       *int       `json:"ppid,omitempty"`
    Start      *time.Time `json:"start,omitempty"`
    UID        *int       `json:"uid,omitempty"`
}

Ingesting Events

Agents ingest events using the V2 API:
import (
    "context"
    "github.com/garnet-org/api/client"
    "github.com/garnet-org/api/types"
)

func ingestEvent() {
    c := client.New("agent-token")
    
    event := types.CreateOrUpdateEventV2{
        // Event data in ashkaal format
    }
    
    result, err := c.IngestEventV2(context.Background(), event)
    if err != nil {
        // Handle error
    }
    
    fmt.Printf("Event ID: %s\n", result.ID)
}
Event ingestion uses PUT semantics - sending the same event twice will update rather than duplicate it.

Querying Events

Retrieve and filter events with powerful query capabilities:
func queryEvents() {
    c := client.New("your-api-key")
    
    kind := kind.KindDetections
    params := types.ListEvents{
        Filters: &types.EventFilters{
            Kind: &kind,
            MetadataNames: []string{
                "crypto_miner_execution",
                "badware_domain_access",
            },
            TimeStart: timePtr(time.Now().Add(-24 * time.Hour)),
            TimeEnd:   timePtr(time.Now()),
        },
        PageArgs: types.PageArgs{
            Page:    intPtr(1),
            PerPage: intPtr(100),
        },
        Sort: &types.Sort{
            Field: "created_at",
            Order: types.SortOrderDesc,
        },
    }
    
    page, err := c.Events(context.Background(), params)
    if err != nil {
        // Handle error
    }
    
    for _, event := range page.Data {
        fmt.Printf("Event: %s - %s\n", event.ID, event.Kind)
    }
}

Available Filters

Agent Filters

  • AgentID: Specific agent
  • Cluster: Kubernetes cluster name
  • Namespace: Kubernetes namespace
  • Node: Kubernetes node name

Event Filters

  • Kind: Event kind (flows, detections, etc.)
  • Kinds: Multiple event kinds
  • MetadataNames: Specific event types
  • TimeStart/TimeEnd: Time range

Retrieving a Single Event

Get detailed information about a specific event:
func getEvent(eventID string) {
    c := client.New("your-api-key")
    
    event, err := c.Event(context.Background(), eventID)
    if err != nil {
        // Handle error
    }
    
    fmt.Printf("Event: %s\n", event.ID)
    fmt.Printf("Agent: %s\n", event.Agent.Hostname)
    fmt.Printf("Kind: %s\n", event.Kind)
    fmt.Printf("Created: %s\n", event.CreatedAt)
}

Event Actions

Take action on events directly:

Blocking an Event

Create a network policy rule to block the destination from an event:
func blockEvent(eventID string) {
    c := client.New("your-api-key")
    
    result, err := c.BlockEvent(
        context.Background(),
        types.NetworkPolicyScopeGlobal,
        eventID,
        "Blocking known malicious domain",
    )
    if err != nil {
        // Handle error
    }
    
    fmt.Printf("Created policy rule: %s\n", result.NetworkPolicyRuleID)
}
Blocking an event automatically extracts the network destination (IP or domain) and creates an appropriate network policy rule.

Event Lifecycle

  1. Detection: Agent detects suspicious activity
  2. Ingestion: Event sent to Garnet API
  3. Processing: Event analyzed and classified
  4. Aggregation: Related events grouped into issues
  5. Action: Security team responds to issues

Event to Issue Relationship

Events are automatically grouped into Issues based on:
  • Event type and severity
  • Affected agent and context
  • Network destination patterns
  • Temporal proximity
A single issue can contain multiple related events. For example, repeated connections to a suspicious domain from the same agent will be grouped into one issue.

Best Practices

  • Use event filtering to reduce noise
  • Monitor high-severity event types closely
  • Set up alerting for critical event types
  • Review event patterns regularly
  • Use time range filters to limit query scope
  • Paginate large result sets
  • Filter by agent or context when possible
  • Use specific metadata names instead of broad kinds
  • Investigate events grouped into issues first
  • Use event context (process, flow) for analysis
  • Block at appropriate scope (global, repo, workflow)
  • Document blocking decisions in the reason field

Error Handling

Common Errors

ErrInvalidEventKind (types/event.go:14)
ErrInvalidEventKind = errs.InvalidArgumentError("invalid event kind")
Returned when the event kind is not one of the supported types. ErrIDcannotBeEmpty (types/event.go:17)
ErrIDcannotBeEmpty = errs.InvalidArgumentError("id is required")
Returned when querying an event without providing an ID. ErrInvalidEventID (types/issue.go:76)
ErrInvalidEventID = errs.InvalidArgumentError("invalid event ID")
Returned when the event ID format is invalid.
  • Agents - Components that detect and report events
  • Issues - Aggregated security concerns from events
  • Network Policies - Rules created from event actions

Build docs developers (and LLMs) love