Documentation

Install

Licensing

Beacon is a paid self-hosted product. Each install validates a signed beacon.license file against an embedded ECDSA P-256 public key. Validation runs offline — Beacon does not phone home.

This page covers buying, installing, rotating, and the update window for 0.3.3-beta. It does not cover the cryptographic internals.

Buying a license

Licenses for Beacon are sold at apexcode.dev/beacon. Checkout runs through Polar. On completion you get an email with a link to your license portal, where you download the signed beacon.license file plus Docker and Composer install commands.

Tier 1 self-hosted: $149 one-time ($99 during beta).

The license is a one-time purchase and does not expire. The version you buy keeps running whether or not you upgrade.

Updates

Every license includes 12 months of updates from the purchase date. Updates land through your license portal — new tags on ghcr.io/apxcde/beacon and new packages on https://packages.apexcode.dev.

After the year, keep the install you have. New releases require a renewal. Your portal shows the date updates run through.

Installing your license

Drop the file at:

storage/app/beacon.license

The path is fixed (config/licensing.phplicense_path). On Docker installs, storage/ is a named volume, so the file persists across container restarts:

docker compose cp ./beacon.license app:/var/www/html/storage/app/beacon.license

On a Composer install from packages.apexcode.dev, copy the file into the project before first boot:

cp ./beacon.license storage/app/beacon.license

Restart the app container to force an immediate re-validation, or wait up to one validation cycle (default: daily).

Test mode

You do not need a license file to develop against a running Beacon with test keys.

Append _test to any API key. While the request carries a _test key, Beacon bypasses license validation entirely (ValidateLicenseOrTestMode) and simulates Twilio without making real calls.

This is the right mode for:

  • local development
  • CI and integration tests
  • evaluating Beacon before you send live SMS

It is not the right mode for production. A _test key is a permission boundary — anyone holding one can drive the system without a license.

Pulling ghcr.io/apxcde/beacon or installing from packages.apexcode.dev still uses the credentials from your license portal.

Validation behavior

Setting Default Effect
LICENSE_ENABLED true Master switch. Set to false only in development.
LICENSE_VALIDATION_FREQUENCY daily How often the cached validation result is refreshed. daily / hourly / always.
LICENSE_GRACE_PERIOD_DAYS 14 After a license expires, Beacon keeps serving requests for this many days while logging a warning.
LICENSE_HARDWARE_FINGERPRINTING false When true, binds the license to one machine. Off by default for self-hosted users.
LICENSE_AUDIT_LOGGING true Logs every validation event.
LICENSE_VERSION_CHECK false Refuses to run a major version above what the license was purchased for. Used for one-time licenses.
PRODUCT_VERSION unset Override for the version-check comparison.

LICENSE_PUBLIC_KEY — also configurable, but do not change it unless you are running a forked distribution. The default value is the public key used to sign every license sold at apexcode.dev/beacon.

What happens when validation fails

Situation Behavior
No license file present, _test key Allowed.
No license file present, live key 402 Payment Required from license middleware.
License signature invalid 402 Payment Required.
License expired, within grace period Allowed, with a warning logged.
License expired, past grace period 402 Payment Required.
License version below installed Beacon version (with LICENSE_VERSION_CHECK=true) 402 Payment Required.

The error response carries a JSON body explaining which check failed, so it is safe to surface the message in your tooling.

Rotating a license

To replace an existing license:

  1. Drop the new beacon.license file at storage/app/beacon.license, overwriting the old one — or run php artisan license:install <file>, which also keeps a timestamped backup of the previous license next to it (beacon.license.backup.<timestamp>).
  2. Restart the app container, or wait for the next validation cycle.

Renewals

Renewal extends the update window so the portal will issue newer image tags and Composer packages. The license file you already have keeps the purchased version running after the window closes.

Disabling licensing entirely

For development only:

LICENSE_ENABLED=false

This disables the middleware so any key (test or live) works. Do not ship this setting to production.

Buying source access

If you need to modify Beacon, white-label it, or have compliance requirements that prevent signed-binary models, contact ApexCode for a source-access license. That is a separate agreement and is not covered by the standard beacon.license file.

Raw markdown · llms.txt