Skip to content

Deprecate KeyExtractors::ip() and drop its usages#106

Merged
sascha-egerer merged 3 commits into
mainfrom
feature/deprecate-keyExtractors-ip
Jun 18, 2026
Merged

Deprecate KeyExtractors::ip() and drop its usages#106
sascha-egerer merged 3 commits into
mainfrom
feature/deprecate-keyExtractors-ip

Conversation

@sascha-egerer

@sascha-egerer sascha-egerer commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

The resolved client IP is the default for every rule (omit the key / keyIp()), so KeyExtractors::ip() (raw REMOTE_ADDR) is @deprecated; the raw peer is read via getServerParams()['REMOTE_ADDR']. Inline the REMOTE_ADDR fallback at the former internal call sites (Config::clientIpResolver, the IP-aware matchers' standalone match(), InfrastructureBanListener), drop the dead portable 'ip' compile arm, and migrate examples and tests to keyless rules. Only ip()'s own unit tests reference it.

The resolved client IP is the default for every rule (omit the key / keyIp()), so
KeyExtractors::ip() (raw REMOTE_ADDR) is @deprecated; the raw peer is read via
getServerParams()['REMOTE_ADDR']. Inline the REMOTE_ADDR fallback at the former
internal call sites (Config::clientIpResolver, the IP-aware matchers' standalone
match(), InfrastructureBanListener), drop the dead portable 'ip' compile arm, and
migrate examples and tests to keyless rules. Only ip()'s own unit tests reference it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR deprecates KeyExtractors::ip() (raw REMOTE_ADDR) and removes its internal usages by making “keyless rules” the default way to key on the resolved client IP (via the Config IP resolver, falling back to REMOTE_ADDR).

Changes:

  • Remove KeyExtractors::ip() usage across matchers/listeners and inline a REMOTE_ADDR fallback resolver at those call sites.
  • Drop the portable key compile arm for {type: 'ip'} (now materializes keyless via compileKeyExtractor()).
  • Migrate examples and tests to omit the rule key (defaulting to the client IP resolver).

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Unit/Store/PdoCacheFunctionalTest.php Updates throttle/fail2ban setup to omit explicit IP keying.
tests/Unit/RequestAttributeIntegrationTest.php Migrates fail2ban rules to rely on default client-IP keying.
tests/Unit/Config/ConfigCompositionTest.php Adjusts composed typed rules to use null key extractors (keyless).
tests/phpt/track/track_threshold_flag.phpt Removes explicit KeyExtractors::ip() from track config.
tests/phpt/throttle/throttle_sliding_window_allows_then_429.phpt Removes explicit IP key from sliding throttle usage.
tests/phpt/throttle/throttle_multi_window_burst_blocks.phpt Removes explicit IP key from multi-window throttle usage.
tests/phpt/throttle/throttle_fixed_window_allows_then_429.phpt Removes explicit IP key from fixed-window throttle usage.
tests/phpt/throttle/throttle_dynamic_limit_by_header.phpt Removes explicit IP key from dynamic throttle usage.
tests/phpt/fail2ban/fail2ban_threshold_then_ban.phpt Removes explicit IP key from fail2ban config.
tests/phpt/context/request_context_fail2ban_signal.phpt Removes explicit IP key from fail2ban context test config.
tests/phpt/allow2ban/allow2ban_threshold_then_ban.phpt Removes explicit IP key from allow2ban config.
src/Portable/PortableConfig.php Removes dead 'ip' arm from key compilation (ip handled as keyless elsewhere).
src/Pattern/SnapshotBlocklistMatcher.php Replaces KeyExtractors::ip() fallback with inline REMOTE_ADDR resolver.
src/Matchers/TrustedBotMatcher.php Replaces KeyExtractors::ip() fallback with inline REMOTE_ADDR resolver + doc tweak.
src/Matchers/IpMatcher.php Replaces KeyExtractors::ip() fallback with inline REMOTE_ADDR resolver + doc tweak.
src/KeyExtractors.php Marks ip() deprecated and clarifies intended usage in docblock.
src/Infrastructure/InfrastructureBanListener.php Replaces default KeyExtractors::ip() with inline REMOTE_ADDR resolver + doc tweak.
src/Config/FileIpBlocklistMatcher.php Replaces KeyExtractors::ip() fallback with inline REMOTE_ADDR resolver + doc tweak.
src/Config.php Changes clientIpResolver() fallback from KeyExtractors::ip() to inline REMOTE_ADDR resolver.
README.md Updates proxy/IP guidance to recommend reading REMOTE_ADDR directly for raw peer.
examples/27-request-context.php Updates example fail2ban rule to omit explicit key extractor.
examples/26-psr17-factories.php Updates throttle examples to omit explicit key extractor.
examples/24-pdo-storage.php Updates throttle/fail2ban examples to omit explicit key extractor.
examples/22-multi-throttle.php Updates multi-throttle example to omit explicit key extractor.
examples/21-sliding-window.php Updates sliding throttle example to omit explicit key extractor.
examples/16-allow2ban.php Updates allow2ban example to omit explicit key extractor.
examples/11-redis-storage.php Updates throttle/fail2ban examples to omit explicit key extractor.
examples/10-observability-opentelemetry.php Updates throttle example to omit explicit key extractor.
examples/09-observability-monolog.php Updates throttle example to omit explicit key extractor.
examples/06-bot-detection.php Updates fail2ban/throttle examples to omit explicit key extractor.
examples/03-api-rate-limiting.php Updates throttle examples to omit explicit key extractor.
examples/02-brute-force-protection.php Updates fail2ban example to omit explicit key extractor.
examples/01-basic-setup.php Updates throttle example to omit explicit key extractor.
CHANGELOG.md Adds deprecation note for KeyExtractors::ip() and updates related guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
Comment thread src/Config.php
KeyExtractors (namespace Flowd\Phirewall) does not import PortableConfig, so the
bare PortableConfig::keyIp() docblock references resolved to the non-existent
Flowd\Phirewall\PortableConfig for IDE/doc tooling. Use the FQCN.
Drop the ip() rule keys in the quick-start, API-rate-limiting and login examples
(keyless now keys on the resolved client IP), remove the imports that become unused,
and use $request in the raw-REMOTE_ADDR prose.
Copilot AI review requested due to automatic review settings June 18, 2026 21:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 4 comments.

Comment thread README.md
Comment on lines 221 to +223
When no resolver is set the client IP is `REMOTE_ADDR`. For the raw connecting peer
address regardless of proxy configuration, use `KeyExtractors::ip()`.
address regardless of proxy configuration, read `$request->getServerParams()['REMOTE_ADDR']`
directly.
Comment thread CHANGELOG.md

- **`KeyExtractors::clientIp(TrustedProxyResolver)`** - the resolved client IP is now the default discriminator for every rule via the `Config` IP resolver, so a dedicated key extractor is no longer needed. Configure proxy trust once with `$config->setIpResolver($trustedProxyResolver->resolve(...))` and omit the rule's key (or use `PortableConfig::keyIp()`); both resolve the client IP. For the raw connecting peer address, `KeyExtractors::ip()` (REMOTE_ADDR) remains the explicit escape hatch.
- **`KeyExtractors::clientIp(TrustedProxyResolver)`** - the resolved client IP is now the default discriminator for every rule via the `Config` IP resolver, so a dedicated key extractor is no longer needed. Configure proxy trust once with `$config->setIpResolver($trustedProxyResolver->resolve(...))` and omit the rule's key (or use `PortableConfig::keyIp()`); both resolve the client IP.
- **`KeyExtractors::ip()`** - the name is ambiguous (it reads like "the client IP" but returns the raw `REMOTE_ADDR` peer, which behind a proxy is the proxy itself) and it bypasses the `Config` IP resolver. To key on the client IP, omit the rule's key (or use `PortableConfig::keyIp()`) so it resolves through the resolver. For the raw connecting peer, read `$request->getServerParams()['REMOTE_ADDR']` directly.
Comment thread src/KeyExtractors.php
Comment on lines +25 to +28
* @deprecated The name is ambiguous and it bypasses the Config IP resolver. To key on
* the client IP, omit the rule's key (or use \Flowd\Phirewall\Portable\PortableConfig::keyIp()) so it resolves
* through the Config's IP resolver (else REMOTE_ADDR). For the raw connecting peer,
* read $request->getServerParams()['REMOTE_ADDR'] directly.
Comment thread src/Config.php
Comment on lines +377 to +380
return $this->ipResolver ?? static function (ServerRequestInterface $serverRequest): ?string {
$remoteAddr = $serverRequest->getServerParams()['REMOTE_ADDR'] ?? null;
return is_string($remoteAddr) && $remoteAddr !== '' ? $remoteAddr : null;
};
@sascha-egerer sascha-egerer merged commit b8b2684 into main Jun 18, 2026
14 checks passed
@sascha-egerer sascha-egerer deleted the feature/deprecate-keyExtractors-ip branch June 18, 2026 22:00
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