ifabula / sevola-interceptor-helper
Laravel database interceptor for automatic field encryption/decryption using Sevola SDK
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Forks: 0
pkg:composer/ifabula/sevola-interceptor-helper
Requires
- php: ^8.2
- ifabula/sevola-sdk-php: *
- illuminate/database: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^10.0
This package is not auto-updated.
Last update: 2025-11-10 09:49:53 UTC
README
Laravel database interceptor for automatic field encryption/decryption using Sevola SDK.
Features
- 🔐 Automatic encryption/decryption of database fields
- 🎯 Configuration-driven (database table defines what to encrypt)
- 🚀 Easy integration with Laravel Eloquent models
- ⚡ Caching for performance
- 🔍 Support for FF1 format-preserving encryption
- 📝 Comprehensive logging for debugging
Installation
1. Install via Composer
composer require ifabula/sevola-interceptor-helper
2. Install Sevola SDK
composer require ifabula/sevola-sdk-php
3. Publish Configuration (Optional)
php artisan vendor:publish --tag=sevola-config
This creates config/sevola.php in your Laravel project.
4. Configure Environment Variables
Add to your .env file:
SEVOLA_API_KEY=your-api-key-here
SEVOLA_BASE_URL=http://localhost:8082
SEVOLA_CONFIG_DATABASE=amplio_encrypt_dev
SEVOLA_CONFIG_TABLE=mst_encryption_config
SEVOLA_LOGGING=true
SEVOLA_DEBUG=false
5. Register Service Provider (Laravel 10 and below)
For Laravel 11+, the service provider is auto-discovered. For older versions, add to config/app.php:
'providers' => [
// ...
Ifabula\SevolaInterceptor\SevolaServiceProvider::class,
],
Usage
Method 1: Using the HasEncryption Trait (Recommended)
Add the trait to your Eloquent models:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Ifabula\SevolaInterceptor\Traits\HasEncryption;
class User extends Model
{
use HasEncryption;
protected $table = 'mst_user_cms';
protected $fillable = [
'name',
'email',
'ROLE_NAME',
'MERCHANT_CODE',
];
}
That's it! Now when you save or retrieve users:
// Encryption happens automatically on save
$user = new User();
$user->name = 'John Doe';
$user->ROLE_NAME = 'Admin'; // This will be encrypted based on config
$user->MERCHANT_CODE = '12345'; // This will be encrypted based on config
$user->save();
// Decryption happens automatically on retrieval
$user = User::find(1);
echo $user->ROLE_NAME; // Automatically decrypted
echo $user->MERCHANT_CODE; // Automatically decrypted
Method 2: Manual Encryption/Decryption
If you need more control, use the services directly:
use Ifabula\SevolaInterceptor\Services\ConfigService;
use Ifabula\SevolaInterceptor\Services\EncryptionService;
// Get the services
$configService = app(ConfigService::class);
$encryptionService = app(EncryptionService::class);
// Check if encryption is configured for a table
if ($configService->hasEncryption('amplio_encrypt_dev', 'mst_user_cms')) {
// Get the config
$config = $configService->getConfig('amplio_encrypt_dev', 'mst_user_cms');
// Encrypt data
$data = [
'name' => 'John Doe',
'ROLE_NAME' => 'Admin',
'MERCHANT_CODE' => '12345',
];
$encrypted = $encryptionService->encryptData($data, $config);
// Decrypt data
$decrypted = $encryptionService->decryptData($encrypted, $config);
}
Configuration Table Schema
The interceptor reads configuration from a database table with this structure:
CREATE TABLE mst_encryption_config (
id INT PRIMARY KEY AUTO_INCREMENT,
config_name VARCHAR(255),
database_name VARCHAR(255),
table_name VARCHAR(255),
encrypted_columns JSON, -- Example: ["ROLE_NAME", "MERCHANT_CODE"]
status VARCHAR(50), -- 'ACTIVE' or 'INACTIVE'
encryption_algorithm VARCHAR(50), -- 'FF1', 'AES-GCM', etc.
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Example configuration:
{
"id": 1,
"config_name": "User CMS Encryption",
"database_name": "amplio_encrypt_dev",
"table_name": "mst_user_cms",
"encrypted_columns": "[\"ROLE_NAME\",\"MERCHANT_CODE\"]",
"status": "ACTIVE",
"encryption_algorithm": "FF1"
}
How It Works
For INSERT/UPDATE (Encryption)
- When you save a model with
HasEncryptiontrait, it triggers thesavingevent - The interceptor checks the config table to see if the table has encryption configured
- If configured and active, it encrypts the specified columns using Sevola SDK
- The encrypted data is then saved to the database
For SELECT (Decryption)
- When you retrieve a model with
HasEncryptiontrait, it triggers theretrievedevent - The interceptor checks the config table to see if the table has encryption configured
- If configured and active, it decrypts the specified columns using Sevola SDK
- The decrypted data is returned to your application
Caching
- Configuration is cached for 5 minutes (configurable via
SEVOLA_CACHE_TTL) - This prevents excessive database queries to the config table
- Cache is automatically cleared when you update the config
Advanced Usage
Clear Configuration Cache
use Ifabula\SevolaInterceptor\Services\ConfigService;
$configService = app(ConfigService::class);
// Clear cache for specific table
$configService->clearCache('amplio_encrypt_dev', 'mst_user_cms');
// Clear all config cache
$configService->clearCache();
Get All Active Configs
use Ifabula\SevolaInterceptor\Services\ConfigService;
$configService = app(ConfigService::class);
$configs = $configService->getAllActiveConfigs();
foreach ($configs as $config) {
echo "Table: {$config->tableName}, Columns: " . implode(', ', $config->encryptedColumns);
}
Query Builder (Without Eloquent)
For raw queries or query builder, you'll need to handle encryption manually:
use Illuminate\Support\Facades\DB;
use Ifabula\SevolaInterceptor\Services\ConfigService;
use Ifabula\SevolaInterceptor\Services\EncryptionService;
$configService = app(ConfigService::class);
$encryptionService = app(EncryptionService::class);
$config = $configService->getConfig('amplio_encrypt_dev', 'mst_user_cms');
if ($config) {
// Encrypt before insert
$data = ['ROLE_NAME' => 'Admin', 'MERCHANT_CODE' => '12345'];
$encrypted = $encryptionService->encryptData($data, $config);
DB::table('mst_user_cms')->insert($encrypted);
// Decrypt after select
$rows = DB::table('mst_user_cms')->get();
foreach ($rows as $row) {
$decrypted = $encryptionService->decryptData((array)$row, $config);
// Use $decrypted...
}
}
Troubleshooting
Encryption Not Working
- Check if
SEVOLA_API_KEYis set in.env - Verify the config table has an ACTIVE entry for your database and table
- Enable logging:
SEVOLA_LOGGING=trueandSEVOLA_DEBUG=true - Check Laravel logs:
tail -f storage/logs/laravel.log
Performance Issues
- Increase cache TTL:
SEVOLA_CACHE_TTL=600(10 minutes) - Ensure your config table is indexed on
database_nameandtable_name - Use Redis for caching instead of file cache
Column Not Being Encrypted
- Verify the column name matches exactly (case-sensitive) in the config table
- Check that the config status is 'ACTIVE'
- Ensure the model uses the
HasEncryptiontrait
Requirements
- PHP 8.2 or higher
- Laravel 11.0 or higher (or Laravel 12.0)
- Sevola SDK PHP
- Database with encryption config table
License
MIT License
Support
For issues and questions, please open an issue on GitLab.