Slim 4 adapter for [guard-core-php](https://github.com/Guard-Core/guard-core-php): wires the guard into Slim's middleware stack. It composes [psr15-guard](https://github.com/Guard-Core/psr15-guard) (the PSR-15 middleware adapter for the same engine) and adds the Slim-native integration layer: PSR-7 factory wiring from Slim's `App`, one-call attachment to the app or a route group, and the body-parsing ordering guidance. Works with Slim 4.
Website · Docs · Playground · Dashboard · Discord
Guard Core is the Python engine. Framework adapters are thin wrappers that translate native request/response types into Guard Core's protocols. The telemetry agents ship security events and metrics to the monitoring backend. Parallel engine implementations exist for Go, PHP, TypeScript (on npm), and Rust (on crates.io) - all ports of the same reference semantics, conformance-tested against the shared adversarial corpus.
| Package | Role | PyPI |
|---|---|---|
| guard-core | Framework-agnostic security engine | |
| guard-agent | Telemetry agent | |
| fastapi-guard | FastAPI / Starlette adapter | |
| flaskapi-guard | Flask adapter | |
| djapi-guard | Django adapter | |
| tornadoapi-guard | Tornado adapter |
Go modules published via GitHub releases. Production-ready.
| Package | Role | Release |
|---|---|---|
| guard-core-go | Go engine | |
| nethttp-guard | net/http adapter | |
| gin-guard | Gin adapter | |
| echo-guard | Echo (v4) adapter | |
| fiber-guard | Fiber (v3) adapter | |
| guard-agent-go | Telemetry agent |
Published on Packagist under the rennf93 vendor. Production-ready.
| Package | Role | Packagist |
|---|---|---|
| guard-core-php | PHP engine | |
| laravel-guard | Laravel adapter | |
| symfony-guard | Symfony adapter | |
| psr15-guard | PSR-15 adapter | |
| slim-guard | Slim 4 adapter | |
| guard-agent-php | Telemetry agent |
Published under the @guardcore npm scope; source in the guard-core-ts monorepo. Production-ready.
| Package | Role | npm |
|---|---|---|
| @guardcore/core | Core engine | |
| @guardcore/express | Express adapter | |
| @guardcore/nestjs | NestJS adapter | |
| @guardcore/fastify | Fastify adapter | |
| @guardcore/hono | Hono (edge) adapter | |
| guardagent | Telemetry agent |
Published on crates.io. Production-ready.
| Package | Role | crates.io |
|---|---|---|
| guard-core-engine | Core engine crate | |
| guard-core-rs | Facade crate (consumer entry point) | |
| actix-guard-rs | Actix Web adapter | |
| axum-guard-rs | Axum adapter | |
| tower-guard-rs | Tower adapter | |
| rocket-guard-rs | Rocket adapter | |
| guard-agent-rs | Telemetry agent |
| Package | Role | PyPI |
|---|---|---|
| guard-core-mcp | MCP server: config validation, docs search, detection sandbox |
- The full guard-core-php engine pipeline in Slim 4's middleware stack: rate limiting, IP lists, payload inspection, security headers
- Composition over duplication: wires psr15-guard rather than re-implementing it
📚 Documentation - full technical documentation for this package.
🛡️ Guard Core - the engine's reference documentation.
🤖 Monitoring Agent Integration - monitor your Guard instance with a monitoring agent.
Slim 4 middleware IS PSR-15 middleware (psr/http-server-middleware), and psr15-guard already provides exactly that. slim-guard does not copy it. It requires psr15-guard and contributes only what is Slim-specific:
- Factory wiring:
SlimGuard::forApp($app, $engine)takes theResponseFactoryInterfacefrom Slim'sAppand resolves a matchingStreamFactoryInterface(explicit argument, response factory that is also a stream factory, or the default slim/psr7 implementation when installed). - Attachment:
addTo($app)calls Slim'sApp::add();addToGroup($group)attaches to a route group with its documented semantics. - Ordering guidance for Slim's optional
BodyParsingMiddleware, which consumes the request body stream.
The relationship is deliberate: slim-guard is the ecosystem's Slim flavor of the PSR-15 adapter, and psr15-guard remains the single place where guard verdicts become PSR-7 responses.
composer require rennf93/slim-guardAttach the guard where your Slim App is assembled:
use RenzoFranceschini\GuardCore\Config\SecurityConfig;
use RenzoFranceschini\GuardCore\Engine\GuardEngine;
use RenzoFranceschini\GuardCoreSlim\SlimGuard;
use Slim\Factory\AppFactory;
$app = AppFactory::create();
SlimGuard::forApp($app, new GuardEngine(new SecurityConfig(
enableRedis: false,
blacklist: ['192.0.2.0/24'],
rateLimit: 100,
rateLimitWindow: 60,
enableRateLimiting: true,
)))->addTo($app);Blocked requests get the engine's block verdict translated to a PSR-7 response by psr15-guard: 403 Forbidden for a blacklisted IP, 429 Too many requests with Retry-After for a rate limit hit. Passing requests continue into Slim's middleware stack untouched.
PHP shared-nothing applies: construct GuardEngine per request in classic FPM, or per worker under long-running runtimes (FrankenPHP, RoadRunner, workerman). SlimGuard and the composed psr15-guard middleware hold no mutable state of their own. In-memory fallbacks are per-request safety nets; distributed rate limits, IP bans, and cloud-range caches require Redis (set enableRedis: true and point REDIS_HOST/REDIS_PORT at your instance).
- Fail-closed is inherited from psr15-guard: if the engine throws, the composed middleware returns the engine's fail-closed response (
500 Security check failed, honorably overridden bycustomErrorResponses) instead of letting the request through. - Bounded body read is inherited from psr15-guard: the request body is scanned as a prefix of at most 256 KiB (matching the engine's full-scan window). Payloads beyond the prefix, or signatures split across its boundary, are not detected.
- Middleware order matters: add the guard so it executes before any middleware that reads the request body stream (Slim's
BodyParsingMiddlewarecasts the stream to a string, which leaves the read pointer at EOF). In Slim, the last middleware added executes first. - App-level attachment (
addTo) screens everything that reaches the app, including unmatched routes that would 404. Group-level attachment (addToGroup) only screens requests that match a route inside the group; a blacklisted IP hitting an unmatched path under the group is answered by Slim's 404, not the guard's 403. - No security headers or CORS are added by this adapter or by psr15-guard; blocked responses are exact engine translations.
composer lint
composer testcomposer test runs the plain-PHP suite in bin/test_slim.php (unit coverage always; set REDIS_HOST to a reachable Redis to include the shared-state integration cases).
Released: v1.1.0 on Packagist. The engine floor is rennf93/guard-core-php ^4.1.0; no 4.1.0 of the engine is currently published (its tag is absent and Packagist's latest is v4.0.4), so public resolution is collapsed until the synchronized 4.2.0 train retags the engine - CI resolves the engine from the master sibling checkout in the meantime. The PSR-15 adapter it composes, rennf93/psr15-guard, is at v1.1.0 on Packagist; the pass-through parity surface below is merged on its master and lands in its next release at the 4.2.0 train.
The pass-through parity surface (engine security headers and CORS verdict headers on the handler response, behavioral return rules over a bounded response-body prefix, the per-route routes map, and the geo rate-limit resolver) lives on the composed rennf93/psr15-guard middleware, whose released 1.x does not carry it yet. This is a composition-chain fact, not a missing capability: the PSR-15 request state (route config, client ip) is created inside psr15-guard's process(), so slim cannot wire it wrapper-side without duplicating security logic. The surface lands with the psr15-guard release at the 4.2.0 train, when slim bumps its constraint. CI already mounts the psr15-guard master sibling, and bin/test_slim.php exercises the surface there (it skips with an explicit pending-psr15-release message over the released Packagist resolution).
MIT