---
title: "Secret-safe about capture — Testing for Laravel | Roundly"
description: "Capture an artisan about section, prove it rendered, then assert no credential leaks — a secret check that cannot pass on empty output."
url: https://roundly-consulting.com/open-source/docs/testing-for-laravel/about-secrets
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Testing for Laravel](https://roundly-consulting.com/open-source/docs/testing-for-laravel.md)

# Secret-safe about capture

Captures one artisan about section and pins that it renders what it must while leaking none of the secrets it must not:

```php
expect($section)->toLeakNoSecrets(array $secrets, array $mustRender);
```

```php
expect('passkeys')->toLeakNoSecrets(
    secrets: ['auth.acme-internal.example', '/srv/acme/secrets', 'ea9b8d66'],
    mustRender: ['Sign-count policy', 'AAGUID allow-list'],
);
```

| Parameter | Type | Meaning |
| --- | --- | --- |
| `$section` | string | The section passed to artisan about --only=<section>. |
| `$secrets` | list<string> | Values that must not render — keys, paths, hosts, fingerprints. Every entry must be a non-blank string; an empty list is a deliberate render-only check. |
| `$mustRender` | list<string> | Strings that must render — positive proof the capture worked. Required, non-empty, and every entry a non-blank string. |

## Order of operations

- First, the output must be non-empty.
- Then every $mustRender string must be present.
- Only then is each $secrets entry asserted absent.

Capture goes through Artisan::call('about', \['--only' => $section\]) and Artisan::output(). It never reads app(Kernel::class)->output(), which returns an empty string — that is how a whole section’s “does not leak” checks once passed vacuously, and the leak was caught only because one positive assertion happened to exist. An empty $mustRender throws InvalidArgumentException at call time, because a negative-only check can pass against empty output.

## Every entry must be set

Every entry of both lists must be a non-blank string, or the call throws InvalidArgumentException. A null secret — config('a.key.that.is.not.set') — or an empty one from an unset env var can never be found, so the leak check would pass while checking nothing; an empty $mustRender needle is found in every output. Set the secret to a real value in the test first.

## In an application

```php
it('does not leak credentials through artisan about', function (): void {
    // Only a secret that is set can be looked for — a null or empty entry throws.
    config(['services.stripe.secret' => 'sk_test_do_not_render_me']);

    expect('environment')->toLeakNoSecrets(
        secrets: [config('app.key'), config('services.stripe.secret')],
        mustRender: ['Application Name'],
    );
});
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/testing-for-laravel.md)
