Skip to content

Audit Logging

App code that touches external systems, customer data, or sensitive resources should record audit events so deployments retain a tamper-evident trail per NIST SP 800-53 SI-12 / AU-2.

The platform emits audit events for its own operations (asset CRUD, login, flow state, S3 writes, RBAC sync). App code is responsible for events the platform cannot see: external API calls, custom data reads/writes, and sensitive operations specific to your workflow.

When to call from a step

Use StoreInterface.record_audit_log() whenever you have step context. It picks up the user automatically from the flow.

from virtualitics_sdk import AuditLogEvent

class FetchSalesforceContacts(Step):
    async def run(self, flow_metadata):
        store = flow_metadata.store

        results = call_salesforce(...)

        await store.record_audit_log_async(
            AuditLogEvent.EXTERNAL_API_CALL,
            resource_id="salesforce_contacts",
            api_endpoint="https://api.salesforce.com/contacts",
            operation="read",
            records_fetched=len(results),
        )
        return Page(...)

Synchronous code in a step:

store.record_audit_log(
    AuditLogEvent.READ_ASSET,
    resource_id=asset_id,
)

When to call from outside a step

Top-level scripts, hooks, or callbacks without flow context can use the module-level helpers and supply the user identity directly.

from virtualitics_sdk import record_audit_log, AuditLogEvent

record_audit_log(
    "user@example.com",
    AuditLogEvent.EXTERNAL_API_CALL,
    resource_id="record_456",
    api_endpoint="https://api.example.com",
    operation="update",
)

Event types

Use existing AuditLogEvent enum values where they fit. The most common choices for app code:

  • EXTERNAL_API_CALL for calls to systems outside the platform.
  • READ_ASSET, CREATE_ASSET, MODIFY_ASSET, DELETE_ASSET for assets the app manages directly (rare; the platform usually emits these).
  • S3_OBJECT_WRITTEN, S3_OBJECT_DELETED for raw object-store writes the platform doesn't see (e.g., writing through a third-party SDK).

What not to include

extra_detail is shipped verbatim to the license server. Do not include:

  • Passwords, API keys, tokens, or session identifiers.
  • PII unless your deployment's data classification permits it.
  • Whole request/response bodies; summarize instead (counts, ids, status).

API

Module helpers

record_audit_log

record_audit_log(user_id: str, event: AuditLogEvent, resource_id: Optional[str] = None, **extra_detail: Any) -> None

Record an audit event outside step context.

For use within step code, prefer StoreInterface.record_audit_log() which automatically populates the user from flow context.

Do not pass credentials, tokens, or PII as extra_detail.

Parameters:

  • user_id (str) –

    User email or GUID.

  • event (AuditLogEvent) –

    An AuditLogEvent enum value. Use AuditLogEvent.EXTERNAL_API_CALL for external API interactions.

  • resource_id (Optional[str], default: None ) –

    Optional resource identifier.

  • extra_detail (Any, default: {} ) –

    EXAMPLE:

    from virtualitics_sdk import record_audit_log, AuditLogEvent  record_audit_log( "user@example.com", AuditLogEvent.EXTERNAL_API_CALL, resource_id="record_456", api_endpoint="https://api.example.com", operation="update", )

record_audit_log_async async

record_audit_log_async(user_id: str, event: AuditLogEvent, resource_id: Optional[str] = None, **extra_detail: Any) -> None

Record an audit event outside step context (async).

Do not pass credentials, tokens, or PII as extra_detail.

Parameters:

  • user_id (str) –

    User email or GUID.

  • event (AuditLogEvent) –

    An AuditLogEvent enum value.

  • resource_id (Optional[str], default: None ) –

    Optional resource identifier.

  • extra_detail (Any, default: {} ) –

    Additional metadata as key-value pairs.

Event enum

AuditLogEvent

Enum for audit log events. Each member has a value corresponding to the event name sent to the API, and a description_template for formatting the log message.