Skip to content

Hardening and completeness pass, released as 1.0.0 - #6

Merged
belisarh merged 121 commits into
mainfrom
redactor/hardening
Sep 14, 2026
Merged

belisarh merged 121 commits into
mainfrom
redactor/hardening

Conversation

@belisarh

@belisarh belisarh commented Aug 27, 2026 •

Copy link
Copy Markdown
Member

Hardening and completeness pass, one commit per change, released as 1.0.0. Full detail per item is in CHANGELOG.md; the upgrade path from 0.1.0 is in docs/upgrading.md.

872 tests · 2,445 assertions · 100% line coverage (CI floor) · PHPStan level 10, no baseline · Pint, Rector and Semgrep clean.

Detection

  • Detections carry entity, offset, confidence and signals; overlaps resolve once by score, priority, then arrival, with a single rewrite per string.
  • Path rules (*, **, [*]) compiled to a trie and checked before everything else.
  • Pattern rules gain modes, capture groups, validators, keywords, min_length, allow lists, samples and counter-samples asserted by redactor:validate.
  • Fifteen checksum validators (Luhn, IBAN, SSN, NHS, BSN, Steuer-ID, NIR, DNI, codice fiscale, Belgian NN, personnummer, fødselsnummer, SIN, TFN, VAT) and Validator::extend().
  • Region packs for GB, NL, DE, FR, IT, ES, BE, SE, NO, CA, AU and EU, off by default.
  • Known secrets from literals, config keys and runtime registration; PCRE failures fail closed.

Operators and pseudonymisation

  • redact, mask, partial, remove, preserve, hash, surrogate, nullify, tokenize, chosen per entity with path > entity > rule > default precedence.
  • Shape-preserving surrogates keyed by HMAC from APP_KEY; reversible tokens through an encrypted cache store and Redactor::detokenize().

API

  • Redactor::profile() fluent builder with withMarkers(), withoutMarkers(), only(), except(), inspect(), redactSafely(); Conditionable and Macroable.
  • inspect() returns a RedactionResult with findings that never include matched text.
  • One exception family under RedactorException; RedactionPerformed event with counts only.

Boundaries

  • RedactorTap never throws; redact route middleware fails closed; StreamRedactor with hold-back window; RedactsResponses trait for Laravel MCP; RedactPrompt middleware for Laravel AI.

Scanning and CI

  • redactor:scan with --staged, --diff, --history, table/JSON/SARIF/JUnit output, baselines with ruleset fingerprint, base64/URL/JSON decoding, redactor:allow markers, publishable pre-commit hook and workflow.
  • Live-credential verification for GitHub, Stripe, Slack, OpenAI, Anthropic, SendGrid and Google, behind three gates, with SecretVerifier::register().

Entity recognition

  • Presidio driver with gates, verified offsets and a circuit breaker; batching of every prose value per payload through PrimingStrategy and BatchRecognizer.
  • In-process ONNX recognition lives in the companion package kirschbaum-development/redactor-onnx.

Conventions and packaging

  • Aligned with Laravel first-party package style: open classes, provider shape, helpers, docblocks; all deprecated aliases removed before the tag.
  • Rector, Semgrep and composer audit workflows; docs/ set of ten pages with the README as an index.
  • Redactor::fake() with nine assertions for application suites.

Performance

  • Config memoised per container, strategy chains cached, patterns grouped by minimum length, copy-on-write walks; ~8.5 µs for a small array, ~76 µs for a 30-key request payload on the CLI without JIT.

@belisarh belisarh changed the title Hardening pass: 24 findings, one commit each Hardening and completeness pass, released as 1.0.0 Sep 14, 2026
@belisarh
belisarh merged commit ca32ddd into main Sep 14, 2026
19 checks passed
@belisarh
belisarh deleted the redactor/hardening branch September 14, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant