dskripchenko / php-pdf-cloud-kms
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.
Requires
- php: ^8.2
- ext-json: *
- ext-openssl: *
- dskripchenko/php-pdf: ^1.19
Requires (Dev)
- aws/aws-sdk-php: ^3.300
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.5
Suggests
- aws/aws-sdk-php: Required for AwsKmsSigner
Provides
None
Conflicts
None
Replaces
None
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 Β· Π ΡΡΡΠΊΠΈΠΉ Β· δΈζ
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 passclientOptions:, or build theKmsClientyourself and usenew AwsKmsSigner($client, β¦). - The key:
KeyUsage: SIGN_VERIFY,RSA_2048/3072/4096orECC_NIST_P256/P384/P521. The caller needskms:Sign. - The algorithm follows the key and the digest:
RSASSA_PKCS1_V1_5_SHA_256,ECDSA_SHA_384β¦ sendDigest: falsesends the signed attributes themselves (MessageType: RAW, up to 4 KB) instead of their digest β for emulators withoutDIGEST, 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 throughnew CallbackToken(fn () => β¦)(google/auth, for one). - The key version: purpose
ASYMMETRIC_SIGN, anEC_SIGN_*orRSA_SIGN_PKCS1_*algorithm. The algorithm fixes the digest: forβ¦_SHA512keys passdigest: DigestAlgorithm::Sha512. RSA-PSS keys are not supported. The caller needsroles/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) orAzureToken::clientCredentials($tenant, $clientId, $secret), ornew CallbackToken(fn () => β¦). - Keys:
RSA,RSA-HSM,EC,EC-HSM(P-256, P-384, P-521), Managed HSM too. The identity needs thesignkey permission or the Key Vault Crypto User role, andgeton certificates forfromCertificate().
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-opensslandext-json, anddskripchenko/php-pdf1.19 or later (Composer installs it). aws/aws-sdk-phpforAwsKmsSigneronly. 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 lacksMessageType: DIGEST, so the live run usessendDigest: false; theDIGESTcall 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 β sfor 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.