承接 illuma-law/laravel-vault-cipher 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

illuma-law/laravel-vault-cipher

最新稳定版本:v0.1.4

Composer 安装命令:

composer require illuma-law/laravel-vault-cipher

包简介

Tenant-aware streaming encryption for Laravel.

README 文档

README

Latest Version on Packagist GitHub Tests Action Action Status Total Downloads

Tenant-aware streaming encryption for Laravel applications.

In multi-tenant (B2B) applications, sharing a single application-wide encryption key (the standard Laravel APP_KEY) creates a massive blast radius if compromised. Vault Cipher solves this by encrypting each tenant's data with their own unique encryption key.

Features

  • Tenant-Specific Keys: Encrypt and decrypt data dynamically using unique keys per tenant.
  • File Streaming Encryption: Securely encrypt large files (e.g., PDFs, videos) on the fly without exhausting PHP memory limits.
  • Eloquent Casts: Drop-in TenantEncrypted casts that automatically resolve the correct key based on the model's relationship.
  • Provider Interface: You control how tenant keys are fetched and stored (Database, HashiCorp Vault, AWS KMS, etc.).

Installation

You can install the package via composer:

composer require illuma-law/laravel-vault-cipher

Publish the config file:

php artisan vendor:publish --tag="vault-cipher-config"

Configuration

The configuration file allows you to define:

  • chunk_size: The chunk size in bytes for streaming encryption (default: 64KB).
  • default_disk: The default filesystem disk for encrypted files (default: local).
  • key_provider: The class responsible for resolving tenant keys.

The Key Provider

You must create a class that implements the TenantKeyProvider interface to tell the package how to resolve an encryption key for a given tenant ID:

namespace App\Services;

use IllumaLaw\VaultCipher\Contracts\TenantKeyProvider;
use App\Models\Tenant;

class MyTenantKeyProvider implements TenantKeyProvider
{
    public function getKey(int|string $tenantId): string
    {
        // Example: Retrieve the key from the database and decrypt it using the master APP_KEY
        $tenant = Tenant::findOrFail($tenantId);
        return decrypt($tenant->encrypted_data_key);
    }
}

Then, register your provider in config/vault-cipher.php:

    'key_provider' => \App\Services\MyTenantKeyProvider::class,

The package provides a VaultKeyGenerator to create compatible encryption keys:

use IllumaLaw\VaultCipher\Support\VaultKeyGenerator;

// Returns a base64-encoded 32-byte key (AES-256 compatible)
$team->encryption_key = VaultKeyGenerator::generate();

Usage & Integration

String Encryption

You can encrypt simple strings dynamically using the Facade:

use IllumaLaw\VaultCipher\Facades\TenantEncryptionManager;

$tenantId = 123;
$encrypted = TenantEncryptionManager::encryptString($tenantId, 'highly sensitive medical data');

$decrypted = TenantEncryptionManager::decryptString($tenantId, $encrypted);

File Streaming Encryption

Storing large files securely requires streaming. Vault Cipher chunk-encrypts the file in memory while writing it to disk.

use IllumaLaw\VaultCipher\Facades\TenantEncryptionManager;

$tenantId = 123;

// Stream content directly to an encrypted file on your configured disk
TenantEncryptionManager::store($tenantId, 'contracts/agreement-1.pdf', $binaryContent);

// Retrieve and stream the decrypted content back (e.g., for downloading)
$content = TenantEncryptionManager::get($tenantId, 'contracts/agreement-1.pdf');

For streaming operations that require temporary access to decrypted files:

use IllumaLaw\VaultCipher\Facades\TenantEncryptionManager;

// Decrypts to a temp path, executes callback, then cleans up the temp file
TenantEncryptionManager::usingDecryptedTempPath(
    tenantId: $tenantId,
    path: 'contracts/agreement-1.pdf',
    callback: function (string $tempPath) {
        // Process the decrypted file (e.g., pass to OCR, thumbnail generation, etc.)
        return processFile($tempPath);
    },
    disk: 's3'
);

You can also encrypt existing files already present on the disk in place:

TenantEncryptionManager::encryptExistingPath($tenantId, 'existing/unencrypted_file.txt');

Eloquent Casts

For database columns, use the provided Eloquent casts to automate encryption and decryption when saving or retrieving models.

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use IllumaLaw\VaultCipher\Casts\TenantEncrypted;
use IllumaLaw\VaultCipher\Casts\TenantEncryptedArray;
use IllumaLaw\VaultCipher\Contracts\TenantCipherable;

class Document extends Model implements TenantCipherable
{
    protected $casts = [
        'content' => TenantEncrypted::class,
        'metadata' => TenantEncryptedArray::class, // Handles arrays/JSON
    ];

    /**
     * Required by TenantCipherable so the Cast knows which key to use.
     */
    public function getTenantIdForCipher(): int|string|null
    {
        // Return the foreign key or relation ID that identifies the tenant
        return $this->team_id; 
    }
}

If your model doesn't implement TenantCipherable, the cast will attempt to look for a team_id or tenant_id property automatically as a fallback.

Key Rotation

When rotating tenant encryption keys, you need to re-encrypt existing data. The package provides TenantKeyRotator for this purpose:

use IllumaLaw\VaultCipher\Facades\TenantEncryptionManager;
use IllumaLaw\VaultCipher\Support\TenantKeyRotator;

// Build encrypters from raw keys during rotation
$oldKey = base64_decode($team->encryption_key);
$newKey = base64_decode(VaultKeyGenerator::generate());

$rotator = new TenantKeyRotator(
    oldEncrypter: TenantEncryptionManager::encrypterForRawKey($oldKey),
    newEncrypter: TenantEncryptionManager::encrypterForRawKey($newKey),
    oldFileEncrypter: TenantEncryptionManager::fileEncrypterForRawKey($oldKey),
    newFileEncrypter: TenantEncryptionManager::fileEncrypterForRawKey($newKey),
);

// Re-encrypt a string value (handles passthrough if decryption fails)
$reEncrypted = $rotator->rotateString($ciphertext);

// Re-encrypt a file on disk (detects chunk vs string encryption)
$rotator->rotateFileOnDisk($disk, 'contracts/agreement-1.pdf');

Testing

Run the test suite:

composer test

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 33
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-20

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固