Audit Logs Policy
Audit logging is an important part of API security that plays a critical role in detecting and correcting issues such as unauthorized access or permission elevations within your system. Audit logging is also a requirement for many compliance certifications as well as part of the buying criteria for larger enterprises.
Adding Audit Logging to your APIs that are secured with Zuplo is as easy as adding a policy. Typically you want to add audit logs to any API that modifies data, however depending on the API you may want it on read operations as well (i.e. retrieve a secret key, etc.)
Enterprise Feature
This policy is only available as part of our enterprise plans. It's free to try only any plan for development only purposes. If you would like to use this in production reach out to us: sales@zuplo.com
Configuration
The configuration shows how to configure the policy in the 'policies.json' document.
config/policies.json
Policy Configuration
name<string>- The name of your policy instance. This is used as a reference in your routes.policyType<string>- The identifier of the policy. This is used by the Zuplo UI. Value should beaudit-log-inbound.handler.export<string>- The name of the exported type. Value should beAuditLogInboundPolicy.handler.module<string>- The module containing the policy. Value should be$import(@zuplo/runtime).handler.options<object>- The options for this policy. See Policy Options below.
Policy Options
The options for this policy are specified below. All properties are optional unless specifically marked as required.
eventTypeBase<string>- Reverse-DNS prefix used for the auto-emitted request event type. Defaults to 'com.zuplo.api'. Defaults to"com.zuplo.api".bucketId<string>- Override the bucket id this policy emits events for. Defaults to the bucket id from the runtime environment.samplingRate<number>- Fraction of requests to capture, between 0 (none) and 1 (all). Defaults to 1. Defaults to1.include<object>- Controls which potentially-sensitive parts of each request are captured in the auto-emitted audit event. Disable fields to satisfy your own data-handling and PII policies. All are enabled by default.queryParams<boolean>- Include the request's query-string parameters in the logged URL. Disable if query strings may contain sensitive data. Defaults totrue.user<boolean>- Include the authenticated user / actor identity (subject, email, connection). Defaults totrue.ipAddress<boolean>- Include the caller's IP address. Defaults totrue.geolocation<boolean>- Include the caller's geolocation (country, region, city). Defaults totrue.
Using the Policy
Automatic Request Auditing
Once the Audit Logs policy is added to a route, it automatically records one structured audit event for every request that passes through it — no extra code required. Each event captures who made the request, what they called, and the outcome.
The automatic event uses the type com.zuplo.api.request and includes the
actor, the HTTP method and path, the response status, and the geolocation of the
caller.
For very high-volume routes you can record only a fraction of requests by
setting the samplingRate option (for example 0.1 to capture 10% of
requests).
Controlling What's Logged
Audit events can contain personal or sensitive data. To keep audit logging
compliant with your own data-handling and PII policies, use the include
option to turn individual fields off. Everything is captured by default; set a
flag to false to omit it:
queryParams— the request's query-string parameters (in the logged URL).user— the authenticated user / actor identity (subject, email, connection). Theuservsanonymousclassification is always kept, but the identifying values are omitted when disabled.ipAddress— the caller's IP address.geolocation— the caller's country, region, and city.
Code
These settings also apply to the geolocation automatically added to custom
events emitted via log().
Emitting Custom Events
Beyond the automatic per-request event, you can record your own domain events —
for example "account deleted" or "API key rotated" — from a handler or custom
policy using the static AuditLogInboundPolicy.log() method. Any fields you
don't supply are filled in automatically from the request context (event id,
time, actor, request id, IP address, user agent, and so on).
Code
The event object passed to log() supports the following fields. Only type is
required.
type— the event type, in reverse-DNS form (e.g.com.acme.account.deleted).subject— the primary entity the event is about.resources— an array of{ type, id, metadata? }describing the resources the event affected.success— whether the operation succeeded.data— any additional structured data to attach to the event.actor— override the automatically-derived actor ({ sub, type, email, connection }).country,region,city— override the caller's geolocation. These default to the current request's location, so you normally don't need to set them.
Audit logging is best-effort: log() never throws and never blocks or fails the
request, even if an event cannot be recorded.
Audit Log Event Shape
Every audit event follows the CloudEvents 1.0 envelope. An automatically-emitted request event looks like this:
Code
Custom events emitted via log() share the same envelope; the type,
subject, resources, success, and data fields come from the event you
pass, and the remaining fields are populated from the request context.
Viewing Audit Logs
In-portal viewing and retrieval of audit logs is coming soon.
Read more about how policies work