定制 laravelsecurityaudit/laravel-ai-egress-guard 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

laravelsecurityaudit/laravel-ai-egress-guard

Composer 安装命令:

composer require laravelsecurityaudit/laravel-ai-egress-guard

包简介

Scan, redact, and optionally block outbound requests to AI providers (OpenAI, Anthropic, Gemini, and more) for leaked secrets and PII. Review in an inbox and fail CI before a prompt leaks. SDK-agnostic, at the HTTP layer.

README 文档

README

Scan every outbound request your Laravel app makes to an AI provider (OpenAI, Anthropic, Gemini, and more) for leaked secrets and PII. Review findings in a built-in inbox, fail your test suite when a prompt would leak, and optionally block an unsafe request before it leaves the app.

Mail Guard answers "is this email safe to send". Egress Guard answers "is this prompt safe to send to a third-party model". It works at the HTTP-client layer, so it is independent of which AI SDK you use.

This is an independent open-source package. It is not affiliated with, endorsed by, or sponsored by Laravel, Laravel LLC, or any AI provider.

Why this exists

A prompt is built from runtime data: a user record, a support ticket, a row from your database. That data can carry an API key, a card number, an email address, a private key, straight to a third party you do not control. The leak is in the data interpolated at call time, not in the code, so static review cannot see it. Egress Guard runs on the actual outbound request body, so it catches what review cannot.

Requirements

  • PHP 8.2+
  • Laravel 12 or 13

Installation

composer require laravelsecurityaudit/laravel-ai-egress-guard
php artisan migrate

The service provider is auto-discovered. Capture and the inbox are enabled outside production by default. It depends on laravelsecurityaudit/laravel-secret-scanner for the detection engine.

How it works

Egress Guard registers a global HTTP-client middleware. For every outbound request to a host in egress-guard.providers, it builds a scan context from the request body, runs the rule set, stores the request and its findings (with high-confidence secrets redacted and the provider key stripped from the stored headers), and, when guard mode is on, can stop the request.

Requests to any other host are ignored on a fast path.

Coverage: Prism, the Http facade, and other SDKs

The global hook covers every request made through Laravel's Http client. Prism is built on Laravel's HTTP client, so Prism calls are covered automatically, as are the official laravel/ai SDK and anything using the Http facade.

A client that ships its own Guzzle stack (for example openai-php) is not seen by the global hook. Attach the guard to those clients directly:

use LaravelSecurityAudit\EgressGuard\Support\EgressGuard;

$client = new \GuzzleHttp\Client(['handler' => EgressGuard::stack()]);
// or push EgressGuard::handler() onto an existing handler stack.

If you have disabled the global hook and want to guard a single Prism call, pass the guard through Prism's withClientOptions():

use LaravelSecurityAudit\EgressGuard\Support\EgressGuard;

// ...->withClientOptions(EgressGuard::clientOptions())

Provider-aware prompt parsing

For OpenAI, Anthropic, and Gemini request shapes, Egress Guard extracts the model and a readable prompt (messages[].content, Anthropic system, Gemini contents[].parts[].text) and stores it alongside the raw body for the inbox. By default the full raw body is scanned (most thorough). Set scan.target to prompt (or EGRESS_GUARD_SCAN_TARGET=prompt) to scan only the extracted message text when the raw JSON is too noisy.

The inbox

In an unguarded environment, open /egress-guard. Each captured request shows its provider, model, a risk badge, and the security findings, with the body redacted. The inbox can contain sensitive prompt data, so it is closed by default unless explicitly opened:

  1. If egress-guard.gate is set, that gate must pass for every request.
  2. If no gate is set, the inbox is served only in egress-guard.unguarded_environments (default ['local']). Anywhere else it returns a 403.
// config/egress-guard.php
'middleware' => ['web', 'auth'],
'gate' => 'viewEgressGuard',

Failing tests when a prompt leaks

use LaravelSecurityAudit\EgressGuard\Support\EgressGuard;

public function test_the_summary_prompt_leaks_nothing(): void
{
    $this->generateSummaryFor($user); // makes the AI call

    EgressGuard::assertNoCriticalFindings();
}

Also available: assertNoLeaks(), assertFlagged($ruleId), and assertNotFlagged($ruleId).

Failing CI with SARIF

php artisan test
php artisan egress-guard:scan --min-severity=critical --format=sarif --output=egress-guard.sarif

egress-guard:scan exits non-zero when any finding meets the threshold. Formats are table, json, and sarif. SARIF results point at the calling route action when known, otherwise at a synthetic egress-guard://request/{id} location.

Guard mode

Guard mode blocks a request when a finding meets the configured threshold. It is off by default and is the part you opt into, often in production.

EGRESS_GUARD_BLOCK=true

Defaults are conservative: it blocks only critical findings at high confidence, and fail_open is true so a scanner error never silently breaks a real AI call. A blocked request throws EgressGuardBlocked. Bypass a known-safe call with the X-Egress-Guard-Bypass header or the guard.allow_source allowlist of route actions. Every block fires an EgressBlocked event and a log warning with the rule ids, never the secret.

Residency

Egress Guard can enforce a data-residency policy. Declare the regions you allow and the region each provider actually processes in, then turn enforcement on:

// config/egress-guard.php
'residency' => [
    'enabled' => true,
    'allowed_regions' => ['EU'],
    'regions' => ['openai' => 'EU', 'anthropic' => 'US'],
],

A request to a provider whose region is not allowed (here Anthropic, US) is blocked with EgressGuardBlocked, exactly like a secret leak, and fires a ResidencyViolation event. With enabled off, the violation still fires the event (and laravel-ai-ledger records it), but the request is not blocked. Set block_unknown to also block a provider whose region you have not declared.

Rules

Rule id Severity Confidence Source
secrets.private_key critical high secret-scanner
secrets.stripe_key critical high secret-scanner
secrets.api_key critical high egress-guard
secrets.aws_access_key critical high egress-guard
secrets.bearer_token warning medium egress-guard
pii.credit_card critical high secret-scanner
pii.email warning medium egress-guard
pii.phone warning low egress-guard

Toggle rules, override severities, and suppress findings in config/egress-guard.php. Add your own by implementing LaravelSecurityAudit\SecretScanner\Scanning\Contracts\Rule.

Configuration

php artisan vendor:publish --tag=egress-guard-config
EGRESS_GUARD_ENABLED=true
EGRESS_GUARD_PATH=egress-guard
EGRESS_GUARD_GATE=viewEgressGuard
EGRESS_GUARD_RETENTION_DAYS=7
EGRESS_GUARD_REDACT=true
EGRESS_GUARD_BLOCK=false

Captured requests older than EGRESS_GUARD_RETENTION_DAYS are removed by the scheduled model:prune command. Set it to 0 to disable.

Testing

composer test
composer analyse

License

The MIT License (MIT). See LICENSE.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 4
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-28

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固