Search by

dskripchenko / php-pdf-cloud-kms

dskripchenko

Cloud KMS signers for dskripchenko/php-pdf: sign PDFs (PAdES, RSA and ECDSA) with keys held by AWS KMS, Google Cloud KMS or Azure Key Vault β€” the key never leaves the cloud.

Package info

github.com/dskripchenko/php-pdf-cloud-kms

pkg:composer/dskripchenko/php-pdf-cloud-kms

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-10-18 14:50 UTC

This package is auto-updated.

Last update: 2026-10-18 16:00:53 UTC


README

Sign PDFs with dskripchenko/php-pdf using a key held by a cloud KMS: AWS KMS, Google Cloud KMS (and Cloud HSM), Azure Key Vault (and Managed HSM). php-pdf computes the digest, the service signs it; the key never leaves the cloud and the document never leaves your process. The result is a PAdES signature with RSA or ECDSA.

🌐 English Β· Deutsch Β· Русский Β· δΈ­ζ–‡

Tests Packagist License: MIT PHP

The certificate

A KMS holds a key pair, not a certificate. Get one issued for the key's public key β€” by your CA, or a qualified provider β€” and pass it as certificatePem. Azure Key Vault can hold the certificate itself; then AzureKeyVaultSigner::fromCertificate() reads both.

Every signer verifies the returned signature against the certificate before handing it to php-pdf, so a key that does not belong to the certificate, or a key whose algorithm uses another digest, fails with a clear error instead of producing a PDF no reader accepts.

AWS KMS

use Dskripchenko\PhpPdf\Pdf\Signature\PdfSigner;
use Dskripchenko\PhpPdf\Pdf\SignatureConfig;
use Dskripchenko\PhpPdfCloudKms\Aws\AwsKmsSigner;

$signer = AwsKmsSigner::create('alias/pdf-signing', $certificatePem, region: 'eu-central-1');

$signed = PdfSigner::fromBytes($pdf)->sign(new SignatureConfig(signer: $signer, timestampAuthority: $tsa));
  • Needs aws/aws-sdk-php. Credentials come from the SDK's default chain β€” environment, profile, ECS/EC2 role, IRSA β€” or pass clientOptions:, or build the KmsClient yourself and use new AwsKmsSigner($client, …).
  • The key: KeyUsage: SIGN_VERIFY, RSA_2048/3072/4096 or ECC_NIST_P256/P384/P521. The caller needs kms:Sign.
  • The algorithm follows the key and the digest: RSASSA_PKCS1_V1_5_SHA_256, ECDSA_SHA_384…
  • sendDigest: false sends the signed attributes themselves (MessageType: RAW, up to 4 KB) instead of their digest β€” for emulators without DIGEST, such as moto.

Google Cloud KMS

use Dskripchenko\PhpPdfCloudKms\Google\GoogleKmsSigner;
use Dskripchenko\PhpPdfCloudKms\Google\GoogleToken;

$signer = new GoogleKmsSigner(
    'projects/my-project/locations/europe-west3/keyRings/pdf/cryptoKeys/signing/cryptoKeyVersions/1',
    $certificatePem,
    GoogleToken::fromMetadataServer(),        // GCE, GKE, Cloud Run, Cloud Functions
);
  • REST API, no Google SDK needed. Tokens: GoogleToken::fromMetadataServer(), GoogleToken::fromServiceAccountJson($json), or any source through new CallbackToken(fn () => …) (google/auth, for one).
  • The key version: purpose ASYMMETRIC_SIGN, an EC_SIGN_* or RSA_SIGN_PKCS1_* algorithm. The algorithm fixes the digest: for …_SHA512 keys pass digest: DigestAlgorithm::Sha512. RSA-PSS keys are not supported. The caller needs roles/cloudkms.signer.
  • The digest is sent with its CRC32C, and the service's integrity flag is checked.

Azure Key Vault

use Dskripchenko\PhpPdfCloudKms\Azure\AzureKeyVaultSigner;
use Dskripchenko\PhpPdfCloudKms\Azure\AzureToken;

// A Key Vault certificate: the certificate and its key in one place.
$signer = AzureKeyVaultSigner::fromCertificate('https://my-vault.vault.azure.net', 'pdf-signing', AzureToken::managedIdentity());

// A bare key, with the certificate kept elsewhere.
$signer = new AzureKeyVaultSigner('https://my-vault.vault.azure.net/keys/pdf/0123abcd…', $certificatePem, $token);
  • REST API, no Azure SDK needed. Tokens: AzureToken::managedIdentity() (VMs, AKS, App Service, Container Apps; a user-assigned identity by its client id) or AzureToken::clientCredentials($tenant, $clientId, $secret), or new CallbackToken(fn () => …).
  • Keys: RSA, RSA-HSM, EC, EC-HSM (P-256, P-384, P-521), Managed HSM too. The identity needs the sign key permission or the Key Vault Crypto User role, and get on certificates for fromCertificate().

Common options

Argument Default Meaning
certificatePem β€” The certificate for the key: PEM or a Certificate
chainPem [] Intermediate certificates to embed β€” a PEM bundle or a list
digest by the key SHA-256 for RSA and P-256, SHA-384 for P-384, SHA-512 for P-521
transport PHP streams Google and Azure: your HTTP client, proxy or retries through php-pdf's HttpTransport

Failures are KmsException with the HTTP $status and the service's $errorCode (AccessDeniedException, PERMISSION_DENIED, Forbidden…); the message explains the common ones β€” the missing permission or role, an unknown or disabled key, an expired token, a digest that does not match the key.

Requirements

  • PHP 8.2+ with ext-openssl and ext-json, and dskripchenko/php-pdf 1.19 or later (Composer installs it).
  • aws/aws-sdk-php for AwsKmsSigner only. Google Cloud KMS and Azure Key Vault need no SDK: their REST APIs are called through php-pdf's HTTP transport.
  • Outbound HTTPS to the service (and to the token endpoint).

How it was checked

  • AWS KMS β€” live against moto (an AWS emulator) in Docker: RSA-2048, RSA-3072, P-256 and P-384 keys created in the emulator, certificates issued for their public keys, PDFs signed and validated by php-pdf and poppler's pdfsig. CI runs it on every change; see docker/README.md. moto lacks MessageType: DIGEST, so the live run uses sendDigest: false; the DIGEST call is covered by unit tests against the SDK's mock handler.
  • Google Cloud KMS and Azure Key Vault have no emulators. The signers are tested against fakes of their REST APIs that sign with real keys β€” the request format, the response decoding (DER for Google, r β€– s for Azure), the errors and the tokens β€” not against the live services.

The php-pdf family

Package What it adds
php-pdf The core: HTML with CSS or a builder to PDF, read, merge, fill forms, sign and validate.
laravel-php-pdf Laravel bridge: a Blade view straight to PDF, response()->pdf(), signing from config.
php-pdf-fonts-liberation Liberation Sans, Serif and Mono, metric-compatible with Arial, Times New Roman and Courier New (OFL, kept out of the MIT core).
php-pdf-cryptopro Signs with a key in CryptoPro CSP on the server: GOST R 34.10-2012, Russian qualified signatures.
php-pdf-pkcs11 Signs with a key on an HSM, a smart card or a USB token, through PKCS#11.
php-pdf-cloud-kms (this package) Signs with a key in AWS KMS, Google Cloud KMS or Azure Key Vault.

License

MIT β€” see LICENSE.