Using Typescript, if we imagine an entity like this:

interface Order {
  id: string;
  address: string;

Now I would like to design a system where we can process entities feeling confident that the address field won't leak by accident, e.g. if I were to log that entity. For example I can imagine a logger that runs all data-to-be-logged through an obfuscation function to strip away address. To make a stupid simple example:

function obfuscate(data:unknown) {
  if(isOrder(data) {
    data.address = "***"

But that function isn't really maintainable as the number of entities and their respective PII fields increase, and it's not even correct because what happens if data is actually an entity that has an Order as its field?

interface Shipment {
  id: string;
  order: Order;

In this case logging a shipment should still not allow order's address to leak.

I think ideally there'd be a predominantly data-driven way to tag fields as PII, letting low-level egress functions obfuscate without knowing the details of the individual pieces of data they process, but not sure how possible that is (e.g. if a field could be tagged as PII then an obfuscation function could inspect each field for that tag without knowing the details of the data being obfuscated).

But how would you approach this? Are there design-patterns you'd recommend? Maybe approaches other languages take that could inspire a Typescript-solution? Happy to hear various tradeoffs to understand this space better.

  • 1
    Not typescript, but this might help with the search: php.net/manual/en/class.sensitiveparameter.php
    – bdsl
    Mar 9, 2023 at 13:26
  • 1
    At this point maybe you should push the primitive values down one more level, have everything be wrapped in e.g. type Protected<T> = { public?: boolean; value: T }, then interface Order { id: Protected<string>; address: Protected<string> } and only serialise values where public is explicitly true.
    – jonrsharpe
    Mar 9, 2023 at 23:42

1 Answer 1


I think this has been asked a few times in different ways.

Don't attempt to log everything and then remove the bits you think are PII, you will miss some!

log("error with shipment : {obsfucate(shipment)}")

Do log specifically chosen information that you know isn't PII

log("error with shipmentId : {shipment.Id}")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.