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
- Protect — You run the CLI to compile PHP files into encrypted bytecode. This is done once per release.
- License — You create licenses in the dashboard for each customer. Licenses are separate from the protected code.
- Ship — You deliver the same protected files to every customer.
- 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.
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)
Installs the CLI to ~/.compilelock/ and links to /usr/local/bin/compilelock. Requires PHP 8.1+.
Authenticate
Generate an API key from the dashboard:
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:
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
Selective protection
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"
}
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).
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
}'
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
}'
Workflow
- Create a project in the dashboard
- Run
compilelock protectto build the protected version - Create a license for your customer in the dashboard
- Ship the protected files + give the customer their license key
- 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:
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:
- Reads the local license file
- Verifies the HMAC signature (tamper-proof)
- Checks domain matches
$_SERVER['HTTP_HOST'] - Checks expiry date
- Periodically validates with the CompileLock API (phone-home)
- If valid → runs the app. If invalid → shows error.
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
List licenses
Revoke a license
7 CLI Reference
| Command | Description |
|---|---|
| compilelock auth --token="KEY" | Authenticate with your API key |
| compilelock protect ./path | Protect files in the given path |
| compilelock protect | Protect using compilelock.json config |
| --output=./dist | Output directory for protected files |
| --exclude="views,config" | Exclude files/folders matching patterns |
| compilelock version | Show CLI version |