Skip to main content

Configuration

Introduction

All of the package's configuration lives in config/redactor.php. Publish it with php artisan vendor:publish --tag=redactor-config.

The file has two parts. The top of the file defines two pattern lists, $credentialPatterns and $identityPatterns, and the returned array spreads them into each profile. The returned array holds the global settings and the profiles.

Resolved profiles are cached and rebuilt only when the raw configuration behind them changes, so reading a profile on every redaction costs nothing measurable. Invalid values throw a ConfigurationException naming the offending path rather than falling back to a default silently.

Top-Level Keys

default_profile

TypeDefaultEnvironment variable
string'default'REDACTOR_DEFAULT_PROFILE

The profile used when none is named. It must be a key under profiles.

scan

Settings for redactor:scan. None of them affect redaction of live payloads.

KeyTypeDefaultEnvMeaning
profilestring'file_scan'REDACTOR_SCAN_PROFILEThe profile the scanner uses unless --profile is passed.
exclude_patternsstring[]*.lock, *.min.js, *.map, vendor/*, node_modules/*, storage/framework/*, public/build/*Globs matched against each file's basename and its path relative to the scanned directory. A pattern ending in /* prunes that directory during the walk.
max_file_sizeint10485760REDACTOR_SCAN_MAX_FILE_SIZEFiles larger than this many bytes are skipped.
skip_binarybooltrueREDACTOR_SCAN_SKIP_BINARYSkip files that contain a NUL byte or are mostly non-printable in their first 8 KB.
respect_gitignorebooltrueREDACTOR_SCAN_RESPECT_GITIGNORESkip files git already ignores.
window_linesint512REDACTOR_SCAN_WINDOW_LINESHow many lines are scanned at once.
overlap_linesint4REDACTOR_SCAN_OVERLAP_LINESHow many lines each window shares with the previous one, so a secret spanning a boundary is still found.
decodebooltrueREDACTOR_SCAN_DECODELook one layer deep inside base64, percent-encoded and JSON-escaped spans.
verification.enabledboolfalseREDACTOR_SCAN_VERIFYAllow --verify to contact providers.
verification.verifiersstring[][]The verifiers permitted to run: github_token, stripe_key, slack_token. An empty list means none.
baselinestring|nullbase_path('.redactor-baseline.json')REDACTOR_SCAN_BASELINEThe file of accepted findings.

See Scanning for what each of these does in practice.

pseudonymization

Settings for the hash, surrogate and tokenize operators.

KeyTypeDefaultEnvMeaning
enabledbooltrueREDACTOR_PSEUDONYMIZATIONWhen false the pseudonymising operators fall back to plain redaction.
keystring|nullnullREDACTOR_PSEUDONYMIZATION_KEYThe HMAC key. At least 16 bytes. Leave null to derive one from APP_KEY.
saltstring|nullnullREDACTOR_PSEUDONYMIZATION_SALTMixed into every surrogate. Shared by every profile unless a profile sets its own.

The mapping is one-way. Anyone holding the key can confirm a guess, so the key must not travel with the logs. Rotating it changes every surrogate. See Operators and Pseudonymisation.

tokenization

Settings for the tokenize operator and Redactor::detokenize().

KeyTypeDefaultEnvMeaning
storestring|nullnullREDACTOR_TOKEN_STOREThe cache store that holds originals. Null means the default cache store.
ttlint|null86400REDACTOR_TOKEN_TTLHow many seconds a token can be exchanged back. Null keeps originals forever.

Originals are encrypted with the application key before they reach the cache. See Reversible Tokens.

events

TypeDefaultEnvironment variable
booltrueREDACTOR_EVENTS

Whether to dispatch RedactionPerformed when a redaction changes something. See Events.

profiles

An array of named profiles. Every key a profile accepts is described under Profile Keys.

custom_strategies

TypeDefault
array<string, class-string>[]

Strategy classes registered under a short name, so a profile's strategies list can name them:

'custom_strategies' => [
'internal_data' => \App\Redaction\InternalDataStrategy::class,
],

Each class must implement Kirschbaum\Redactor\Strategies\Contracts\Strategy. See Extending.

Profile Keys

Every profile accepts the keys below. Where the shipped default profile reads an environment variable, it is listed; the other profiles set literal values. The "Default" column is what applies when the key is absent from a profile, which is not always what the shipped profiles set.

Strategies and Keys

KeyTypeDefaultEnvMeaning
enabledbooltrueREDACTOR_ENABLEDWhen false, redact() returns the content unchanged and inspect() reports nothing.
strategiesstring[][]Strategy class names or custom_strategies names, in the order they run.
safe_keysstring[][]Keys whose values, subtrees included, are emitted untouched. Supports * wildcards, compared case-insensitively.
blocked_keysstring[][]Keys whose values are always redacted. Same wildcard syntax.

Rules

KeyTypeDefaultMeaning
patternsarray<string, string|array>[]Named pattern rules, shorthand regex or full form. See Rules.
pathsarray<string, string|array>[]Dotted path patterns mapped to an operator. See Path Rules.
allowliststring[][]Literals and regexes that are never findings whichever detector reports them. See Allow-Lists.
known_secretsarray[]The application's own credentials. See known_secrets.

Operators and Confidence

KeyTypeDefaultEnvMeaning
operatorsarray<string, string|array>[]What to do with each entity, plus a default. When absent the default operator is redact. See Operators.
min_confidencefloat0.0REDACTOR_MIN_CONFIDENCEDetections scoring below this are ignored. Must be between 0 and 1. See Confidence.

Output and Limits

KeyTypeDefaultEnvMeaning
replacementstring'[REDACTED]'REDACTOR_REPLACEMENTThe text the redact operator writes.
mark_redactedbooltrueREDACTOR_MARK_REDACTEDAdd '_redacted' => true to an associative array that was changed. Never added to a list, never overwrites an existing _redacted key, never written into an HTTP response or MCP structured content.
track_redacted_keysboolfalseREDACTOR_TRACK_KEYSWith mark_redacted, also add _redacted_keys.
non_redactable_object_behaviorstring'preserve'REDACTOR_OBJECT_BEHAVIORWhat to do with an object that cannot be walked: preserve, remove, redact or empty_array.
max_value_lengthint|nullnullREDACTOR_MAX_VALUE_LENGTHStrings longer than this many bytes are truncated or redacted. Null disables the check.
large_string_behaviorstring'truncate'REDACTOR_LARGE_STRING_BEHAVIORtruncate keeps the head, scans it and appends a note; redact replaces the whole value.
redact_large_objectsbooltrueREDACTOR_LARGE_OBJECTSWhether LargeObjectStrategy does anything.
max_object_sizeint|null100REDACTOR_MAX_OBJECT_SIZEArrays and objects with more items than this are replaced with a summary. Null disables the check.
max_depthint32REDACTOR_MAX_DEPTHHow many levels the walk descends before replacing the rest of the subtree. Guards cyclic and pathologically nested payloads.

A truncated string looks like this:

<first 5000 bytes> [REDACTED] (String truncated: 65536 characters, 5000 kept)

The head is cut with mb_strcut() so it stays valid UTF-8, and the strategies after LargeStringStrategy still scan it.

shannon_entropy

KeyTypeDefaultEnvMeaning
enabledbooloff when absentREDACTOR_SHANNON_ENABLEDWhether the entropy detector runs. The strategy treats a missing key as disabled.
thresholdfloat4.8REDACTOR_SHANNON_THRESHOLDBits per character a token must reach, unless a charset threshold applies.
min_lengthint25REDACTOR_SHANNON_MIN_LENGTHTokens shorter than this, in characters, are never measured.
charset_thresholdsarray<string, float>nonePer-alphabet thresholds for hex, base64 and base64url. When the token's alphabet has one, it wins over threshold.
exclusion_patternsstring[][]Regexes for tokens that score high without being sensitive: URLs, dates, UUIDs, IPs, MAC addresses, SQL. A pattern that cannot be evaluated excuses nothing.

A hex digest cannot exceed 4.0 bits per character because it has 16 symbols, so judging it against 4.8 guarantees a miss. The shipped profiles set hex to 3.0 and both base64 alphabets to 4.5. The hex exclusion /^[0-9a-f]+$/i deliberately does not excuse strings of 32 characters or more, since those may be digests.

Tokens are whitespace-delimited. A value with no internal whitespace is one token, so a bare API key is reported whole; a sentence with a key in it reports only the key.

recognition

Named entity recognition. Present in the shipped default profile and inert until enabled.

KeyTypeDefaultEnvMeaning
enabledboolfalseREDACTOR_RECOGNITIONWhether EntityRecognitionStrategy does anything. When false the strategy is left out of the chain entirely.
driverstring'presidio'The registered recogniser to use.
urlstring'http://127.0.0.1:5002/analyze'REDACTOR_RECOGNITION_URLThe Presidio /analyze endpoint. Only read by the presidio driver.
languagestring'en'Passed to the recogniser.
entitiesstring[][] (all)The recogniser's own labels to ask for. The shipped profile lists PERSON, LOCATION, ORGANIZATION, NRP.
entity_maparray<string, string>[]Recogniser label to package entity, for operators. An unmapped label is lowercased.
score_thresholdfloat0.6Spans scoring below this are dropped.
min_lengthint20Values shorter than this many bytes are not sent.
max_lengthint5000Values longer than this are not sent.
min_wordsint3Values with fewer whitespace-separated words are not sent.
timeoutfloat2.0Seconds to wait for the recogniser.
batchbooltrueSend every prose value in a payload in one call before the walk, instead of one call per value.
failure_thresholdint3Consecutive failures before the circuit breaker opens.
cooldownint60Seconds the breaker stays open.

See Entity Recognition.

known_secrets

KeyTypeDefaultMeaning
valuesstring[][]Literal secrets.
configstring[][]Config keys whose string values are secrets. A key that points at an array registers every string under it.

The shipped profiles list app.key. Values shorter than 8 characters and nulls are skipped, so an unset secret in a local environment never fails the profile. See Known Secrets.

pseudonymization (per profile)

A profile may carry its own pseudonymization block. Its non-null keys are merged over the global block, so a profile can set a salt of its own to stop its surrogates correlating with other profiles, or set enabled to false:

'export' => [
'pseudonymization' => ['salt' => 'export-2026'],
// ...
],

The Shared Pattern Lists

The two lists at the top of the config file are spread into the default, strict, observability and file_scan profiles. Order matters: on an equal confidence score the rule listed first wins an overlap, which is why url_with_auth sits ahead of email and anthropic_key ahead of openai_key.

$credentialPatterns, in order:

RuleEntityConfidenceNotes
url_with_authurl_credentials0.9Any scheme. Only the password is replaced (capture 2).
private_key_blockprivate_key1.0PEM BEGIN ... PRIVATE KEY to END, across lines.
jwtjwt0.9Three base64url segments, the first two starting eyJ.
bearer_tokenbearer_token0.85Bearer <token>; only the token is replaced.
aws_access_keyaws_access_key0.9AKIA or ASIA plus 16 characters.
github_tokengithub_token0.95ghp_, gho_, ghu_, ghs_, ghr_ and github_pat_ tokens.
stripe_keystripe_key0.95sk_ and rk_ keys only; publishable keys are meant to be seen.
slack_tokenslack_token0.9xox[abpors]- tokens.
anthropic_keyanthropic_key0.95sk-ant- keys.
openai_keyopenai_key0.9sk- and sk-proj- keys.
google_api_keygoogle_api_key0.9AIza plus 35 characters.
sendgrid_keysendgrid_key0.95SG. keys.

$identityPatterns, in order:

RuleEntityConfidenceNotes
emailemail0.8Byte-level, so non-ASCII local parts and domains match. Keyword @.
phone_formattedphone0.6Needs separators or parentheses, so dates, versions and cards are not mistaken.
phone_e164phone0.7+ and 9 to 15 digits.
phone_barephone0.5Ten bare digits, only when the value contains phone, tel, mobile, cell or fax.
ssnssn0.7Hyphenated, with the ssn validator.
ssn_baressn0.4Nine bare digits, only near ssn, social security, tax id or tin, with the validator.
credit_cardcredit_card0.6 (default)13 to 16 digits with optional spaces or dashes, with the luhn validator.
ibaniban0.6 (default)Compact or spaced, with the iban validator.

Every rule in both lists declares samples, counter_samples and min_length, and every rule that can carries keywords. See Rules.

The Shipped Profiles Compared

Settingdefaultstrictobservabilityfile_scanperformance
StrategiesSafe, Blocked, LargeObject, LargeString, KnownSecrets, Regex, Entropy, RecognitionSafe, Blocked, LargeObject, LargeString, KnownSecrets, Regex, EntropySafe, Blocked, KnownSecrets, Regex, EntropyKnownSecrets, Regex, EntropySafe, Blocked, KnownSecrets, Regex
Safe keys27 identifiers, timestamps and enumerations7 (id, uuid, created_at, updated_at, timestamp, level, event)21nonesame 27 as default
Blocked keys24, including *token*, *key*, *secret*, email, names, ssn, card fieldsdefault plus secret, phone, address, user_agent, ip, name, username8 (password, *token*, *secret*, authorization, private_key, client_secret, cvv, pin)none7 (password, secret, *token*, *key*, authorization, private_key, client_secret)
Patternsshared listsshared lists, ipv4, uuidshared lists, ipv4shared lists, api_key_generic, aws_secret_key, base64_key, password_assignmentemail, simple_token
Pathsnonenonerequest.headers.authorization, request.headers.cookie, **.password all redactnonenone
Operatorscredit_card partial keep 4none configured (all redact)email surrogate keeping domain, phone and ip surrogate, credit_card surrogate keeping 6-digit BINcredit_card partial keep 4none configured
min_confidence0.00.00.40.00.0
mark_redactedtruetruefalsetruefalse
track_redacted_keysfalsetruefalsefalsefalse
non_redactable_object_behaviorpreserveredactpreservepreservepreserve
max_value_length500010005000nullnull
redact_large_objectstruetruetruefalsefalse
max_object_size10025100100null
max_depth3216323216
Entropyon, 4.8 over 25, charset thresholdson, 4.0 over 15, no charset thresholdson, 4.8 over 25, charset thresholdson, 4.8 over 25, charset thresholds, extra word and number exclusionsoff
Known secretsapp.keyapp.keyapp.keyapp.keyapp.key
Recognitionpresent, disablednot listednot listednot listednot listed

Environment Variables

Every variable the shipped configuration reads:

# Global
REDACTOR_DEFAULT_PROFILE=default
REDACTOR_EVENTS=true

# Pseudonymisation and tokens
REDACTOR_PSEUDONYMIZATION=true
REDACTOR_PSEUDONYMIZATION_KEY=
REDACTOR_PSEUDONYMIZATION_SALT=
REDACTOR_TOKEN_STORE=
REDACTOR_TOKEN_TTL=86400

# The default profile
REDACTOR_ENABLED=true
REDACTOR_REPLACEMENT="[REDACTED]"
REDACTOR_MARK_REDACTED=true
REDACTOR_TRACK_KEYS=false
REDACTOR_OBJECT_BEHAVIOR=preserve
REDACTOR_MAX_VALUE_LENGTH=5000
REDACTOR_LARGE_STRING_BEHAVIOR=truncate
REDACTOR_LARGE_OBJECTS=true
REDACTOR_MAX_OBJECT_SIZE=100
REDACTOR_MAX_DEPTH=32
REDACTOR_MIN_CONFIDENCE=0.0
REDACTOR_SHANNON_ENABLED=true
REDACTOR_SHANNON_THRESHOLD=4.8
REDACTOR_SHANNON_MIN_LENGTH=25
REDACTOR_RECOGNITION=false
REDACTOR_RECOGNITION_URL=http://127.0.0.1:5002/analyze

# Scanning
REDACTOR_SCAN_PROFILE=file_scan
REDACTOR_SCAN_MAX_FILE_SIZE=10485760
REDACTOR_SCAN_SKIP_BINARY=true
REDACTOR_SCAN_RESPECT_GITIGNORE=true
REDACTOR_SCAN_WINDOW_LINES=512
REDACTOR_SCAN_OVERLAP_LINES=4
REDACTOR_SCAN_DECODE=true
REDACTOR_SCAN_VERIFY=false
REDACTOR_SCAN_BASELINE=.redactor-baseline.json

Only the default profile reads the per-profile variables. The other shipped profiles set literal values, so REDACTOR_MAX_VALUE_LENGTH changes default and nothing else.

How Values Are Validated

env() hands every value over as a string, so each key is coerced and checked when the profile is built:

  • Booleans accept true, false, 1, 0, and the strings true, false, 1, 0, yes, no, on, off and an empty string, case-insensitively.
  • Integers must be positive; max_value_length and max_object_size also accept null, and an empty string from env() counts as null.
  • non_redactable_object_behavior, large_string_behavior and a rule's mode and validator must be one of the documented values.
  • min_confidence must be between 0 and 1.
  • A pattern that does not compile is dropped from the profile; a rule with no pattern and no words, or with a bad mode, throws.

Anything that fails throws a ConfigurationException whose message names the path, such as profiles.default.max_depth. php artisan redactor:validate surfaces all of them at once.

Region Packs

regions at the top level holds pattern lists grouped by country: gb, nl, de, fr, it, es, be, se, no, ca, au and eu. A profile's regions key lists the packs to spread into its patterns. Packs are off unless listed. See Region Packs.