Documentation

Everything you need to protect, license, and deploy PHP applications with CompileLock.

1 Overview

CompileLock protects your PHP source code by compiling it into encrypted bytecode that runs on a custom VM. Your customers can run the application without having access to the original source.

How it works

  1. Protect — You run the CLI to compile PHP files into encrypted bytecode. This is done once per release.
  2. License — You create licenses in the dashboard for each customer. Licenses are separate from the protected code.
  3. Ship — You deliver the same protected files to every customer.
  4. Activate — When the customer deploys your app, they enter their license key on an activation screen. The runtime validates the license before starting the application.
Key concept

Protection and licensing are separate steps. You protect your code once. Then you create as many licenses as you need — each with different domains, expiry dates, and activation limits. No need to re-protect for each customer.

Requirements

  • PHP 8.1 or higher
  • CompileLock PHP extension on the target server
  • A CompileLock account (free tier available)

2 Installation

CLI Tool (your machine)

curl -fsSL https://compilelock.com/install.sh | sh

Installs the CLI to ~/.compilelock/ and links to /usr/local/bin/compilelock. Requires PHP 8.1+.

Authenticate

Generate an API key from the dashboard:

compilelock auth --token="YOUR_API_KEY"

Always wrap the token in quotes — it contains a | character. Stored in ~/.compilelock/config.json. One-time setup per machine.

PHP Extension (customer's server)

The runtime extension must be installed on any server running protected code:

# Coming soon — PHP extension for bytecode execution
php -m | grep compilelock

3 Protecting Files

Protection compiles your PHP source into encrypted bytecode. The output is the same for every customer — licensing is handled separately.

Full project

compilelock protect ./app --project=1 --output=./dist

Selective protection

# Only specific directories
compilelock protect ./app/Services ./app/Http/Controllers --project=1
# Exclude patterns
compilelock protect ./app --project=1 --exclude="views,config"

Configuration file

Create compilelock.json for repeatable builds:

{
  "project_id": "1",
  "include": ["app/Services", "app/Http/Controllers"],
  "exclude": ["app/Http/Controllers/Api/WebhookController.php"],
  "output": "./dist"
}
compilelock protect

4 Licensing

Licenses are created in the dashboard and are independent from the protected code. You protect once, then create as many licenses as you need.

License options

  • Domain lock — restrict to specific domains (optional). If set, the license will only work on the specified domain.
  • Expiry date — set when the license expires (optional). After this date, the activation screen will be shown again.
  • Max activations — limit the number of installations (required). Each time a customer activates a license on a new server, the count increases.
  • Revoke — disable a license at any time from the dashboard. The next phone-home check (every 24h) will invalidate the local license.

API examples

You can also manage licenses via the API. All endpoints require a Bearer token (your API key).

Create a license with all options
curl -X POST https://compilelock.com/api/licenses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": 1,
    "domain": "client.example.com",
    "expires_at": "2027-01-01",
    "max_activations": 3
  }'
Create a license without domain lock or expiry
curl -X POST https://compilelock.com/api/licenses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": 1,
    "max_activations": 1
  }'
Revoke a license
curl -X POST https://compilelock.com/api/licenses/1/revoke -H "Authorization: Bearer YOUR_API_KEY"

Workflow

  1. Create a project in the dashboard
  2. Run compilelock protect to build the protected version
  3. Create a license for your customer in the dashboard
  4. Ship the protected files + give the customer their license key
  5. Customer deploys and enters the license key on the activation screen

5 Activation & Runtime

First launch — activation screen

When a customer deploys your protected application for the first time, the CompileLock runtime shows an activation screen instead of your app:

Activate Your License
This installation must be activated before the application can be used.
CL-XXXXXX-XXXXXX-XXXXXX
Activate
Need help? Contact your vendor.

The customer enters the license key you provided. The runtime validates it against the CompileLock API, checking domain, expiry, and activation count. On success, the license is stored locally and the app starts.

Subsequent requests — license gate

On every boot or request, the runtime:

  1. Reads the local license file
  2. Verifies the HMAC signature (tamper-proof)
  3. Checks domain matches $_SERVER['HTTP_HOST']
  4. Checks expiry date
  5. Periodically validates with the CompileLock API (phone-home)
  6. If valid → runs the app. If invalid → shows error.
Important

The entire application is behind a license gate. Without a valid license, no routes, controllers, or pages are accessible. The activation screen is the only thing visible.

What happens when a license is revoked?

When you revoke a license from the dashboard, the next phone-home check will invalidate the local license. The app will stop working and show an error screen.

6 API Reference

All API requests require a Bearer token from API Keys.

Create a license

curl -X POST https://compilelock.com/api/licenses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_id":1,"domain":"client.com","max_activations":3}'

List licenses

curl https://compilelock.com/api/licenses -H "Authorization: Bearer YOUR_API_KEY"

Revoke a license

curl -X POST https://compilelock.com/api/licenses/42/revoke -H "Authorization: Bearer YOUR_API_KEY"

7 CLI Reference

Command Description
compilelock auth --token="KEY"Authenticate with your API key
compilelock protect ./pathProtect files in the given path
compilelock protectProtect using compilelock.json config
--output=./distOutput directory for protected files
--exclude="views,config"Exclude files/folders matching patterns
compilelock versionShow CLI version