mtownsend/array-redactor
Redact sensitive data from PHP arrays before logging or storing it. Array Redactor masks values by key using dot notation and wildcards, with a configurable replacement string and Laravel support. Keeps passwords, tokens, and personal data out of your logs and dumps.
Architecture fit. mtownsend/array-redactor remains a single-responsibility utility: given an associative array and a list of keys, it returns a copy with matching values replaced by a redaction token. The Laravel layer is still an optional service provider and facade. What changes with 1.0.1 is that the transform is no longer a pure data operation — callback support in the redaction method means arbitrary user-supplied code now executes inside the log/audit path. Architecturally it is still a cross-cutting concern with no I/O, no persistence, and no state of its own, and still trivially composable at logging middleware, Monolog processors, exception handlers, HTTP client taps, and audit writers. The shift is that determinism and testability now depend on callback discipline rather than on the library: a pure array transform plus a reviewer-approved callback is fine; a callback that queries a database, calls a service, or does regex detection turns a 50-line utility into an opaque, side-effecting step in the hot path. The implicit contract about which keys carry sensitive data still exists and will still drift.
Integration feasibility. Still a one-line composer require plus auto-discovery in Laravel, still no meaningful transitive dependencies. The new fact is that 1.0.1 exists — which is also the confusing fact. Our prior read had the last release in 2019; a 1.0.1 implies a 1.0.0 line that we have not assessed, so the release history between 2019 and now is unexamined. Pin to exactly 1.0.1 (not ^1.0) until we have read the diff from the 2019 tag. Two feasibility questions now gate install: (a) does 1.0.x widen the php constraint to our PHP matrix, and (b) what is the callback's signature and failure contract. Both are still a half-day spike, not a project.
Technical risk. Re-ranked:
null, or throws converts a redaction step into either a leak, a blank field, or a broken logger. A callback that receives the raw value and logs, traces, or serializes it in a debug path defeats the entire purpose. This is a new attack surface and a new code-review obligation, and it sits inside the path that handles the most sensitive data we have.Key questions.
null, false, a non-string return, or a thrown exception — swallowed, propagated, or does the original value survive?redact. Confirm the actual public API surface and whether 1.0.0 renamed anything — a rename is a breaking change we have not accounted for.php constraint, namespace, or Laravel provider change?config:cache, queued jobs, and anything that serializes configuration?Stack fit. Standalone PHP with an optional Laravel provider; fits Laravel 8–11 if the constraint is forked or already widened in 1.0.x. Still a natural fit for our logging pipeline and any place we serialize payloads for human review. Callbacks make it a plausible host for value-level masking (a token format, an account-number pattern), but hosting detection logic inside a logging dependency is a deliberate trade: it removes a dependency and adds bespoke security code we own. Default position: use callbacks for token shaping and formatting only, not for detection.
Migration path. Unchanged and now more valuable: never call the facade or the library's method directly from application code. Keep the narrow internal boundary — Redactor::redact(array $payload, array $keys): array — and treat callbacks as an implementation detail behind it. That boundary is what converts sporadic upstream releases, API renames, and abandonment into a one-file swap, and it is what prevents callbacks from proliferating across call sites where nobody reviews them as security code. Golden-file tests must now cover both the token path and the callback path: nested positives, case variants, renamed-key negatives, callback-throws, and callback-returns-null.
Compatibility. Pin 1.0.1 exactly during evaluation, then move to a caret constraint only after reading the changelog and diff for the 1.0.0 line. Confirm the PHP constraint before anything else; if it blocks install, fork to acme/array-redactor rather than using --ignore-platform-reqs. Verify the Laravel provider still uses deferred binding and that config publishing remains optional. If we only need the core class, skip the provider — the facade buys us nothing and the callback feature is available without it.
Sequencing.
Maintenance. Still near-zero churn on the core, but 1.0.1 adds a surface we must now track: the callback contract. If we use callbacks, we own that code as security code — reviewed, tested, and covered by the same drift assertions as the key list. The upstream release does not reduce our governance load (SBOM entry, named owner, unmaintained-fork note, periodic review); it adds a small amount of upgrade diligence and a provenance check. Budget roughly one engineer-day per year plus a one-time fork effort, and add half a day for the 1.0.0→1.0.1 diff review now.
Support. Unchanged: no vendor, no SLA, no security contact. A single patch release is not a support relationship, and we should not present it internally as "actively maintained." Support is us, and any callback we write is supported exclusively by us.
Scaling. The base transform is still O(n) and negligible against log I/O and JSON encoding. Callbacks add per-matched-value invocation cost, which is fine for string formatting and not fine for regex over long free-text fields, per-value service calls, or anything that touches a database — those turn a hot-path utility into a latency and failure amplifier. Bound payload size before redaction, keep callbacks O(1) and allocation-light, and never let a callback open a socket.
Failure modes.
config:cache or queued/lazy log contexts.JsonSerializable payloads if only plain arrays are traversed — unaddressed by this release.Ramp-up. Hours for the core API; the callback path adds a short but non-trivial onboarding item — engineers must understand that a callback is security code in a hot path, that it receives the raw value, and that its failure modes are silent. The real learning cost is still the key inventory: someone must own and review the list of sensitive fields and prove it matches the schemas actually flowing. Staff against the policy, not the package.
TPM recommendation. Use it, pinned to 1.0.1, behind our internal interface, on a fork we control, with the redaction key list as a reviewed configuration artifact. Add two conditions this release forces: (1) clear the provenance and 2019→1.0.1 diff review before the dependency lands anywhere near production, and (2) permit callbacks only inside our adapter, only for token shaping and formatting, and only under the same review bar as security code. Keep the written caveat that this is key-based redaction, not PII detection — callback support makes that caveat more important, not less, because it now looks like a detection hook.
How can I help you explore Laravel packages today?