Audit Events Implementation Guide | Fluid Attacks Help

Audit Events

This guide provides essential instructions for implementing audit events and preventing unenriched events in new implementations. Audit events are crucial for tracking system activities and maintaining security compliance.

🚨 Critical Requirements

Every audit event MUST include these metadata fields when applicable:

metadata: {
  organization: "organization-name",  group: "group-name",
  // ... additional context}

Event Structure

{
  action: "CREATE" | "READ" | "UPDATE" | "DELETE",                                                                               author: string,                    // Who performed the action
  date: Date,                                                                                                         
  mechanism: "API" | "WEB" | "SCHEDULER" | "TASK" | "MIGRATION" | "JIRA" | "FORCES" | "MELTS" | "RETRIEVES" | "FIXES",  metadata: Record<string, unknown>, // MUST include organization & group if applicable                                 
  object: string,                    // What was affected                                                               objectId: string                   // Unique identifier within object type scope                                     
}

Implementation Examples

TypeScript/JavaScript

import { Tracks } from "@fluidattacks/tracks";

const client = new Tracks();
client.event.create({
  action: "CREATE",
  author: "user@example.com",  
  date: new Date(),
  mechanism: "WEB",
  metadata: {
    organization: "org-name",    
    group: "group-name",    
    description: "New vulnerability created"  
  },
  object: "Vulnerability",  
  objectId: "vuln-id"
});

Python

from fluidattacks_tracks import Tracks from fluidattacks_tracks.resources.event import Event client = Tracks() client.event.create( Event( action="CREATE",
        author="user@example.com",  
        date=datetime.now(UTC),
        mechanism="WEB",
metadata={ organization: "org-name",
            group: "group-name",    
            description: "New vulnerability created"  
}, object="Vulnerability",
        objectId="vuln-id"
) )

Object Naming Convention

Tracks supports any naming convention for the object field, providing flexibility for different use cases. However, Fluid Attacks applications follow two specific naming patterns to ensure consistency across the platform:

1. Instance-Based Events

For events that reference a specific instance of a platform entity, use the entity name and include the instance ID in objectId:

object: "Vulnerability"
objectId: "vuln-id"

object: "Group"objectId: "unittesting"

object: "Group.Findings"objectId: "unittesting"

object: "Organization"objectId: "okada"

object: "Organization.Analytics.AcceptedVulnerabilitiesBySeverity"objectId: "okada"

object: "Group.Integrations.Connect.Jira"objectId: "testgroup"

2. Action-Based Events

For events that represent platform actions without a specific instance, use descriptive action names:

object: "Login"objectId: "Microsoft"
object: "Autoenroll.Welcome"objectId: "unknown"
object: "UploadGroupFile"objectId: "repo_nickname/group_name"
object: "HelpDeskMenu"objectId: "unknown"

Naming Guidelines for Fluid Attacks Applications

  1. Use PascalCase for object names.
  2. Use dots (.) for hierarchical relationships.
  3. Be descriptive but concise.
  4. Include complements for action variants when needed.
  5. Ensure objectId is unique and meaningful for the context when applicable.
  6. Follow the two patterns above for consistency across the platform.
  7. objectId must be related to the instance that starts the event name (e.g., “Group.Findings” → group name, “Organization.Analytics” → organization name/ID).
  8. objectId may use generic values like “unknown” when no specific information is relevant.

Validation Checklist

Before creating an event, verify:
  1. organization field is included in metadata (when applicable)
  2. group field is included in metadata (when applicable)
  3. object follows naming convention
  4. author is properly identified
  5. mechanism matches the context
  6. objectId is unique and meaningful
  7. Verify that no unauthorized information is captured

Common Patterns

Conditional Metadata

Use conditional inclusion when organization and group information may not always be available or applicable. This ensures metadata fields are only included when they have meaningful values.

const metadata: Record<string, unknown> = {};
if (groupName) metadata.group = groupName;
if (organizationName) metadata.organization = organizationName;

Best Practices

âś… Good Examples

// Includes all required context
metadata: {
  organization: "org-name",
  group: "group-name",  
  state: {
    source: "ANALYST",    
    status: "VULNERABLE",    
    severity: "HIGH"  }
}

// Conditional inclusion
const metadata: Record<string, unknown> = {};
if (groupName) metadata.group = groupName;
if (organizationName) metadata.organization = organizationName;

❌ Bad Examples

// Inconsistent naming
metadata: {
  org: "org-name",
  groupName: "group-name"
}

// Including undefined values
metadata: {
  group: groupName, // Could be undefined
  organization: organizationName // Could be undefined}

Idea
Tip
Have an idea to simplify our architecture or noticed docs that could use some love? Don't hesitate to open an issue or submit improvements.