Skip to content

Latest commit

 

History

History
135 lines (106 loc) · 4.21 KB

redaction.md

File metadata and controls

135 lines (106 loc) · 4.21 KB

Redaction

Redaction is not supported in the browser #670

To redact sensitive information, supply paths to keys that hold sensitive data using the redact option. Note that paths which contain hypens need to use brackets in order to access the hyphenated property:

const logger = require('.')({
  redact: ['key', 'path.to.key', 'stuff.thats[*].secret', 'path["with-hyphen"]']
})

logger.info({
  key: 'will be redacted',
  path: {
    to: {key: 'sensitive', another: 'thing'}
  },
  stuff: {
    thats: [
      {secret: 'will be redacted', logme: 'will be logged'},
      {secret: 'as will this', logme: 'as will this'}
    ]
  }
})

This will output:

{"level":30,"time":1527777350011,"pid":3186,"hostname":"Davids-MacBook-Pro-3.local","key":"[Redacted]","path":{"to":{"key":"[Redacted]","another":"thing"}},"stuff":{"thats":[{"secret":"[Redacted]","logme":"will be logged"},{"secret":"[Redacted]","logme":"as will this"}]}}

The redact option can take an array (as shown in the above example) or an object. This allows control over how information is redacted.

For instance, setting the censor:

const logger = require('.')({
  redact: {
    paths: ['key', 'path.to.key', 'stuff.thats[*].secret'],
    censor: '**GDPR COMPLIANT**'
  }
})

logger.info({
  key: 'will be redacted',
  path: {
    to: {key: 'sensitive', another: 'thing'}
  },
  stuff: {
    thats: [
      {secret: 'will be redacted', logme: 'will be logged'},
      {secret: 'as will this', logme: 'as will this'}
    ]
  }
})

This will output:

{"level":30,"time":1527778563934,"pid":3847,"hostname":"Davids-MacBook-Pro-3.local","key":"**GDPR COMPLIANT**","path":{"to":{"key":"**GDPR COMPLIANT**","another":"thing"}},"stuff":{"thats":[{"secret":"**GDPR COMPLIANT**","logme":"will be logged"},{"secret":"**GDPR COMPLIANT**","logme":"as will this"}]}}

The redact.remove option also allows for the key and value to be removed from output:

const logger = require('.')({
  redact: {
    paths: ['key', 'path.to.key', 'stuff.thats[*].secret'],
    remove: true
  }
})

logger.info({
  key: 'will be redacted',
  path: {
    to: {key: 'sensitive', another: 'thing'}
  },
  stuff: {
    thats: [
      {secret: 'will be redacted', logme: 'will be logged'},
      {secret: 'as will this', logme: 'as will this'}
    ]
  }
})

This will output

{"level":30,"time":1527782356751,"pid":5758,"hostname":"Davids-MacBook-Pro-3.local","path":{"to":{"another":"thing"}},"stuff":{"thats":[{"logme":"will be logged"},{"logme":"as will this"}]}}

See pino options in API for redact API details.

Path Syntax

The syntax for paths supplied to the redact option conform to the syntax in path lookups in standard EcmaScript, with two additions:

  • paths may start with bracket notation
  • paths may contain the asterisk * to denote a wildcard
  • paths are case sensitive

By way of example, the following are all valid paths:

  • a.b.c
  • a["b-c"].d
  • ["a-b"].c
  • a.b.*
  • a[*].b

Overhead

Pino's redaction functionality is built on top of fast-redact which adds about 2% overhead to JSON.stringify when using paths without wildcards.

When used with pino logger with a single redacted path, any overhead is within noise - a way to deterministically measure it's effect has not been found. This is because its not a bottleneck.

However, wildcard redaction does carry a non-trivial cost relative to explicitly declaring the keys (50% in a case where four keys are redacted across two objects). See the fast-redact benchmarks for details.

Safety

The redact option is intended as an initialization time configuration option. It's extremely important that path strings do not originate from user input. The fast-redact module uses a VM context to syntax check the paths, user input should never be combined with such an approach. See the fast-redact Caveat and the fast-redact Approach for in-depth information.