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:
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_CALLfor calls to systems outside the platform.READ_ASSET,CREATE_ASSET,MODIFY_ASSET,DELETE_ASSETfor assets the app manages directly (rare; the platform usually emits these).S3_OBJECT_WRITTEN,S3_OBJECT_DELETEDfor 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_CALLfor 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.