Skip to main content

Session Recording Auditing

Pomerium Enterprise

This article describes a feature available to Pomerium Enterprise customers.

Overview

The Integrity and Auditing documentation describes the "chain of custody" for session recording data, enabling end-users to meet strict compliance requirements for the handling and auditing of privileged information.

The "chain of custody" model Pomerium provides relies on:

  • Storage access patterns: guarantees about how the recordings are uploaded and accessed
  • Enterprise audit logs: records every access by end-users through Pomerium Enterprise
  • Cloud provider audit logs: Audit logs at the storage layer include metadata that can be correlated with Pomerium Enterprise, enabling verification when data was accessed through Pomerium Enterprise.

This model provides a tamper-evident audit trail for the handling and access of session recording data.

Storage access patterns

For remote access to the blob store, Pomerium follows WORM (Write Once Read Many) semantics. The roles each Pomerium component plays against the blob store are:

ComponentReadWriteDelete
Pomerium Core (recording producer)OccasionallyOnce per objectNever
Pomerium EnterpriseYesNeverNever
important

Pomerium's security and integrity guarantees are only as strong as those of the underlying storage layer. Configure encryption, object locking (or equivalent), and retention on the bucket to match the compliance requirements of your environment.

To verify the integrity of recordings produced and stored, Pomerium verifies the hash digest of the recording matches on every transfer up-to and including the final object stored in the storage layer.

Uploads will fail if any transfer in the below chain has inconsistent digests.

Auditing (Enterprise)

Both Pomerium Enterprise and cloud providers for object storage produce audit logs that satisfy strict audit-of-audit compliance standards.

Logs available from both these sources can be correlated to verify integrity and data access.

In Enterprise, each time a bucket or specific recording data is accessed, Enterprise will emit audit logs. For example:

{"level":"info","access_id":"777b6b59-a7e6-4310-af76-448da383f47d","access_type":"recording","deny":false,"success":true,"reason":"","recording_format":"ssh","object_key":"default/ssh/v1/3ff8e81f44b6eaecadaaaa7d541c8c51/*","source_ip":"<redacted>",user_agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0","user_role":"admin","user_email":"alamarre@pomerium.com","user_id":"<redacted>","user_hmac_id":"aw3iU61Z7p6wxCnNq/JVDgGHpJzhwT3eqs5Wmz8BPD8=","user_session_start":1779724385,"user_session_exp":1779724685,"datasource":"9d8dbd2c-8cce-4e66-9c1f-c490b4a07243/gcs-dev","time":"2026-05-25T11:53:05-04:00","message":"authorize blob read"}

Some of the fields above were redacted for the docs, but will contain the relevant information related to access.

FieldDescriptionSensitivity
access_idUnique identifier for a particular action. Note that an action here can have multiple access events - opening the bucket, reading metadata, and viewing the recordingLow
access_typeThe type of access.
  • recording: the recording contents were viewed
  • metadata: the recording metadata was viewed
  • bucket: (internal) Pomerium Enterprise made a connection to the bucket for reading
  • download: the recording was downloaded
Low
denyWhether the access was denied.Low
successWhether the access succeeded.Low
reasonOptional. Provides additional details about failuresLow
recording_formatFormat of the recording being accessed (e.g. ssh).Low
object_keyObject storage key (or key prefix) of the recording data being accessed. Contains the Pomerium cluster ID. cluster ID is assigned when connecting Pomerium instances to Enterprise via the cluster syncerModerate
source_ipIP address the request originated from.High
user_agentUser agent header of the client that made the request. Contains remote host information.Moderate
user_rolePomerium Enterprise role of the user performing the access.Moderate
user_emailEmail address of the user performing the access.Moderate
user_idIdentity Provider (IdP) user id of the user performing the access.High
user_hmac_idHash-based Message Authentication Code (HMAC) of the user id, suitable for correlation with the blob storage audit logsLow
user_session_startUnix timestamp of when the user's session started.Low
user_session_expUnix timestamp of when the user's session expires.Low
datasourceIdentifier of the configured blob datasource being read (<namespace-id>/<datasource-name>). <namespace-id> is the ID of the namespace in Pomerium Enterprise where this datasource was configuredModerate
important

The HMAC of the user id is generated from the shared secret Pomerium Enterprise uses. When rotating the shared secret, keep track of the previous secret in order to correlate against older audit logs.

Auditing (Blob)

Each cloud provider emits its own audit logs when objects in the recording bucket are accessed. Refer to the provider-specific documentation below to enable and query these logs.

Google Cloud Storage (GCS) Cloud Audit Logs for storage.googleapis.com must be enabled. Data Access logs must be explicitly enabled on the recording bucket for:

  • ADMIN_READ
  • DATA_READ
  • DATA_WRITE

See Cloud Audit Logs with Cloud Storage.

When properly configured, requests made by Pomerium Enterprise are annotated with:

metadata: {
audit_context: {
app_context: "EXTERNAL"
audit_info: {
x-goog-custom-audit-pomerium-access-id: "b340be6f-d9d6-4569-9b8f-53d5fac8db0c"
x-goog-custom-audit-pomerium-user: "PomeriumEnterprise/v0.32.0+0d0554ca+2026-05-25T11:06:03-04:00 (u=aw3iU61Z7p6wxCnNq/JVDgGHpJzhwT3eqs5Wmz8BPD8=)"
}
}
requested_bytes: 1071492
}
methodName: "storage.objects.get"
FieldDescription
x-goog-custom-audit-pomerium-access-idPomerium-generated access id for this action. Correlates with the access_id field in the Pomerium Enterprise audit log entry, allowing a GCS audit log entry to be matched back to the originating user action.
x-goog-custom-audit-pomerium-userIdentifies the Pomerium Enterprise build that issued the request, along with the HMAC of the user id (u=...). Correlates with the user_hmac_id field in the Pomerium Enterprise audit log entry.
note

The example query below inspects audit logs for operations made by Pomerium. Individual setups may differ from the query below.

protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
protoPayload.serviceName="storage.googleapis.com"
protoPayload.methodName:("storage.objects.get" OR "storage.objects.list")
resource.labels.bucket_name="<bucket-name>"

Integrity checks

The following criteria indicate that recording content or metadata may have been accessed or modified outside of Pomerium's chain of custody:

  • there is more than one object revision for any session recording object in the remote store
  • there are blob storage data-read logs for recording content or metadata that are not annotated with Pomerium access information
  • there are blob storage data-read logs whose access_id or user_hmac_id do not match any Pomerium Enterprise audit logs