Skip to content

Generate test credentials at run time - #37

Merged
imanimanyara merged 2 commits into
mainfrom
chore/generated-test-credentials
Oct 19, 2026
Merged

imanimanyara merged 2 commits into
mainfrom
chore/generated-test-credentials

Conversation

@imanimanyara

@imanimanyara imanimanyara commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Why

GitGuardian raised 28 incidents across laranail by 2026-10-18. 27 were literal test credentials or false positives, and each was closed by hand. This is the org-wide sweep that stops the next one.

What changed

  • 81 literals reported by CredentialLiterals → 0: 55 replaced, 26 exempted (25 markers).
  • Replaced with TestCredentials::password() / ::secret() wherever the exact value does not matter: passwords that must merely satisfy a rule, confirmation pairs, hunter2/hunter3-style match and mismatch values, unknown-field values in the dropUnknownFields tests, a closure-bypass value, a non-UUID value, and the userinfo in the URL credential tests (built with sprintf). Where a test needs a length, the generator is asked for it (password('brief', 8), password('plain', 14), password('excessive', 41), password('balanced', 12)). Purposes are single plain words.
  • Distinct values are asserted where the failing case depends on them: the confirmation tests in PasswordRuleTest, StringRuleTest and the wildcard RuleSetTest assert mismatch differs from confirmed.
  • Exempted (// @credential-literal-exempt: <reason>), because the literal is what the test proves:
    • PasswordRuleTest (16): a deliberately weak input; exactly the 8-character minimum; shorter than the minimum (×3); shorter than the configured default minimum of 10; crafted to miss exactly one required character class (×4); digits only (×2), lower case only, letters only, no digit, no symbol — each the input a composition rule must reject.
    • FluentRuleTest (4): shorter than the min(12) the admin branch applies; shorter than the min(12) a skipped branch would apply, so passing proves the skip; longer than the max(5) the default branch applies; shorter than the minimum.
    • IntegrationTest (2), StringRuleTest (1), RuleSetTest (1): shorter than the minimum / than the min(12) a skipped branch would apply.
    • RuleSetWithBagTest (1 marker, 2 literals): both values are shorter than the min() rules, so the bag must report them.
  • Guard: tests/Architecture/NoLiteralCredentialsTest.php, minFiles: 143 (159 files scanned).
  • laranail/package-tools floor raised from ^0.1.3 to ^0.1.9, the first release with TestCredentials and the guard (laranail rule 3).
  • CHANGELOG [Unreleased] → ### Changed.

Verification (local, PHP 8.5)

  • Pest: 6153 passed, 123 skipped, 2 failed. Both failures are the activeUrl tests (FluentRuleTest "validates activeUrl shortcut", StringRuleTest "validates string with activeUrl"), which resolve real DNS and cannot in the local sandbox; this PR does not touch them.
  • laranail-pint --test: passed.
  • PHPStan: no errors.
  • Rector dry-run: no changes.
  • Red proof: a literal 'password' => '…' appended to IntegrationTest.php turned the guard red, naming the file and line; reverted with git checkout.

Follow-up: package-tools 0.1.10

  • laranail/package-tools floor raised to ^0.1.10.
  • NoLiteralCredentialsTest gains a second test, assertCredentialPurposesAreWordsIn() (same dir, minFiles: 143).
  • Purposes renamed: 0 (all 22 distinct purposes were already single words). Markers removed: 0 (all 25 still needed by the 0.1.10 scanner, checked line by line).
  • Red proof: a scratch TestCredentials::password() call with a hyphenated purpose turned the new test red; the file was restored and nothing of it is committed.
  • Locally: Pint, PHPStan and Rector clean; Pest passes except two activeUrl tests that need real DNS, which this machine's sandbox cannot resolve.

GitGuardian raised 28 incidents across laranail by 2026-10-18, 27 of
them literal test credentials or false positives, each closed by hand.

Passwords and secrets the suite only needed as arbitrary values are now
generated by TestCredentials, one plain-word purpose per value. The
confirmation tests assert their matching and mismatching values differ,
since the failing case depends on it. A guard fails on any literal
added later.

Rule tests whose input is the point (too short for a min(), missing
exactly one character class, digits only) keep their literal and carry
an exemption marker with the reason.

package-tools 0.1.9 is the first release with TestCredentials and the
guard, so the floor moves to ^0.1.9.
Copilot AI balanced review requested due to automatic review settings October 19, 2026 12:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Benchmark results

Scenario Optimizations Native Laravel Optimized Speedup Δ vs base
Product import — 500 items, simple rules Wildcard, fast-check 168.0ms 3.0ms ~56x +0%
Nested order lines — 1000 orders × 5 line items Wildcard, fast-check (nested) 815.8ms 20.1ms ~41x +11%
Event scheduling — 100 items, field-ref dates Wildcard, partial fast-check 25.8ms 1.2ms ~22x +0%
Article submission — 50 items, custom Rule objects Wildcard only 9.9ms 2.5ms ~4x +0%
Conditional import — 100 items, 47 conditional fields Wildcard, pre-evaluation 215.8ms 44.9ms ~5x -1%
Login form — 3 fields, no wildcards Fast-check (flat) 0.1ms 0.0ms ~10x —

GitGuardian reads a compound purpose, two words joined by a hyphen, as the
password itself, which turns a generated credential back into a reported
one. package-tools 0.1.10 ships assertCredentialPurposesAreWordsIn(), so the floor
moves to ^0.1.10 and the credential guard gains a second test that keeps every
purpose a single plain lowercase word.

No purpose in this suite needed renaming, and every remaining exemption marker is still required by the 0.1.10 scanner.
@imanimanyara
imanimanyara merged commit 54c06da into main Oct 19, 2026
11 checks passed
@imanimanyara
imanimanyara deleted the chore/generated-test-credentials branch October 19, 2026 14:46
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.

2 participants