PHPackages                             sergkulich/laravel-key-rotate - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. sergkulich/laravel-key-rotate

ActiveLibrary[Security](/categories/security)

sergkulich/laravel-key-rotate
=============================

A Laravel package to rotate app key and re-encrypt data stored in eloquent models.

2.0.0(4mo ago)04MITPHPPHP ^8.3CI passing

Since Dec 22Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/skulich/laravel-key-rotate)[ Packagist](https://packagist.org/packages/sergkulich/laravel-key-rotate)[ RSS](/packages/sergkulich-laravel-key-rotate/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (9)Versions (4)Used By (0)

Laravel Key Rotate
==================

[](#laravel-key-rotate)

[![Latest Version on Packagist](https://camo.githubusercontent.com/3cb4ad30f562626f0d0a6da97b18208416a6f565618cc902e7b21ec393455a02/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736572676b756c6963682f6c61726176656c2d6b65792d726f746174652e737667)](https://packagist.org/packages/sergkulich/laravel-key-rotate)[![PHP Version Require](https://camo.githubusercontent.com/ec95384fc72c8d1713d369e765b0f908b3f4eb18b644eb32e6c67f143661a48e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736572676b756c6963682f6c61726176656c2d6b65792d726f74617465)](https://camo.githubusercontent.com/ec95384fc72c8d1713d369e765b0f908b3f4eb18b644eb32e6c67f143661a48e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736572676b756c6963682f6c61726176656c2d6b65792d726f74617465)[![Laravel Version](https://camo.githubusercontent.com/e32f3842606098013f9dd55974249a52546ccdf9cf571ca076105f68f8370716/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d25354531312e302532302d7265643f6c6f676f3d6c61726176656c)](https://camo.githubusercontent.com/e32f3842606098013f9dd55974249a52546ccdf9cf571ca076105f68f8370716/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d25354531312e302532302d7265643f6c6f676f3d6c61726176656c)[![Run Tests](https://github.com/sergkulich/laravel-key-rotate/actions/workflows/tests.yml/badge.svg)](https://github.com/sergkulich/laravel-key-rotate/actions)[![Code Coverage](https://camo.githubusercontent.com/32855e94577df9d0a30995653b17d33a5fbfdf644518f96ea0374313397d19b7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d3130302532352d627269676874677265656e)](https://camo.githubusercontent.com/32855e94577df9d0a30995653b17d33a5fbfdf644518f96ea0374313397d19b7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d3130302532352d627269676874677265656e)[![License](https://camo.githubusercontent.com/4f7639a50436cb6ea7170550cd68db2265a07ca1aaef415b168326c2da62e60a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f736572676b756c6963682f6c61726176656c2d6b65792d726f746174652e737667)](https://camo.githubusercontent.com/4f7639a50436cb6ea7170550cd68db2265a07ca1aaef415b168326c2da62e60a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f736572676b756c6963682f6c61726176656c2d6b65792d726f746174652e737667)[![Total Downloads](https://camo.githubusercontent.com/f0870935debf40f7a56506881a791b767d8eb5ac08449a2d1e91f6dad5e41256/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736572676b756c6963682f6c61726176656c2d6b65792d726f746174652e737667)](https://packagist.org/packages/sergkulich/laravel-key-rotate)

Laravel Key Rotate package allows automatically copy current `APP_KEY` and update `APP_PREVIOUS_KEYS` with it, After that it will call `key:generate` artisan command to generate new `APP_KEY`, and, optionally, update all your Eloquent Models encrypted fields.

The Command available only then `app()->runningInConsole()` as it may take a while to update Models.

Warning

The package is in beta. Use with caution.

Never run in production without previous local testing and fresh `.env` copy and `DB` dump.

Table of contents
=================

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
- [Dive Deeper](#dive-deeper)
    - [The Event](#the-event)
    - [The Listener](#the-listener)
    - [Models](#models)
    - [Casts](#casts)
- [Tests](#tests)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [License](#license)

Installation
------------

[](#installation)

Install the package via composer:

```
composer require sergkulich/laravel-key-rotate
```

Usage
-----

[](#usage)

Run artisan command to rotate the key.

```
php artisan key:rotate
```

Use `--force` option to run the command in production to avoid confirmation prompt.

```
php artisan key:rotate --force
```

Dive deeper
-----------

[](#dive-deeper)

Quick example of extended usage.

You need to register `KeyRotate::useListener()` only if you want your model encrypted fields to be re-encrypted.

```
namespace App\Providers;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if (app()->runningInConsole()) {
            // Subscribe The Listener to The Event
            KeyRotate::withListener()
                // Discover Models that are not in App\ namespace
                ->withDir(base_path('src/Domain'), 'Domain\\')
                // Exclude Models
                ->withoutModel(User::class)
                // Exclude Model Fields
                ->withoutModelFileds(Secret::class, ['secret'])
                // Without Cast
                ->withoutCast('encrypted:array')
                // With Custom Cast
                ->withCast(CustomCast::class);
        }
    }
}
```

### The Event

[](#the-event)

The `key:rotate` command fires an event after successful completion.

#### The Event Class

[](#the-event-class)

The package provides helper to get the event class name to subscribe listeners to it.

```
$keyRotateEventClass = KeyRotate::getEventClass();

Event::listen($keyRotateEventClass, MyKeyRotateListener::class);
```

### The Listener

[](#the-listener)

The package provides default listener that update encrypted models fields after key rotation.

#### The Listener Class

[](#the-listener-class)

The package provides helper to get the listener class name in case you need it.

```
KeyRotate::getListenerClass();
```

#### Get Instance of the Listener

[](#get-instance-of-the-listener)

Simply subscribe the listener to the event in your app service provider boot method.

```
namespace App\Providers;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if (app()->runningInConsole()) {
            KeyRotate::withListener();
        }
    }
}
```

Or get singleton instance of the listener and call it anywhere in your code.

```
// Get Instance
$listener = KeyRotate::getListener();

// Call it either
$listener();
// or
$listener->handle();
```

### Models

[](#models)

The package discovers all Models in your `app()->path()` folder with `app()->getNamespace()` namespace.

But only then `app()->runningInConsole()`, so no unnecessary file scans happen during http requests.

#### Discover Models

[](#discover-models)

It's possible to discover Models with defined namespace that are not located in your `app()->path()` but in a custom directory.

```
$listener->withDir(base_path('src/Domain'), 'NameSpace\\Domain\\');
```

#### Include Models

[](#include-models)

It's possible to include Model to be updated with the listener without scanning directories.

```
$listener->withModel(CustomModel::class);
```

#### Exclude Models

[](#exclude-models)

It's possible to exclude Model from being updated with the listener.

```
$listener->withoutModel(User::class);
```

#### Exclude Model Fields

[](#exclude-model-fields)

It's possible to exclude some Model fields from being updated with the listener.

```
$listener->withoutModelFields(User::class, ['encrypted_text', 'encrypted_array']);
```

### Casts

[](#casts)

By default, the listener takes care of Laravel's predefined `encrypted` Casts.

```
[
    'encrypted',
    'encrypted:array',
    'encrypted:collection',
    'encrypted:object',
    AsEncryptedArrayObject::class,
    AsEncryptedCollection::class,
];
```

At your disposal there are helpers to reduce the above list or extend it with your custom cast that implements `Castable`, `CastsAttributes`, or `CastsInboundAttributes` interfaces.

```
// Exclude cast
$listener->withoutCast('encrypted:array');

// Include cast
$listener->withCast(CustomCast::class);
```

Tests
-----

[](#tests)

Run the entire test suite:

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for more information.

License
-------

[](#license)

The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance77

Regular maintenance activity

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~189 days

Total

3

Last Release

128d ago

Major Versions

1.0.1 → 2.0.02026-01-05

PHP version history (2 changes)1.0.0PHP ^8.2

2.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/19b0704d357e2e3bcbdbfd53e191d96eb4e0417e9b13e4a56f6f8367153eab32?d=identicon)[skulich](/maintainers/skulich)

---

Top Contributors

[![skulich](https://avatars.githubusercontent.com/u/170199581?v=4)](https://github.com/skulich "skulich (14 commits)")

---

Tags

laravelkeycommandrotatere-encrypt

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/sergkulich-laravel-key-rotate/health.svg)

```
[![Health](https://phpackages.com/badges/sergkulich-laravel-key-rotate/health.svg)](https://phpackages.com/packages/sergkulich-laravel-key-rotate)
```

###  Alternatives

[msurguy/honeypot

Honeypot spam prevention

4381.2M12](/packages/msurguy-honeypot)[spomky-labs/aes-key-wrap

AES Key Wrap for PHP.

5022.7M14](/packages/spomky-labs-aes-key-wrap)[enlightn/laravel-security-checker

A Laravel package to scan your dependencies for known security vulnerabilities.

51173.4k](/packages/enlightn-laravel-security-checker)[hackeresq/laravel-settings

Super simple key/value settings for Laravel 8+

312.1k](/packages/hackeresq-laravel-settings)[solution-forest/filament-firewall

This is a middleware for whitelisting/blacklisting for Filament Admin

457.8k3](/packages/solution-forest-filament-firewall)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
