Lesson 27 / 32
Audit Logs and Support Access
Record tenant-visible audit events for sensitive actions, and give support staff controlled, logged access to tenant data.
By Rahul Agarwal · 15 years in web development
Who did what, in which tenant
Enterprise tenants expect an audit log: an append-only record of security-relevant actions inside their tenant, such as sign-ins, role changes, data exports, API key creation and settings changes. Each entry records the tenant, the actor, the action, the target, the time and relevant details, and tenant admins can usually view or export their own log. The other side is your staff. Support engineers sometimes need to see what a customer sees, but unrestricted database access for support is a serious risk. A safer design is controlled impersonation: support opens a session into a tenant only through a tool that requires a reason or ticket, possibly the customer's approval, limits the time, can be read-only, and writes every step to the tenant's audit log. Then customers can see exactly when your team accessed their data and why.
Structured audit events
Every entry is self-describing JSON scoped to a tenant, including support impersonation.
import json
from datetime import datetime, timezone
def audit(tenant_id, actor, action, target, **details):
entry = {
# fixed time so the example output is stable; use datetime.now(timezone.utc)
"ts": datetime(2026, 1, 5, 10, 30, tzinfo=timezone.utc).isoformat(),
"tenant_id": tenant_id,
"actor": actor,
"action": action,
"target": target,
"details": details,
}
print(json.dumps(entry)) # in production: append-only store, not stdout
audit("acme", "priya@acme.in", "user.role_changed", "user:42", old="viewer", new="admin")
audit("acme", "support@vendor", "tenant.impersonation_started", "tenant:acme", ticket="SUP-981")
Output:
{"ts": "2026-01-05T10:30:00+00:00", "tenant_id": "acme", "actor": "priya@acme.in", "action": "user.role_changed", "target": "user:42", "details": {"old": "viewer", "new": "admin"}}
{"ts": "2026-01-05T10:30:00+00:00", "tenant_id": "acme", "actor": "support@vendor", "action": "tenant.impersonation_started", "target": "tenant:acme", "details": {"ticket": "SUP-981"}}Make audit logs tamper-evident
Store audit events in an append-only store that the application cannot update or delete, separate from ordinary tables. Some teams also chain hashes of entries so tampering is detectable.
Quick check: Which practice best balances support needs with tenant trust?
- Time-limited, reason-required impersonation that is recorded in the tenant's audit log
- Giving support engineers the database superuser password
- Asking customers to share their passwords with support
- Letting support export any tenant's data without records
Answer
Time-limited, reason-required impersonation that is recorded in the tenant's audit log — Controlled impersonation gives support what it needs while making access explicit, minimal and visible to the customer. The other options remove accountability.