Audit logging in Geode provides comprehensive tracking of all database operations, creating an immutable record of who accessed what data, when they accessed it, and what changes were made. This capability is essential for security monitoring, regulatory compliance, forensic analysis, incident response, and operational troubleshooting.
Audit Logging Overview
Geode’s audit system captures detailed information about every database interaction:
- Authentication Events: Login attempts, failures, session management
- Authorization Events: Permission checks, access grants and denials
- Data Access: All read operations with query details and result metadata
- Data Modifications: CREATE, UPDATE, DELETE operations with before/after values
- Schema Changes: Graph definitions, constraints, indexes, policies
- Administrative Actions: User management, configuration changes, maintenance
- System Events: Startup, shutdown, errors, resource exhaustion
Audit Event Structure
Every audit event contains:
{
"event_id": "evt_2026012810152345678",
"timestamp": "2026-01-28T10:15:23.456789Z",
"event_type": "data_access",
"severity": "info",
"actor": {
"user_id": "[email protected]",
"session_id": "sess_abc123def456",
"roles": ["analyst", "viewer"],
"ip_address": "192.168.1.100",
"user_agent": "geode-client-python/0.1.3"
},
"operation": {
"type": "SELECT",
"query": "MATCH (c:Customer) WHERE c.region = $region RETURN c.name, c.email",
"parameters": {"region": "EMEA"},
"graph": "production",
"duration_ms": 45,
"rows_returned": 127,
"bytes_transferred": 8192
},
"result": {
"status": "success",
"error_code": null,
"error_message": null
},
"context": {
"transaction_id": "txn_xyz789",
"request_id": "req_abc123",
"correlation_id": "corr_456def"
}
}
Enabling Audit Logging
Command Line Configuration
# Enable comprehensive audit logging
geode serve --audit-enabled=true \
--audit-log-level=comprehensive \
--audit-log-file=/var/log/geode/audit.log \
--audit-log-format=json
# Enable specific event types only
geode serve --audit-enabled=true \
--audit-events=authentication,authorization,data_modification,admin
# Configure log rotation
geode serve --audit-log-max-size=100MB \
--audit-log-max-files=30 \
--audit-log-compress=true
Configuration File
# geode.yaml
audit:
enabled: true
level: comprehensive # minimal, security, compliance, comprehensive
# Event types to log
events:
authentication: true
authorization: true
data_access: true
data_modification: true
schema_changes: true
admin_actions: true
system_events: true
# Output configuration
output:
file:
path: /var/log/geode/audit.log
format: json # json, syslog, cef
rotation:
max_size: 100MB
max_files: 30
compress: true
# Optional: Stream to external system
stream:
enabled: true
endpoint: "https://siem.example.com/collect"
batch_size: 100
flush_interval: 5s
# Data handling
include_query_parameters: true
include_result_data: false # Avoid logging sensitive data
include_before_after: true # For modifications
mask_sensitive_fields:
- password
- ssn
- credit_card
# Retention
retention_days: 2555 # 7 years for compliance
Audit Log Levels
Minimal Level
Logs only critical security events:
audit:
level: minimal
# Logs:
# - Authentication failures
# - Authorization denials
# - Administrative actions
# - System errors
Security Level
Logs all security-relevant events:
audit:
level: security
# Logs:
# - All authentication events
# - All authorization events
# - Permission changes
# - User management
# - Configuration changes
Compliance Level
Logs events required for regulatory compliance:
audit:
level: compliance
# Logs:
# - All data access (who accessed what)
# - All data modifications (what changed)
# - Exports and data transfers
# - Schema changes
# - Plus all security events
Comprehensive Level
Logs everything:
audit:
level: comprehensive
# Logs:
# - Every query executed
# - Every connection made
# - All internal operations
# - Performance metrics
# - Plus all compliance events
Event Types
Authentication Events
{
"event_type": "authentication",
"subtype": "login_success",
"actor": {
"user_id": "[email protected]",
"ip_address": "192.168.1.100",
"auth_method": "password"
},
"details": {
"mfa_used": true,
"mfa_method": "totp",
"session_duration": 3600
}
}
Authentication subtypes:
login_success- Successful loginlogin_failure- Failed login attemptlogout- User logoutsession_expired- Session timeoutmfa_challenge- MFA initiatedmfa_success- MFA passedmfa_failure- MFA failedtoken_issued- API token createdtoken_revoked- API token revoked
Authorization Events
{
"event_type": "authorization",
"subtype": "access_denied",
"actor": {
"user_id": "[email protected]",
"roles": ["viewer"]
},
"details": {
"resource": ":SensitiveData",
"operation": "SELECT",
"required_permission": "read:sensitive",
"actual_permissions": ["read:public"],
"policy_applied": "sensitive_data_policy"
}
}
Authorization subtypes:
access_granted- Permission check passedaccess_denied- Permission check failedpermission_granted- New permission addedpermission_revoked- Permission removedrole_assigned- Role given to userrole_removed- Role taken from userrls_applied- Row-level security filtered results
Data Access Events
{
"event_type": "data_access",
"subtype": "query_executed",
"actor": {
"user_id": "[email protected]"
},
"operation": {
"type": "SELECT",
"query": "MATCH (c:Customer) WHERE c.vip = true RETURN c",
"graph": "production",
"labels_accessed": ["Customer"],
"properties_accessed": ["name", "email", "vip"],
"rows_returned": 45,
"duration_ms": 23
}
}
Data access subtypes:
query_executed- Read query completeddata_exported- Bulk data exportreport_generated- Report creationaggregation_computed- Aggregate query
Data Modification Events
{
"event_type": "data_modification",
"subtype": "node_updated",
"actor": {
"user_id": "[email protected]"
},
"operation": {
"type": "UPDATE",
"graph": "production",
"target": {
"label": "Customer",
"id": "cust_12345"
},
"changes": {
"before": {"status": "active", "tier": "gold"},
"after": {"status": "active", "tier": "platinum"}
}
}
}
Modification subtypes:
node_created- New node insertednode_updated- Node properties changednode_deleted- Node removedrelationship_created- New relationshiprelationship_updated- Relationship changedrelationship_deleted- Relationship removedbulk_insert- Batch data importbulk_delete- Batch data removal
Schema Change Events
{
"event_type": "schema_change",
"subtype": "constraint_created",
"actor": {
"user_id": "[email protected]"
},
"details": {
"object_type": "constraint",
"object_name": "unique_customer_email",
"definition": "CONSTRAINT unique_customer_email ON :Customer ASSERT email IS UNIQUE"
}
}
Schema subtypes:
graph_created- New graphgraph_dropped- Graph deletedconstraint_created- New constraintconstraint_dropped- Constraint removedindex_created- New indexindex_dropped- Index removedpolicy_created- RLS policy addedpolicy_modified- RLS policy changedpolicy_dropped- RLS policy removed
Administrative Events
{
"event_type": "admin_action",
"subtype": "user_created",
"actor": {
"user_id": "[email protected]"
},
"details": {
"target_user": "[email protected]",
"roles_assigned": ["analyst"],
"password_policy": "standard"
}
}
Administrative subtypes:
user_created- New user accountuser_modified- User properties changeduser_deleted- User account removeduser_disabled- Account disableduser_enabled- Account enabledpassword_changed- Password updatedconfig_changed- Server configuration modifiedbackup_created- Backup initiatedbackup_restored- Restore completedmaintenance_started- Maintenance window began
Querying Audit Logs
Built-in Audit Queries
-- Recent authentication failures
SELECT * FROM system.audit_log
WHERE event_type = 'authentication'
AND subtype = 'login_failure'
AND timestamp > current_timestamp() - INTERVAL '24 hours'
ORDER BY timestamp DESC;
-- Data access by specific user
SELECT timestamp, operation.query, operation.rows_returned
FROM system.audit_log
WHERE actor.user_id = 'analyst@example.com'
AND event_type = 'data_access'
AND timestamp BETWEEN $start_date AND $end_date;
-- Modifications to sensitive labels
SELECT *
FROM system.audit_log
WHERE event_type = 'data_modification'
AND operation.target.label IN ('Customer', 'Payment', 'Account')
ORDER BY timestamp DESC
LIMIT 100;
-- Permission escalation attempts
SELECT *
FROM system.audit_log
WHERE event_type = 'authorization'
AND subtype = 'access_denied'
AND details.required_permission LIKE '%admin%'
ORDER BY timestamp DESC;
Command Line Queries
# Search recent audit logs
geode audit search --since=1h --event-type=authentication
# Export audit data
geode audit export --start=2026-01-01 --end=2026-01-31 \
--format=csv --output=january-audit.csv
# Summary statistics
geode audit summary --period=24h
# Output:
# Authentication Events: 1,234
# - Successful logins: 1,180
# - Failed logins: 54
# Data Access Events: 45,678
# - Queries executed: 45,678
# - Rows returned: 2,345,678
# Modification Events: 1,234
# - Nodes created: 456
# - Nodes updated: 678
# - Nodes deleted: 100
Security Monitoring
Real-Time Alerting
# geode.yaml
audit:
alerts:
# Multiple failed logins
- name: brute_force_detection
condition: |
count(event_type = 'authentication' AND subtype = 'login_failure')
WHERE actor.ip_address = $ip
AND timestamp > now() - interval '5 minutes'
> 5
action:
notify:
- channel: slack
webhook: ${SLACK_SECURITY_WEBHOOK}
- channel: pagerduty
service_key: ${PAGERDUTY_KEY}
# Unusual data access
- name: large_data_export
condition: |
event_type = 'data_access'
AND operation.rows_returned > 10000
action:
notify:
- channel: email
recipients: [email protected]
# Admin action after hours
- name: after_hours_admin
condition: |
event_type = 'admin_action'
AND extract(hour from timestamp) NOT BETWEEN 9 AND 17
action:
notify:
- channel: slack
webhook: ${SLACK_OPS_WEBHOOK}
# Privilege escalation
- name: privilege_escalation
condition: |
event_type = 'admin_action'
AND subtype IN ('role_assigned', 'permission_granted')
AND details.target_role IN ('admin', 'dba', 'security_admin')
action:
notify:
- channel: email
recipients: [email protected]
Anomaly Detection
# geode.yaml
audit:
anomaly_detection:
enabled: true
# Baseline learning period
learning_period: 7d
detectors:
# Unusual access patterns
- name: access_pattern_anomaly
metric: queries_per_user_per_hour
sensitivity: medium
alert_threshold: 3.0 # standard deviations
# Unusual data volume
- name: data_volume_anomaly
metric: rows_returned_per_user_per_day
sensitivity: high
alert_threshold: 2.5
# New access patterns
- name: new_label_access
type: first_time_access
alert_on: label
SIEM Integration
Splunk Integration
# Install Splunk forwarder
# Add Geode audit logs as input
cat > /opt/splunkforwarder/etc/system/local/inputs.conf <<EOF
[monitor:///var/log/geode/audit.log]
disabled = false
sourcetype = geode:audit:json
index = database_audit
EOF
# Configure Splunk to parse Geode audit events
cat > /opt/splunkforwarder/etc/system/local/props.conf <<EOF
[geode:audit:json]
TIME_FORMAT = %Y-%m-%dT%H:%M:%S.%6N%Z
TIME_PREFIX = "timestamp":"
KV_MODE = json
EOF
Elasticsearch Integration
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/geode/audit.log
json.keys_under_root: true
json.add_error_key: true
fields:
log_type: geode_audit
fields_under_root: true
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "geode-audit-%{+yyyy.MM.dd}"
pipeline: geode-audit-pipeline
# Create Elasticsearch pipeline for enrichment
PUT _ingest/pipeline/geode-audit-pipeline
{
"processors": [
{
"date": {
"field": "timestamp",
"formats": ["ISO8601"]
}
},
{
"geoip": {
"field": "actor.ip_address"
}
}
]
}
Datadog Integration
# datadog.yaml
logs:
- type: file
path: /var/log/geode/audit.log
service: geode
source: geode-audit
sourcecategory: database
init_config:
instances:
- min_collection_interval: 10
# Add custom metrics from audit events
dogstatsd_mapper_profiles:
- name: geode_audit
prefix: geode.audit.
mappings:
- match: "authentication.login_success"
name: "geode.audit.login.success"
tags:
auth_method: "$1"
- match: "authentication.login_failure"
name: "geode.audit.login.failure"
tags:
reason: "$1"
Streaming to Kafka
# geode.yaml
audit:
output:
kafka:
enabled: true
brokers:
- kafka1:9092
- kafka2:9092
- kafka3:9092
topic: geode-audit-events
compression: lz4
batch_size: 100
flush_interval: 1s
security:
protocol: SASL_SSL
sasl_mechanism: PLAIN
username: ${KAFKA_USERNAME}
password: ${KAFKA_PASSWORD}
Compliance Reporting
Generating Compliance Reports
# Generate SOC 2 compliance report
geode audit report --framework=soc2 \
--period=Q4-2025 \
--output=soc2-q4-2025.pdf
# Generate GDPR data access report
geode audit report --framework=gdpr \
--data-subject=[email protected] \
--output=gdpr-access-report.pdf
# Generate HIPAA audit report
geode audit report --framework=hipaa \
--period=2025 \
--include-evidence=true \
--output=hipaa-2025-audit.pdf
Automated Compliance Checks
# geode.yaml
audit:
compliance:
frameworks:
- gdpr
- hipaa
- soc2
checks:
# GDPR: Records of processing
- name: gdpr_article_30
frequency: daily
query: |
SELECT DISTINCT actor.user_id, operation.type,
array_agg(DISTINCT operation.labels_accessed)
FROM system.audit_log
WHERE timestamp > current_timestamp() - INTERVAL '24 hours'
GROUP BY actor.user_id, operation.type
# HIPAA: Access to PHI
- name: hipaa_phi_access
frequency: daily
query: |
SELECT * FROM system.audit_log
WHERE operation.labels_accessed && ARRAY['Patient', 'MedicalRecord']
AND timestamp > current_timestamp() - INTERVAL '24 hours'
Audit Log Security
Protecting Audit Logs
# geode.yaml
audit:
security:
# Encrypt audit logs
encryption:
enabled: true
algorithm: aes-256-gcm
key_source: hsm
# Sign audit entries for integrity
signing:
enabled: true
algorithm: ed25519
key_file: /etc/geode/keys/audit-signing.key
# Immutable storage
immutable: true
append_only: true
# Access control
access:
read_roles:
- security_admin
- compliance_auditor
write_roles: [] # Only system can write
Log Integrity Verification
# Verify audit log integrity
geode audit verify --log-file=/var/log/geode/audit.log
# Output:
# Verifying audit log integrity...
# Total entries: 1,234,567
# Valid signatures: 1,234,567
# Chain integrity: OK
# No tampering detected
# Verify specific time range
geode audit verify --start=2026-01-01 --end=2026-01-31
Retention and Archival
Retention Policies
# geode.yaml
audit:
retention:
# Hot storage (fast access)
hot:
duration: 30d
storage: /var/log/geode/audit
# Warm storage (compressed)
warm:
duration: 365d
storage: /archive/geode/audit
compression: zstd
# Cold storage (long-term archive)
cold:
duration: 2555d # 7 years
storage: s3://audit-archive/geode
encryption: true
# Automatic purge after retention
purge_after_retention: true
Archival Commands
# Archive old audit logs
geode audit archive --older-than=30d \
--destination=s3://audit-archive/geode \
--compress=true
# Restore archived logs for investigation
geode audit restore --date-range=2025-01-01:2025-03-31 \
--source=s3://audit-archive/geode \
--destination=/tmp/audit-investigation
Best Practices
1. Enable Audit Logging in Production
# Always run with at least security-level auditing
audit:
enabled: true
level: security # minimum for production
2. Protect Audit Log Integrity
audit:
security:
signing: true
immutable: true
encryption: true
3. Implement Real-Time Monitoring
audit:
alerts:
- name: critical_events
condition: severity = 'critical'
action:
notify: immediate
4. Align Retention with Compliance
# Common retention requirements:
# - GDPR: No specific requirement (balance with data minimization)
# - HIPAA: 6 years
# - SOC 2: 1 year minimum, 3+ years recommended
# - PCI DSS: 1 year minimum
audit:
retention:
duration: 2555d # 7 years covers most requirements
5. Regular Audit Log Review
# Schedule regular reviews
# Daily: Security events
# Weekly: Access patterns
# Monthly: Compliance summary
# Quarterly: Full audit review
Troubleshooting
Missing Events
# Check audit configuration
geode audit config show
# Verify event types enabled
geode audit config show | grep events
# Check for disk space issues
df -h /var/log/geode
# Check audit log permissions
ls -la /var/log/geode/audit.log
Performance Impact
# Optimize audit performance
audit:
async: true
buffer_size: 10000
flush_interval: 5s
batch_writes: true
# Exclude high-volume, low-value events
exclude:
- event_type: data_access
operation.query: "MATCH (n) RETURN count(n)" # Health checks
Related Topics
- Compliance - Regulatory compliance frameworks
- Security - Security overview
- Authorization - Access control
- RBAC - Role-based access control
- Encryption - Data encryption
- Monitoring - System monitoring
Further Reading
- Audit Logging Guide - Complete audit configuration
- Security Overview - Meeting regulatory requirements
- Security Architecture - Security design
- SIEM Integration Whitepaper - Enterprise logging integration