Audit Logs

These chapters are only freely configurable for clients that self-host Unique (either Customer Managed or On Premise Tenants).

Multi or Single Tenant clients are subject to Uniques configuration (see below).

To support debugging and internal and external compliance, Unique provides logs of user and system events.

 


About audit logs

The audit log lists events triggered from API interactions within Unique. This includes versioned/public APIs as well as internal APIs (refer to APIs & Integrations).

Each audit log entry has an action that signals the performed operation. Depending on the action, additional information might be present in the data field.

Additionally, each entry contains the following fields:

Scope

The scope of the audit logs is to support forensic analysis in case of incidents and to log accountability for privileged actions. The goal is not to enable content filtering on requests or responses.

For this Unique recommends https://unique-ch.atlassian.net/wiki/spaces/SD/pages/500105333/Data+Leakage+Prevention+DLP#I-DLP-Proxy or https://unique-ch.atlassian.net/wiki/spaces/SD/pages/500105333/Data+Leakage+Prevention+DLP#II-Analytics-APIs.

Exclusions

Certain actions and/or endpoints are excluded, namely:

  • Health probes

  • All operations that require no privileged Roles and Permissions and query non-sensitive data (e.g. a user asking for their companies name or theme)

  • All operations that require no privileged Roles and Permissions and query data about the calling identity itself (e.g. a user loading his own profile)

  • All operations that require no privileged Roles and Permissions and create or update data affecting only the calling identity (e.g. a user creating a new chat for themselves)

Unique is opting for a secure by default approach, so the Audit Log is written implicitly on any operation using interceptors. Due to this enforced security, the amount of audit logs can grow exponentially if no exclusions are defined. The exclusions above balance the demand for security and compliance against the total cost of ingesting and storing large amounts of data.

Destinations

Audit Logs are written by line as JSON and their log level is 35 or audit respectively.

Console

In order to output to the console, set AUDIT_LOG_DIR to /dev/stdout.

File

In order to output to a directory, point AUDIT_LOG_DIR to a mounted volume that can host a large amount of data. Unique services will automatically rotate files in order to keep them smaller compared to the overall amount.

Modi

The Audit Logs have two log modi. Unique defaults to basic except when explicitly specified per service (environment) as AUDIT_LOG_MODE.

basic

Includes the fields as described above in About audit logs.

Example

{ "level": 35, "time": "2024-11-26T07:04:20.040Z", "pid": 7, "hostname": "node-chat-87977b44f-8h6ns", "name": "audit-log", "userId": "278092901995999999", "companyId": "235013255892999999", "clientIpAddress": "87.116.137.97", "data": { "type": "GRAPHQL", "variables": { "orderId": "analyticOrder_tjy26se9pt4cojdfpqgah2d2" }, "method": "POST", "url": "/", "description": "An analytics order was deleted." }, "action": "AnalyticsOrderDelete" }

verbose_including_cid

Unique strongly advises against using this mode at all. If resorting to use it as last resort in production, ensure it is turned on and off just-in-time.

Even strictly discouraged, this mode is available as per client request.

Since this mode is explicitly opt-in, Unique waives all liability when using this mode and the client is solely responsible to handle the logs including their sensitive content responsibly.

If verbose_including_cid is enabled, all log entries will, additionally to the basic fields include:

  • Full HTTPS request object

  • Full HTTPS response object

Both of these can include sensitive and/or CID data.

{ "level": 35, "time": "2024-11-26T08:25:44.378Z", "pid": 8, "hostname": "node-ingestion-7b58bb4f5f-lfjtm", "name": "audit-log", "userId": "278092901995999999", "companyId": "235013255892999999", "clientIpAddress": "109.92.213.255", "data": { "type": "GRAPHQL", "method": "POST", "url": "/", "description": "Content has been upserted.", "request": { "method": "POST", "url": "/", "headers": { "via": "2 kong/3.8.0", "host": "gateway.qa.unique.app", "connection": "keep-alive", "x-forwarded-for": "109.92.213.255", "x-forwarded-proto": "https", "x-forwarded-host": "gateway.qa.unique.app", "x-forwarded-port": "443", "x-forwarded-path": "/ingestion/graphql", "x-forwarded-prefix": "/ingestion/", "x-real-ip": "109.92.213.255", "x-kong-request-id": "e49a3f130cd2af1683d376037376f160", "content-length": "816", "sec-ch-ua-platform": "\"Windows\"", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.26 Safari/537.36", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "content-type": "application/json", "sec-ch-ua-mobile": "?0", "accept-language": "en-US", "accept": "*/*", "origin": "https://next.qa.unique.app", "sec-fetch-site": "same-site", "sec-fetch-mode": "cors", "sec-fetch-dest": "empty", "accept-encoding": "gzip, deflate, br, zstd", "priority": "u=1, i", "x-user-id": "278092901995999999", "x-company-id": "235013255892999999", "x-company-name": "Gandalf", "x-company-domain": "gandalf.com", "x-user-roles": "admin.app-repository.write,admin.space.write,admin.user-management.write,chat.admin.all,chat.chat.basic,chat.chat.unlimited,chat.chat.upload,chat.data.admin,chat.debug.read,chat.feedback.read,chat.knowledge.read,chat.knowledge.write" }, "body": { "query": "mutation ContentUpsert($input: ContentCreateInput!, $fileUrl: String, $chatId: String, $scopeId: String, $sourceOwnerType: String, $sourceName: String, $sourceKind: String, $storeInternally: Boolean) {\n contentUpsert(\n input: $input\n fileUrl: $fileUrl\n chatId: $chatId\n scopeId: $scopeId\n sourceOwnerType: $sourceOwnerType\n sourceName: $sourceName\n sourceKind: $sourceKind\n storeInternally: $storeInternally\n ) {\n id\n key\n byteSize\n mimeType\n ownerType\n ownerId\n writeUrl\n readUrl\n createdAt\n internallyStoredAt\n }\n}", "variables": { "input": { "key": "file1.txt", "mimeType": "text/plain", "ownerType": "SCOPE" }, "sourceOwnerType": "USER", "scopeId": "scope_rce2umm9mhv347k8ihixxxxx", "storeInternally": true }, "operationName": "ContentUpsert" }, "params": {}, "query": {} }, "response": { "id": "cont_wu4u7gf9aqcx1c9eizzjfjc0", "source": { "id": "src_t8i94zhd12u9dwebu6ds7rir", "kind": "UNIQUE_BLOB_STORAGE", "name": null, "ownerId": "278092901995999999", "ownerType": "USER", "createdAt": "2024-07-30T06:25:45.018Z", "updatedAt": "2024-07-30T06:25:45.018Z" }, "mimeType": "text/plain", "collectionName": "235013255892999999_av5mr6t9knr1di95wjq4io8x", "key": "file1.txt", "byteSize": 0, "ownerType": "SCOPE", "ownerId": "scope_rce2umm9mhv347k8ihixxxxx", "createdAt": "2024-11-26T08:25:44.371Z", "internallyStoredAt": "2024-11-26T08:25:44.370Z" } }, "action": "ContentUpserted" }

Limitations

Implicitness

Due to the implicit and enforced nature of the current audit logs, the list of events in non-deterministic and cannot be documented beforehand. Unique can provide an example set of actions as well as their documentation but ultimately, with any new product change, new events might be introduced that are audit-logged by default.

clientIpAddress

Unique leverages request-ip which tries to pin the clients IP as best as possible. This field (not a vulnerability of Unique but a factoid of the internet) is spoofable, which means, users savvy enough can submit another source of their request. Also, FSI clients often route traffic through upstream services, proxies or firewalls which might naturally modify the original IP to their own resulting in all audit logs then featuring exactly the same IP, the one from the upstream service. See in request-ip which headers are honoured.


Single and Multi Tenant Clients

Multi Tenant

Audit Logs are retained for 90 days using basic level. Clients requiring a longer audit log duration must upsell their contract to a single or customer managed tenant.

Upon request Unique can provide an excerpt of the audit logs. The granularity is business days and the maximum to request at once is 5 business days. Preparing an audit log export for multi tenant customers takes at least 3 business days. In that case, the client is responsible to provide a secure channel for transfer of the log export. This process is available once per quarter except when presenting a legal dispute or data leak investigation.

Single Tenants

Audit logs are retained for 5 years (1825 days) using basic level.

Upon request Unique can provide temporary limited access to the audit log location. Preparing an audit log export for Single Tenants takes at least 3 business days. This process is available once per quarter except when presenting a legal dispute or data leak investigation.

Unique does not provide Single Tenant Audit Logs to a clients location of choice as this includes actively processing the data potentially by a human which is against Uniques security policies. The client will receive a Azure Storage Account SAS token that is valid for the agreed time (max. 5 business days). The client is responsible to download the files on their own behalf during this time.

Unique will not delete audit logs even after ending a contract (legal and compliance requirements). Unique will continue holding the logs until the 5 years expired.


Author

@Dominik Meyer

 

© 2024 Unique AG. All rights reserved. Privacy PolicyTerms of Service