Skip to content
Console
Menu

Queues

Workflows

Getting Started

Authentication

KV Store

Scrubbing

What is removed before an error is stored, and how an environment adds to it

Scrubbing is the line between a useful error report and a stored credential. A Scrubbing Policy is what is removed from every captured error before it is stored, and it runs on the way in rather than on the way out: the occurrence that is written is the occurrence after the rules have been applied, so a secret that a stack trace carried is not in the record you read back later. The stack field is scrubbed with the rest of the occurrence.

#The default rules

The defaults always apply, to every occurrence, whatever the environment's policy says:

  • Fields named like a password, a secret, a token, a key, a cookie, a session, an authorization or a card are replaced with [Filtered].
  • Card numbers, bearer tokens, JWTs and Sylphx secret keys are replaced wherever they appear.
  • Email addresses are replaced with [email] unless keep_emails is set.

The first rule reads a name, the second reads a value, and together they catch the two ways a secret reaches a stack trace: carried in a field whose name says what it is, or pasted into one whose name does not.

#An environment's policy adds to them

The environment's Scrubbing Policy adds to the defaults; it cannot remove them. There is no setting that turns the default rules off, which is the reason a policy can be written by whoever owns the application without anyone having to read it as a security review.

FieldTypeWhat it is
denied_fieldsstring[]More field names to replace with [Filtered] wherever they appear in tags, extra data, request data, or breadcrumb data (case-insensitive, matched as a substring).
keep_emailsboolKeep email addresses instead of replacing them with [email].

denied_fields is matched case-insensitively and as a substring, so one name covers every field that contains it — national_insurance covers national_insurance_number and customerNationalInsurance. Add a name when the defaults do not know what your domain calls the thing that must not be stored.

keep_emails exists because an email address is often the identifier you need: for an application whose users are told their address appears in error reports, keeping them makes a group readable. It is the one default rule an environment may switch off, and switching it off is a decision about your users rather than about the platform.

#One policy per environment

A policy is a singleton, and its name says so:

Name
orgs/{org}/projects/{project}/envs/{env}/scrubbing_policies/default
Id
scp_<env>

There is one per environment and no call that creates another. meta.etag fences updates: send the etag you read and the write lands only if nothing has changed since; a mismatch fails with ETAG_MISMATCH and writes nothing. Two people editing the policy at once is a conflict rather than a silent overwrite.

#Read it

Reading the policy needs observability:read. It answers with the environment's own fields — the extra names it filters and the email switch — and the metadata every resource carries. The default rules are not listed beside them, because they are not the environment's to state.

Shell
sylphx observability scrubbing-policies get orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy
Shell
curl "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy" \
  -H "Authorization: Bearer $SYLPHX_API_KEY"

#Add to it

Writing the policy needs observability:write, and it takes an update_mask: the fields you name are the fields written, and an unset mask writes every populated field.

Shell
sylphx observability scrubbing-policies update orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy
Shell
curl -X PATCH "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy" \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy"}'
TypeScript
const response = await sylphx.observability.scrubbingPolicies.update({ scrubbingPolicy: { name: 'orgs/acme/projects/shop/envs/production/scrubbing_policies/scrubbing-policy' } })

--denied-fields names one more field to filter and repeats for each; --keep-emails flips the email rule. The scrubbing_policies commands show both flags.

#Why the floor is the point

A policy that could remove a default rule would be a policy nobody could read at a glance: every reader would have to check what the environment had turned off before deciding whether a report was safe to keep. Making the policy additive is what lets the two questions stay separate — the defaults are the platform's answer to what must never be stored, and the environment's answer is only what else it wants gone.