Prompt
How do I add audit logs for API access and policy changes?
Latest observation
Oct 5, 2026
OpenAI APIWeb search: off
To add audit logs for API access and policy changes, design your logging around who did what, when, from where, and what changed. A good audit trail is append-only, tamper-resistant, and searchable.
1) Decide what to log
API access events
Log at least:
- timestamp
- actor: user ID, service account, API key ID
- action: endpoint/method, operation name
- resource: object or tenant affected
- result: success/failure, status code
- request metadata: IP, user agent, request ID, trace ID
- scope/permissions used
- latency
- failure reason if denied or errored
Examples:
api.read.customerapi.update.invoiceapi.auth.failedapi.rate_limited
Policy change events
Log:
- who changed it
- what policy/rule changed
- before and after values
- reason/comment
- approval info if applicable
- source: UI, API, automation
- timestamp
- correlation IDs
Examples:
- policy created/updated/deleted
- role assignment changed
- permission granted/revoked
- threshold or allowlist/denylist edited
2) Use a structured log format
Prefer JSON over plain text so logs are queryable.
Example audit log record:
{
"event_type": "policy.updated",
"timestamp": "2026-10-05T12:34:56Z",
"actor": {
"type": "user",
"id": "u_12345",
"email": "admin@example.com"
},
"target": {
"type": "policy",
"id": "pol_987"
},
"action": "update",
"source": {
"ip": "203.0.113.10",
"user_agent": "Mozilla/5.0",
"request_id": "req_abc",
"trace_id": "trace_def"
},
"changes": [
{
"field": "max_login_attempts",
"old": 5,
"new": 3
}
],
"reason": "Tighten brute-force protection",
"result": "success"
}
For API access:
{
"event_type": "api.access",
"timestamp": "2026-10-05T12:35:10Z",
"actor": {
"type": "api_key",
"id": "key_456"
},
"method": "GET",
"endpoint": "/v1/customers/123",
"resource": {
"type": "customer",
"id": "123"
},
"result": "success",
"status_code": 200,
"latency_ms": 84,
"source": {
"ip": "198.51.100.22",
"request_id": "req_xyz",
"trace_id": "trace_xyz"
}
}
3) Instrument the right places
For API access
Add audit logging in:
- authentication middleware
- authorization middleware
- request handler / controller layer
- error/exception paths
Best practice:
- log attempts and denials, not just successful calls
- include a correlation/request ID across all logs
- avoid logging secrets, tokens, or full payloads unless necessary
For policy changes
Add logging in:
- admin UI save actions
- policy management API endpoints
- IaC/automation pipelines that apply policy changes
- database write layer for policy tables if needed
4) Make logs tamper-resistant
Audit logs should be harder to alter than normal application logs:
- write to append-only storage
- restrict delete/edit permissions
- ship logs off-host to a central log system
- use WORM storage or immutable buckets if possible
- consider hash chaining or digital signatures for high-assurance environments
- separate audit log access from application admin access
5) Protect privacy and security
- Do not log passwords, API keys, secrets, session tokens, or full credit card data
- Mask sensitive fields:
- email:
a***@example.comif needed - tokens: never store raw values
- email:
- Apply data retention policies
- Limit access to audit logs to security/compliance roles
- Encrypt logs in transit and at rest
6) Store logs in a queryable system
Common choices:
- SIEM: Splunk, Sentinel, QRadar
- Log platforms: ELK/OpenSearch, Datadog, New Relic
- Cloud-native: CloudTrail/CloudWatch, Azure Activity Log, GCP Cloud Audit Logs
- Dedicated audit DB/table for compliance reporting
Index by:
- actor ID
- target ID
- event type
- timestamp
- tenant/org ID
- request ID
7) Add alerting and reporting
Create alerts for:
- repeated failed API auth
- privileged policy changes
- policy deletions
- changes outside business hours
- changes by unusual actors or IPs
- mass permission grants
Generate reports for:
- all policy changes in a period
- all admin actions by a given user
- all access to a sensitive resource
8) Example implementation pattern
A simple pattern is a dedicated audit logger:
def log_audit(event_type, actor, target, result, **kwargs):
event = {
"event_type": event_type,
"timestamp": utc_now_iso(),
"actor": actor,
"target": target,
"result": result,
**kwargs
}
audit_log_sink.write_json(event)
Use it in API handlers:
def get_customer(request, customer_id):
actor = current_actor(request)
if not authorize(actor, "customer.read", customer_id):
log_audit(
"api.access.denied",
actor=actor,
target={"type": "customer", "id": customer_id},
result="denied",
method="GET",
endpoint=f"/v1/customers/{customer_id}",
source=request_meta(request)
)
return forbidden()
log_audit(
"api.access",
actor=actor,
target={"type": "customer", "id": customer_id},
result="success",
method="GET",
endpoint=f"/v1/customers/{customer_id}",
status_code=200,
source=request_meta(request)
)
return get_customer_data(customer_id)
9) Checklist
- Define audit event schema
- Capture API auth/authz success and failure
- Capture policy create/update/delete events
- Include actor, target, timestamp, source, result
- Use structured JSON logging
- Send logs to immutable central storage
- Mask secrets and sensitive values
- Add retention and access controls
- Add alerts and reports
- Test log completeness and immutability
If you want, I can also give you:
- a database schema for audit logs,
- a middleware example for Node/Python/Java, or
- a compliance-focused audit event model for SOC 2 / ISO 27001 / HIPAA.