gause/laravel-keyring
Composer 安装命令:
composer require gause/laravel-keyring
包简介
A driver-based secret manager for Laravel — injects secrets from OS keychains into your environment at runtime.
README 文档
README
A driver-based secret manager for Laravel. Injects secrets from your OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) into your Laravel environment at runtime — no secrets ever written to disk.
Works seamlessly with Laravel Herd.
The Problem
Local development secrets are a pain. You have .env files with database passwords, API keys, and tokens sitting in plaintext on your filesystem. They get accidentally committed, shared in Slack, or lost when switching machines.
Laravel Keyring solves this by storing your secrets in your operating system's native credential manager and injecting them into Laravel's environment at boot time. Your .env file only needs placeholder values — the real secrets live in your OS keychain.
Installation
composer require gause/laravel-keyring --dev
The package auto-discovers its service provider. To publish the config file:
php artisan vendor:publish --tag=keyring-config
Quick Start
1. Store a secret
php artisan keyring:set DB_PASSWORD
# You'll be prompted for the value with hidden input
Or with the value inline:
php artisan keyring:set STRIPE_SECRET sk_test_abc123
2. Use it in your app
Your secrets are automatically injected into $_ENV, $_SERVER, and putenv() at boot time. This means env('DB_PASSWORD') just works — even with Laravel Herd.
You can also access secrets directly:
use Keyring\Facades\Keyring; // Via facade $secret = Keyring::get('STRIPE_SECRET'); // Via helper $secret = keyring('STRIPE_SECRET'); $secret = keyring('STRIPE_SECRET', 'fallback-value'); // Via dependency injection public function __construct(KeyringManager $keyring) { $secret = $keyring->get('STRIPE_SECRET'); }
3. List your stored secrets
php artisan keyring:list
This shows key names only — never values.
Drivers
Note: OS-native drivers (Keychain, Secret Service, WinCred) store secrets under a namespace derived from your
APP_NAMEenvironment variable (defaults toLaravel). This means each project has its own isolated set of secrets. If you renameAPP_NAME, previously stored secrets won't be accessible under the new name. You can override the namespace explicitly via theKEYRING_NAMESPACEenv variable. File-based drivers (env, json) don't use the namespace — they are scoped by file path.
macOS Keychain (default on macOS)
Uses the native security CLI to store secrets in your login keychain. Secrets are stored as generic passwords with the service name {namespace}.{KEY}. (To inspect them manually, open Keychain Access — not the Passwords app.)
// config/keyring.php 'default' => 'keychain',
Linux Secret Service (default on Linux)
Uses secret-tool (gnome-keyring / KWallet) to store secrets. Requires the secret-tool package to be installed.
# Ubuntu/Debian sudo apt install libsecret-tools # Fedora sudo dnf install libsecret
'default' => 'secret-service',
Windows Credential Manager (default on Windows)
Uses cmdkey and PowerShell to store secrets in the Windows Credential Manager.
'default' => 'wincred',
Env File Driver
Reads/writes a separate .env.secrets file. Useful for CI/CD, Docker, or teammates without OS keychain setup.
'default' => 'env', 'drivers' => [ 'env' => [ 'path' => base_path('.env.secrets'), ], ],
JSON Driver
Stores secrets in an encrypted JSON file at storage/.keyring. Uses Laravel's Crypt facade for encryption.
'default' => 'json', 'drivers' => [ 'json' => [ 'path' => storage_path('.keyring'), 'encrypt' => true, // set to false for plain JSON ], ],
Laravel Herd Setup
Laravel Herd doesn't load .env files the same way as php artisan serve. Keyring bridges this gap by injecting secrets directly into the PHP environment at boot time.
- Store your secrets in the keychain:
php artisan keyring:set DB_PASSWORD your-db-password php artisan keyring:set REDIS_PASSWORD your-redis-password
- In your
.env, leave the values empty or use placeholders:
DB_PASSWORD= REDIS_PASSWORD=
- Ensure env injection is enabled (it is by default):
// config/keyring.php 'inject_into_env' => true,
That's it. Keyring will inject the real values from your keychain before Laravel reads the config.
Laravel Valet Setup
The setup is the same as Laravel Herd. If Keyring doesn't resolve your secrets from the keychain (returns null), it's likely because Valet starts PHP-FPM as root via sudo. Root has no access to your user's login keychain. Herd doesn't have this problem because it runs as a native macOS app in your user session.
To fix this, run PHP-FPM under your user instead of root — never use sudo when starting PHP via Homebrew services:
# Stop the root-owned PHP service sudo brew services stop php # Start PHP under your user (no sudo!) brew services start php # Restart Valet valet restart
After this, Valet's PHP-FPM workers run as your user and can access the login keychain normally.
Artisan Commands
keyring:get {key}
Retrieve and display a secret value.
php artisan keyring:get STRIPE_SECRET php artisan keyring:get STRIPE_SECRET --driver=json
keyring:set {key} {value?}
Store a secret. If value is omitted, you'll be prompted with hidden input.
php artisan keyring:set API_KEY php artisan keyring:set API_KEY sk_test_abc123 php artisan keyring:set API_KEY sk_test_abc123 --driver=json
keyring:forget {key}
Delete a secret (with confirmation).
php artisan keyring:forget OLD_API_KEY
keyring:list
List all stored key names (never values).
php artisan keyring:list php artisan keyring:list --driver=env
keyring:import {--file=.env}
Import secrets from a .env file. You'll be prompted to select which keys to import.
php artisan keyring:import php artisan keyring:import --file=.env.production
Env Injection
By default, Keyring injects all stored secrets into the environment at boot time. You can control this behavior:
// config/keyring.php // Disable injection entirely 'inject_into_env' => false, // Only inject specific keys 'inject_keys' => [ 'STRIPE_SECRET', 'DB_PASSWORD', 'REDIS_PASSWORD', ],
Important: Keyring never overwrites environment variables that are already set. If DB_PASSWORD is already present in $_ENV, Keyring won't touch it.
Performance
Env injection runs shell commands on every request. For OS-native drivers (Keychain, Secret Service, WinCred), listing explicit keys is significantly faster than discovering all secrets:
| Scenario | Avg overhead per request |
|---|---|
| Injection disabled | — |
Explicit inject_keys (1 key) |
+27 ms |
Explicit inject_keys (5 keys) |
+131 ms |
Explicit inject_keys (20 keys) |
+498 ms |
Empty inject_keys (discover all, 20 secrets) |
+506 ms |
Benchmarked on macOS Keychain. Each key adds ~25ms (one shell call to security find-generic-password).
For best performance, always list your keys explicitly:
'inject_keys' => [ 'STRIPE_SECRET', 'DB_PASSWORD', ],
Caching
For applications where ~25ms per key per request is too much overhead, Keyring provides an opt-in caching layer. Once enabled, resolved secrets are cached and subsequent requests skip the shell calls entirely.
// config/keyring.php 'cache' => [ 'enabled' => env('KEYRING_CACHE', false), 'driver' => env('KEYRING_CACHE_DRIVER', 'apcu'), // apcu, array 'ttl' => (int) env('KEYRING_CACHE_TTL', 3600), // seconds ],
Cache drivers:
| Driver | Storage | Persistence | Best for |
|---|---|---|---|
apcu |
Shared memory (APCu) | Across requests (within worker) | Local development with APCu installed |
array |
PHP array | Current request only | Testing |
Secrets are only ever cached in RAM — never written to disk. The APCu driver requires the APCu extension. If APCu is not available, caching is silently disabled and a warning is logged.
Installing APCu with Laravel Herd:
Herd ships with its own PHP binaries, so you need to compile the extension via Homebrew and register it in Herd's php.ini. See the Herd PHP Extensions docs for full details.
# 1. Install Homebrew PHP (needed for pecl/phpize) brew install php # 2. Compile APCu pecl install apcu # 3. Add to Herd's php.ini (adjust version number to match yours) echo "extension=/opt/homebrew/Cellar/php/$(php -r 'echo PHP_VERSION;')/pecl/$(php -r 'echo PHP_ZEND_VERSION;')/apcu.so" \ >> ~/Library/Application\ Support/Herd/config/php/85/php.ini # 4. Restart Herd, then verify php -m | grep apcu
Cache commands:
# Warm the cache (pre-resolve all secrets) php artisan keyring:cache:warm # Clear the cache php artisan keyring:cache:clear # Show cache status php artisan keyring:cache:status
Alternatives to caching: If you use php artisan config:cache, Laravel bakes resolved env() values into the cached config file — so secrets are only resolved once. Similarly, Laravel Octane keeps the application in memory, so secrets are resolved once per worker boot. In these setups, you may not need caching at all.
Community Drivers
You can register custom drivers using the extend() method, similar to Laravel Socialite:
use Keyring\Facades\Keyring; use Keyring\Contracts\Driver; // In a service provider boot() method Keyring::extend('vault', function ($app) { return new HashiCorpVaultDriver( url: config('keyring.drivers.vault.url'), token: config('keyring.drivers.vault.token'), ); });
Your custom driver must implement Keyring\Contracts\Driver:
use Keyring\Contracts\Driver; class HashiCorpVaultDriver implements Driver { public function get(string $key): ?string { /* ... */ } public function set(string $key, string $value): void { /* ... */ } public function forget(string $key): void { /* ... */ } public function has(string $key): bool { /* ... */ } public function all(): array { /* ... */ } }
Then use it:
Keyring::driver('vault')->get('DATABASE_URL');
Configuration Reference
return [ // Driver: auto, keychain, secret-service, wincred, env, json 'default' => env('KEYRING_DRIVER', 'auto'), // Namespace prefix for secrets 'namespace' => env('KEYRING_NAMESPACE', env('APP_NAME', 'Laravel')), // Throw exception on missing keys 'strict' => env('KEYRING_STRICT', false), // Inject secrets into $_ENV at boot 'inject_into_env' => env('KEYRING_INJECT', true), // Specific keys to inject (empty = all) 'inject_keys' => [], // Cache resolved secrets in RAM (opt-in, requires APCu) 'cache' => [ 'enabled' => env('KEYRING_CACHE', false), 'driver' => env('KEYRING_CACHE_DRIVER', 'apcu'), 'ttl' => (int) env('KEYRING_CACHE_TTL', 3600), ], 'drivers' => [ 'keychain' => [], 'secret-service' => [], 'wincred' => [], 'env' => [ 'path' => base_path('.env.secrets'), ], 'json' => [ 'path' => storage_path('.keyring'), 'encrypt' => true, ], ], ];
Testing
composer test # Run tests composer test:coverage # Run with coverage (90%+ required) composer analyse # PHPStan level max composer format:check # Laravel Pint style check composer ci # Run all checks
Security
- Secrets stored in OS keychains are protected by your user account and OS security mechanisms
- The JSON driver encrypts values using Laravel's
APP_KEYviaCrypt::encryptString() - The cache layer (APCu) stores values in RAM only — secrets are never written to disk
- Env injection never overwrites already-set environment variables
- The
keyring:listcommand never displays secret values - Add
.env.secretsandstorage/.keyringto your.gitignore
If you discover a security vulnerability, please email your@email.com instead of opening an issue.
Changelog
Please see CHANGELOG for recent changes.
Contributing
Please see CONTRIBUTING for details.
License
The MIT License (MIT). Please see License File for more information.
gause/laravel-keyring 适用场景与选型建议
gause/laravel-keyring 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 13 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 01 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「security」 「laravel」 「keychain」 「env」 「secrets」 「herd」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 gause/laravel-keyring 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 gause/laravel-keyring 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 gause/laravel-keyring 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Provide a way to secure accesses to all routes of an symfony application.
It's a barebone security class written on PHP
Joomla Keychain Package
Contao CMS integrity check for some files
A PHP security linter to detect insecure functions like var_dump, print_r, and other dangerous functions in your codebase
Alfabank REST API integration
统计信息
- 总下载量: 13
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 27
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-01