phpcq/gnupg
GnuPG wrapper and signature verification library used by the phpcq tool runner. Provides a lightweight API for interacting with GnuPG and validating signatures to support automated PHP code quality checks in CI pipelines.
Install the Package:
composer require phpcq/gnupg
Ensure the gnupg PHP extension is installed (pecl install gnupg or via system package manager).
Basic Initialization in Laravel:
use Phpcq\Gnupg\Gnupg;
$gnupg = new Gnupg();
$gnupg->setBinary(config('gnupg.binary_path', '/usr/bin/gpg')); // Configure in config/gnupg.php
First Use Case: Verify a Git Commit Signature in CI
$signature = file_get_contents(storage_path('app/signature.asc'));
$commitData = file_get_contents(storage_path('app/commit.txt'));
$fingerprint = config('gnupg.trusted_fingerprints.lead_developer');
$result = $gnupg->verify($signature, $commitData, $fingerprint);
if (!$result['valid']) {
throw new \RuntimeException("Invalid commit signature: {$result['error']}");
}
Laravel Service Provider Setup (app/Providers/GnupgServiceProvider.php):
use Illuminate\Support\ServiceProvider;
use Phpcq\Gnupg\Gnupg;
class GnupgServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Gnupg::class, function () {
$gnupg = new Gnupg();
$gnupg->setBinary(config('gnupg.binary_path'));
return $gnupg;
});
}
}
Register the Provider (config/app.php):
'providers' => [
// ...
App\Providers\GnupgServiceProvider::class,
],
use Illuminate\Support\Facades\Gnupg; // After creating a Facade
public function verifyCommitSignature()
{
$signature = file_get_contents(storage_path('app/signature.asc'));
$commitData = file_get_contents(storage_path('app/commit.txt'));
$fingerprint = config('gnupg.trusted_fingerprints.lead_developer');
$result = Gnupg::verify($signature, $commitData, $fingerprint);
if (!$result['valid']) {
event(new \App\Events\SignatureFailed($result['error']));
return false;
}
return true;
}
public function encryptConfig()
{
$recipientFingerprint = config('gnupg.recipient_fingerprint');
$sensitiveData = config('app.sensitive_data');
$encrypted = Gnupg::encrypt($sensitiveData, $recipientFingerprint);
file_put_contents(storage_path('app/encrypted_config.asc'), $encrypted);
return true;
}
public function decryptDeploymentData()
{
$encryptedData = file_get_contents(storage_path('app/encrypted_data.asc'));
$privateKey = file_get_contents(storage_path('app/private.key'));
$decrypted = Gnupg::decrypt($encryptedData, $privateKey);
return json_decode($decrypted, true);
}
// Import a public key
Gnupg::importKey(file_get_contents(storage_path('app/public.key')));
// List all keys
$keys = Gnupg::listKeys();
Create app/Facades/Gnupg.php:
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Gnupg extends Facade
{
protected static function getFacadeAccessor()
{
return 'gnupg';
}
}
Update GnupgServiceProvider to bind the Facade:
$this->app->bind('gnupg', function () {
return $this->app->make(Gnupg::class);
});
use Illuminate\Console\Command;
use App\Facades\Gnupg;
class ImportGpgKey extends Command
{
protected $signature = 'gpg:import {key_file}';
protected $description = 'Import a GPG public key';
public function handle()
{
$keyFile = $this->argument('key_file');
$result = Gnupg::importKey(file_get_contents($keyFile));
$this->info("Key imported: " . ($result ? 'Success' : 'Failed'));
}
}
use Closure;
use App\Facades\Gnupg;
class VerifyApiSignature
{
public function handle($request, Closure $next)
{
$signature = $request->header('X-Signature');
$data = $request->getContent();
$fingerprint = config('gnupg.api_trusted_fingerprint');
$result = Gnupg::verify($signature, $data, $fingerprint);
if (!$result['valid']) {
abort(403, 'Invalid signature');
}
return $next($request);
}
}
use App\Facades\Gnupg;
use App\Events\SignatureVerified;
public function handle(SignatureVerified $event)
{
// Log or notify on successful verification
\Log::info("Signature verified for {$event->fingerprint}");
}
use Illuminate\Support\Facades\Cache;
public function verifyWithCache($signature, $data, $fingerprint, $ttl = 3600)
{
$cacheKey = "gpg_verify_{$fingerprint}_{md5($data)}";
$cached = Cache::get($cacheKey);
if ($cached !== null) {
return $cached;
}
$result = Gnupg::verify($signature, $data, $fingerprint);
Cache::put($cacheKey, $result, $ttl);
return $result;
}
gpg command not found or incorrect path.$gnupg->setBinary('/usr/local/bin/gpg2'); // Use full path
which gpg in your environment.gpg --list-keys to confirm).config/gnupg.php:
'trusted_fingerprints' => [
'lead_developer' => 'ABCD1234EFGH5678',
],
setPassphrase():
$gnupg->setPassphrase(config('gnupg.private_key_passphrase'));
.env for production.$gnupg->setArmor(false); // Disable ASCII armor for binary data
Dockerfile:
RUN apt-get update && apt-get install -y gnupg
scripts/install-gnupg.sh).gpg: no valid OpenPGP data found.gpg --verify signature.asc file.txt.gpg --list-keys and updateHow can I help you explore Laravel packages today?