Skip to main content

Overview

The BlockEvent method blocks an event by creating a network policy rule at the specified scope. This method extracts the network destination from the event and creates a deny rule to prevent future connections to that destination.

Method Signature

func (c *Client) BlockEvent(
    ctx context.Context,
    scope types.NetworkPolicyScope,
    eventID string,
    reason string,
) (types.EventActionPerformed, error)

Parameters

ctx
context.Context
required
The context for the request. Use this for cancellation, deadlines, and request-scoped values.
scope
types.NetworkPolicyScope
required
The scope at which to create the network policy rule. Valid values:
  • types.NetworkPolicyScopeGlobal - Apply to entire project
  • types.NetworkPolicyScopeRepo - Apply to specific repository (GitHub)
  • types.NetworkPolicyScopeWorkflow - Apply to specific workflow (GitHub)
  • types.NetworkPolicyScopeCluster - Apply to Kubernetes cluster
  • types.NetworkPolicyScopeNode - Apply to specific Kubernetes node
eventID
string
required
The unique identifier of the event to block.
reason
string
required
A user-provided reason explaining why the event is being blocked. This is required for audit purposes.

Response

EventActionPerformed
object
Response containing details about the created network policy rule.

Examples

Block at Global Scope

import (
    "context"
    "fmt"
    "github.com/garnet-org/api/client"
    "github.com/garnet-org/api/types"
)

func blockEventGlobally(c *client.Client, eventID string) error {
    result, err := c.BlockEvent(
        context.Background(),
        types.NetworkPolicyScopeGlobal,
        eventID,
        "Suspicious network activity detected",
    )
    if err != nil {
        return fmt.Errorf("failed to block event: %w", err)
    }
    
    fmt.Printf("Successfully blocked event %s\n", result.EventID)
    fmt.Printf("Created rule %s in policy %s\n",
        result.NetworkPolicyRule.ID,
        result.NetworkPolicyID)
    fmt.Printf("Blocked: %s (%s)\n",
        result.NetworkPolicyRule.Value,
        result.NetworkPolicyRule.Type)
    
    return nil
}

Block at Repository Scope

func blockEventForRepo(c *client.Client, eventID string) error {
    result, err := c.BlockEvent(
        context.Background(),
        types.NetworkPolicyScopeRepo,
        eventID,
        "Malicious domain access from repository workflow",
    )
    if err != nil {
        return err
    }
    
    fmt.Printf("Blocked at repository scope\n")
    fmt.Printf("Rule ID: %s\n", result.NetworkPolicyRule.ID)
    
    return nil
}

Block at Cluster Scope

func blockEventForCluster(c *client.Client, eventID string) error {
    result, err := c.BlockEvent(
        context.Background(),
        types.NetworkPolicyScopeCluster,
        eventID,
        "Threat detected in Kubernetes cluster",
    )
    if err != nil {
        return err
    }
    
    fmt.Printf("Created cluster-scoped block rule\n")
    fmt.Printf("Destination: %s\n", result.NetworkPolicyRule.Value)
    
    return nil
}

Block with Timeout

import "time"

func blockEventWithTimeout(c *client.Client, eventID, reason string) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    result, err := c.BlockEvent(
        ctx,
        types.NetworkPolicyScopeGlobal,
        eventID,
        reason,
    )
    if err != nil {
        return err
    }
    
    fmt.Printf("Event blocked at %s\n", result.CreatedAt.Format(time.RFC3339))
    return nil
}

Block Multiple Events

func blockMultipleEvents(
    c *client.Client,
    eventIDs []string,
    scope types.NetworkPolicyScope,
    reason string,
) error {
    var blocked, failed int
    
    for _, eventID := range eventIDs {
        result, err := c.BlockEvent(
            context.Background(),
            scope,
            eventID,
            reason,
        )
        
        if err != nil {
            fmt.Printf("Failed to block %s: %v\n", eventID, err)
            failed++
            continue
        }
        
        fmt.Printf("Blocked %s: %s\n", eventID, result.NetworkPolicyRule.Value)
        blocked++
    }
    
    fmt.Printf("\nSummary: %d blocked, %d failed\n", blocked, failed)
    
    if failed > 0 {
        return fmt.Errorf("%d events failed to block", failed)
    }
    
    return nil
}

Inspect Block Details

func blockAndInspect(c *client.Client, eventID string) error {
    result, err := c.BlockEvent(
        context.Background(),
        types.NetworkPolicyScopeGlobal,
        eventID,
        "Security incident response",
    )
    if err != nil {
        return err
    }
    
    rule := result.NetworkPolicyRule
    
    fmt.Println("=== Block Details ===")
    fmt.Printf("Event ID:    %s\n", result.EventID)
    fmt.Printf("Policy ID:   %s\n", result.NetworkPolicyID)
    fmt.Printf("Rule ID:     %s\n", rule.ID)
    fmt.Printf("Rule Type:   %s\n", rule.Type)
    fmt.Printf("Blocked:     %s\n", rule.Value)
    fmt.Printf("Action:      %s\n", rule.Action)
    fmt.Printf("Created:     %s\n", result.CreatedAt.Format(time.RFC3339))
    fmt.Println("=====================")
    
    return nil
}

Error Handling

import (
    "errors"
    "strings"
)

func blockEventWithErrorHandling(
    c *client.Client,
    eventID string,
    scope types.NetworkPolicyScope,
) error {
    result, err := c.BlockEvent(
        context.Background(),
        scope,
        eventID,
        "Automated block based on threat intelligence",
    )
    
    if err != nil {
        // Check for specific error conditions
        if strings.Contains(err.Error(), "not found") {
            return errors.New("event does not exist")
        }
        
        if strings.Contains(err.Error(), "no network destination") {
            return errors.New("event has no network destination to block")
        }
        
        if strings.Contains(err.Error(), "unauthorized") {
            return errors.New("insufficient permissions to block event")
        }
        
        if strings.Contains(err.Error(), "already exists") {
            fmt.Println("Destination is already blocked")
            return nil // Not an error - already handled
        }
        
        return fmt.Errorf("unexpected error: %w", err)
    }
    
    fmt.Printf("Successfully blocked: %s\n", result.NetworkPolicyRule.Value)
    return nil
}

Conditional Blocking

import "github.com/garnet-org/jibril-ashkaal/pkg/kind"

func conditionalBlock(c *client.Client, eventID string) error {
    // First, get the event to check its type
    event, err := c.Event(context.Background(), eventID)
    if err != nil {
        return err
    }
    
    // Only block network flow and detection events
    if event.Kind != kind.KindFlows && event.Kind != kind.KindDetections {
        return fmt.Errorf("event kind %s cannot be blocked", event.Kind)
    }
    
    // Determine scope based on agent context
    scope := types.NetworkPolicyScopeGlobal
    // You could inspect event.Agent.Context to determine appropriate scope
    
    result, err := c.BlockEvent(
        context.Background(),
        scope,
        eventID,
        fmt.Sprintf("Blocking %s event from agent %s",
            event.Kind, event.Agent.Name),
    )
    
    if err != nil {
        return err
    }
    
    fmt.Printf("Blocked %s event\n", event.Kind)
    return nil
}

API Endpoint

POST /api/v1/events/{eventID}/actions/block

Request Body

The method sends the following JSON body:
{
  "action_type": "block",
  "scope": "global",
  "reason": "User-provided reason"
}

Error Responses

The method may return errors for:
  • 404 Not Found: Event does not exist
  • 400 Bad Request:
    • Event has no network destination
    • Invalid scope specified
    • Reason is empty or invalid
  • 401 Unauthorized: Missing or invalid authentication
  • 403 Forbidden: Insufficient permissions
  • 409 Conflict: Rule already exists
  • 500 Internal Server Error: Server-side error

Notes

  • The event must have a network destination (IP or domain) to be blocked
  • The reason parameter is required and used for audit trails
  • Blocking creates a deny rule in the network policy at the specified scope
  • If a rule for the destination already exists, a conflict error is returned
  • The scope determines where the block is enforced (global, repo, cluster, etc.)
  • System global scope (NetworkPolicyScopeSystemGlobal) can only be used by administrators
  • The rule type (CIDR or domain) is automatically determined from the event data
  • Network policy rules are enforced by Garnet agents in real-time

Build docs developers (and LLMs) love