Skip to content
New PHP 8.5 loader ready — start a free 3-day trial, no card required
Licensing 8 min read • June 2025

How to License PHP Software with Domain Lock and Expiry

Encoding your PHP source code protects it from being read. Licensing controls where and for how long it can run. This article explains how Ed25519 cryptographic licensing works in practice — issuing per-client licenses, binding them to domains or IPs, setting expiration dates, and handling renewals without manual intervention.

Why Licensing Matters Beyond Encoding

Encoding prevents your source code from being read. But without licensing, a client who receives your encoded application can copy it to any number of servers, share it with competitors, or run it indefinitely after their subscription lapses.

A proper licensing system answers three questions at runtime: Is this the authorized domain? Has the license expired? Has the license been tampered with? PHPcube answers all three cryptographically — no network call required.

How Ed25519 Licensing Works

Each license.lic file contains two layers:

Inner payload (AES-256-CBC encrypted)

Contains: client name, authorized domains, IP restrictions, expiry date, product key, and creation timestamp. Encrypted with your vendor master key.

Outer signature (Ed25519)

The entire encrypted payload is signed with your Ed25519 private key. The loader verifies this signature using your public key, which is compiled into phpcube.so. If a single byte of the license file changes, verification fails instantly.

This means a client cannot extend their own expiry date, add domains, or forge a license — they do not have your private key, and the public key embedded in the loader will reject any tampered file.

Issuing a Domain-Locked License

From the customer portal, or via the CLI:

./phpcube-cli license \
  --client="Acme Corp" \
  --domain="acme.com,*.acme.com" \
  --expires="2026-12-31" \
  --product-key="$KEY" \
  --key-dir=keys \
  --out=license.lic

Key parameters:

  • --domain Comma-separated list. Supports exact domains (acme.com) and wildcards (*.acme.com).
  • --expires Date in YYYY-MM-DD format, or lifetime for no expiry.
  • --product-key The secret key used to encrypt your PHP files. The loader derives the decryption key from this.
  • --client Client name embedded in the license payload for identification.

License Enforcement at Runtime

When a protected PHP file is executed, the loader performs these checks in sequence before any PHP code runs:

  1. 1 Locate license.lic — searches the script directory, walks up to 5 parent directories, checks $_SERVER['DOCUMENT_ROOT'], and reads phpcube.license_path from php.ini.
  2. 2 Verify Ed25519 signature — if the file has been modified in any way, execution stops here.
  3. 3 Decrypt payload — AES-256-CBC decryption using the vendor master key to reveal the license contents.
  4. 4 Check domain — compares $_SERVER['HTTP_HOST'] against the authorized domain list. Wildcards are matched correctly.
  5. 5 Check expiry — compares current date against the expiry field. A 7-day grace period is built in to handle renewal delays.
  6. ✓ Execute — the product key is extracted, the PHP payload is decrypted in RAM, and execution proceeds normally.

All of this happens in native C inside the Zend extension — no PHP userland code, no disk writes, no network calls.

Handling Renewals Automatically

When a client renews their subscription, you issue a new license.lic with an updated expiry date. The loader auto-discovers the file — no server restart required. The 7-day grace period means a client's application keeps running even if their renewal is a few days late.

For fully automated renewals, use the REST API to issue a new license from your billing system the moment a payment is confirmed:

POST /api/issue
X-API-Key: your-api-key
Content-Type: application/json

{
  "client": "Acme Corp",
  "domain": "acme.com,*.acme.com",
  "expires": "2027-12-31",
  "product_key": "your-product-key"
}

The API returns the signed license.lic binary. Deploy it to the client server via rsync, SFTP, or your own deployment pipeline.

Displaying License Info in Your Application

Call phpcube_license_info() anywhere in your PHP code to surface license details in your admin dashboard:

$info = phpcube_license_info();
echo 'Licensed to: ' . $info['client'] . PHP_EOL;
echo 'Expires: '     . $info['expires'] . PHP_EOL;
echo 'Days remaining: ' . $info['days_remaining'] . PHP_EOL;

Key Takeaways

  • ✓ Ed25519 signatures make licenses tamper-proof — clients cannot modify domain or expiry fields
  • ✓ Domain lock and wildcard support covers single domains and entire subdomains
  • ✓ All checks happen in native C — no network calls, works fully offline
  • ✓ 7-day grace period prevents disruption during renewal delays
  • ✓ REST API enables fully automated license issuance from your billing system

Start issuing cryptographic licenses today

Free 3-day trial — no payment required. Full licensing API included.

Related Articles

Start free Loader
✓ Copied!