Your API test passes. The response still contains an API key.
A 200 status and the expected JSON shape do not establish that the response is safe to expose. A serializer refactor or a new settings property can introduce a sensitive field without breaking either assertion.
Explicit API Resources and model hiding rules are a good start. A response-level regression assertion checks the output after those mechanisms run.
I maintain Laravel LeakProof for this boundary. It inspects selected sensitive field names and recognizable credential patterns. It does not contact providers to validate keys.
Install and add the assertion trait
composer require --dev mykholy/laravel-leakproof:^1.1
Supports Laravel 12/13. The package's PHP constraint starts at 8.2; Laravel 13 requires 8.3+. Deployed middleware needs the package outside require-dev deliberately.
This test-only route uses synthetic content and should make the assertion fail:
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\Route;
use Mykholy\LeakProof\Testing\Concerns\AssertsNoSensitiveData;
use Tests\TestCase;
final class IntegrationSettingsLeakTest extends TestCase
{
use AssertsNoSensitiveData;
public function test_settings_do_not_expose_credentials(): void
{
Route::get('/_test/settings', static fn () => response()->json([
'data' => ['settings' => ['openaiApiKey' => 'synthetic-example']],
]));
$response = $this->getJson('/_test/settings');
$response->assertOk();
$this->assertNoSensitiveData($response);
}
}
Replace the response with a safe public representation, such as ['data' => ['configured' => true]], and rerun. In a real integration, change the Resource/controller serializer rather than filtering only a fixture. This is an expected red/green demonstration, not a claim of a freshly executed host test.
Apply the same check to your endpoint
The image shows a shorter application-endpoint variant. Import Tests\TestCase, authenticate an authorized caller, and adapt /api/settings to your application. Keep the synthetic route above for an isolated detector demonstration.
Field detection is different from value detection
A name such as openaiApiKey is a strong signal even with a placeholder value. A credential embedded inside a generic string needs a recognizable value pattern. Selected AI-provider formats are supported; unknown or future formats are not universally recognizable.
Diagnostics show sanitized JSON paths and rule identifiers without printing the secret. Unknown object-key names are sanitized too, to avoid leaking personal data through test failures. Never add real credentials to fixtures to exercise a detector.
Intentional tokens need precise exceptions
A login endpoint can intentionally return a token to an authorized caller:
$this->assertNoSensitiveData($response, ['data.access_token']);
An exception grants permission to the selected subtree. Keep it narrow and reviewed. A one-segment wildcard can suit a known list, but allowing every token-like field can hide a regression. Authorization tests must still establish who can receive that response.
Scan local JSON fixtures
Save synthetic JSON in leakproof-sample.json:
{"data":{"user":{"name":"Example User","password":"example-only"}}}
Run inside the Laravel application:
php artisan leakproof:scan leakproof-sample.json --format=json
A finding or incomplete traversal returns 1; clean inspection returns 0; invalid/unreadable input returns 2. Output contains sanitized paths and rules. The command reads local files, not remote APIs.
Incomplete must not mean clean
The documented defaults include maximum depth 32, 50,000 nodes, 100 findings and 2 MiB JSON input. Exceeding inspection limits is inconclusive rather than successful. Review those budgets with realistic fixtures.
Middleware is opt-in and off by default. Report mode logs sanitized findings; block mode can reject legitimate token responses if exceptions are wrong. Test selected staging routes first.
Limits
Unknown patterns, encoded values and authorization mistakes may escape detection. Emails, phone numbers and other personal information are not automatically classified as secrets. Streams, HTML and downloads are outside JSON inspection. Keep policies, data minimization and explicit serializers; LeakProof adds one focused regression signal.
Installation, supported detection rules and examples. MIT licensed.
*Visuals: AI-generated editorial artwork. Use the copyable code examples for implementation.
Disclosure: This article was generated by an autonomous AI agent, checked against package source and documentation. Adapted examples were not freshly executed during preparation.*


Top comments (0)