InfrastructureSecurity

Who opened that slide? Audit logs in pathology image management

Martin Schulze
Who opened that slide? Audit logs in pathology image management

Pharma customers routinely expect CROs to firewall their slides and analysis reports, to make sure only authorized representatives can access the data. When the audit comes around though, the big question is: Can you prove it?

The question is easy to state and hard to answer because of where the audit trail sits. In most deployments it stops at the application door: the log records what happened inside the image management system, and everything that touches the data directly is invisible. Let's walk through the access patterns you actually find in the field, what each one can and cannot log, and how we think about the problem at cytario.

Pattern one: block storage, no per-file audit

The traditional setup. A scanner writes whole-slide images onto a network drive, and every workstation, viewer, and analysis tool mounts the same share over SMB or NFS.

Most of the time, you won't actually find any reasonable audit log here. Technically, the operating system can record file-share access with object-access auditing or Samba VFS modules, but that is only meaningful as long as no system accounts are involved that can't be attributed to an actual user. Especially when it comes to image processing though, system accounts are a very common approach. Additionally, the volume of log information can be enormous, and with no low-cost storage available it is often not retained for a reasonable time.

Even if a system is put in place, no system accounts are in use and there is enough storage for the logs, this pattern tends to collapse as the volume of data under management grows and external users get involved. Sharing a folder from your internal network drive with an external user is not an easy task and from a security perspective best to be avoided completely.

Pattern two: SharePoint-grade auditing that pathology cannot use

Some organizations then reach for a platform that genuinely solves the logging half: SharePoint and similar content platforms record who viewed or downloaded which item, per user, per action, and give you a searchable audit log for it.

The logging is excellent. But so is the price. Even worse: you can't reasonably work with multi-gigabyte pyramidal whole-slide images in a document platform. Forcing terabytes of vendor-format slides through it is not feasible, so these platforms end up holding the PDFs, spreadsheets, and maybe a report layer, while the pixels stay elsewhere and the audit story splits in two. You get a fine-grained trail for the documents and no trail at all for the data they describe.

Pattern three: the vendor owns the bucket

The newer architecture, and the one most current image management systems (IMS) use. The IMS stores its data on S3 or another object store, and it owns the bucket. Credentials live inside the application; the application streams tiles to the browser; no other system is supposed to talk to the bucket directly.

Because every request goes through the application, the application can keep an audit log, and most claim to. The problem is what that log is worth to you. Its format, its retention, and its completeness are decisions made inside the vendor's codebase. When you ask "who accessed case X's slides between March and June?", you ask the vendor, and you trust the answer. Sometimes the bucket is invisible to the customer's own tooling altogether; sometimes it is a service account's keys that appear in the log on every single read, with no trace of the person behind the request.

The pattern is workable until the day you need an application to access the underlying data without having a custom integration with the IMS. In most deployments, these additional applications will then get a system account with broad access to the underlying bucket, completely bypassing the audit log of the IMS.

The common thread

None of these patterns is lazy engineering. But they all suffer from one of two issues: either they can't scale, or they put something in between you and the data.

cytario's pattern: audit at the storage layer

cytario makes a different decision. The permissions do not live in our application; they live in the object storage layer, and we push them there. When you share a folder with a group, cytario writes the grant into the bucket policy itself, as conditions on the identity claims of the user's session. Every reader, the cytario viewer included, gets evaluated against that policy. The application cannot grant itself anything the policy does not allow.

The consequence for auditing is the interesting part. If the storage layer enforces access, the storage layer is also the right place to record it, and object storage is good at this.

What the storage layer already records

On AWS, you enable CloudTrail data events for your bucket. Every object-level call, every GetObject, PutObject, ListBucket, lands as a structured record with the time, the bucket and key, the source IP, and the user agent. Because cytario users access the bucket through per-user OIDC federation rather than a shared vendor account, the userIdentity block carries the actual end user, not a service account. A single record tells you that a pathologist opened a specific slide at a specific time from a specific machine, and you read it in your own AWS account with your own retention policy. If a lab runs on premises instead, RustFS, the S3-compatible store our self-hosted deployments use, has several paths to the same result: a per-request audit stream you can forward to a webhook, Kafka, NATS, PostgreSQL, or most other pipelines, and S3-style event notifications on top. Either way, the audit trail of the data is generated by the storage system that enforced the access, not by an application you have to take at its word.

Vendor-held static IAM vs cytario OIDC + STS federation: side-by-side flow diagram showing credential location, data plane, and audit attribution.

Attribution to user and client

Per-user identity is half of what makes these logs usable. The other half is knowing how the data was reached, and there the user agent and the STS session identifiers do the work. The same federated credential pattern covers every access path: a pathologist in the cytario viewer, an analyst copying slides with the AWS CLI, a script running in a Jupyter notebook via boto3, or Cyberduck. Reads of the same object land in the trail as distinct records: the browser requests in one form, the CLI with a CLI user agent, the app jobs under a broker session minted for the submitting user, with the write-session policy changes showing up as their own distinct action in the management trail. You can distinguish "downloaded via the web viewer" from "fetched by an analysis script" without trusting anyone's memory.

The result

See what this enables in practice:

Audit logs in cytario: who accessed which object and when.

The demo runs on a slide we have used in demos at many conferences, and the log pattern makes the point: you can read the busiest hours at the booth straight off the access log. That is the analytics side of the story. Audit logs in cytario are not only more reliable and comprehensive, they become a real treasure trove of data to utilize beyond compliance.


Have questions about implementing a secure digital pathology infrastructure? Get in touch with us – we'd love to discuss your specific needs and how cytario can help you reduce costs while securing your operations.

Further resources

Related cytario blog posts

AWS documentation