---
title: "Filesystem driver — Certificates for Laravel | Roundly"
description: "Keep PEM material on a Laravel Storage disk — import certificates issued elsewhere or self-sign them for local development."
url: https://roundly-consulting.com/open-source/docs/certificates-for-laravel/filesystem
language: en
---

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

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

# Filesystem driver

The filesystem driver manages PEM material on a Storage disk. It is not a CA: it reads material produced elsewhere — an external ACME run, a purchased certificate — and, with self\_signed enabled, generates self-signed certificates for local development and tests. It never reports work it did not do:

```php
config(['certificates.drivers.filesystem.self_signed' => true]);
Certificates::for('app.test')->using('filesystem')->issue();
```

## Driver keys

| Key | Env | Default | Purpose |
| --- | --- | --- | --- |
| `disk` | `CERTIFICATES_FS_DISK` | local | Storage disk holding the PEM material. |
| `path` | `CERTIFICATES_FS_PATH` | certificates | Directory on that disk. |
| `self_signed` | `CERTIFICATES_FS_SELF_SIGNED` | false | Mint fresh self-signed material on every issue and renewal — never over a CA-issued PEM. Off, a name with no stored PEM throws. |
| `self_signed_days` | `CERTIFICATES_FS_SELF_SIGNED_DAYS` | 90 | Validity of self-signed certificates, in days. |

## Layout

It uses the same layout as the ACME store — one directory per certificate name holding certificate.pem, private.key and an optional chain.pem. The defaults (local disk, certificates path) match drivers.acme.store, so the filesystem driver reads ACME-issued material out of the box. It writes the same way too — temporary files moved into place once all are written (see ACME & Let’s Encrypt):

```
certificates/                          path on the disk
└── generated-tls-app-example-com/     Certificates::certificateName($domain)
    ├── certificate.pem                leaf certificate
    ├── private.key                    private key
    └── chain.pem                      intermediate chain, when present
```

## Importing existing certificates

Place certificate.pem and private.key (and chain.pem when you have one) under the directory named by Certificates::certificateName($domain). exists() checks for certificate.pem; get() lists every stored certificate by its common name, or its first SAN when it has none; status() parses the leaf for expiry, issuer, serial, fingerprint and SANs, so imported material is registered with its real expiry. Without self\_signed, issuing a name with no stored PEM throws CertificateException — import the material first — and renewing material nobody replaced fails as not renewed (same fingerprint). Pull stored certificates into the registry with:

```bash
php artisan certificates:sync --driver=filesystem
```

## Self-signed certificates

With self\_signed on, every issue and renewal mints fresh self-signed material covering every requested domain (subjectAltName included), valid for self\_signed\_days — so a renewal really moves the expiry. A PEM a real CA issued is never overwritten with a self-signed one. Self-signed material is recognised by its issuer name matching its subject name and its signature verifying with its own key — never by common name — so a hostname over 64 characters, which gets no common name, renews like any other.

```bash
CERTIFICATES_FS_DISK=local
CERTIFICATES_FS_PATH=certificates
CERTIFICATES_FS_SELF_SIGNED=true
CERTIFICATES_FS_SELF_SIGNED_DAYS=90
```

## 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/certificates-for-laravel.md)
