Skip to content

This guide covers how to manage licenses for your Synqly Embedded deployment. You'll learn how to generate sub-licenses, inspect license files, verify licenses, and handle renewals.


Overview

The Synqly Embedded container image includes built-in license management. All license operations — generating sub-licenses, inspecting license metadata, and verifying license validity — are performed using the same container image that runs your service. No additional tools are required.

Licenses use a two-level model:

  1. Primary license — issued by Synqly for your organization. Contains your encrypted credentials and defines the maximum license duration.
  2. Sub-license — generated by you from the primary license. Each sub-license is tied to a specific deployment instance and has its own expiration date (which cannot exceed the primary license expiration).

This model lets you provision time-limited individual deployments for your customers without contacting Synqly, while Synqly retains control over the overall license duration.


What You'll Receive

When Synqly provisions your license, you will receive two items:

  1. A primary license file - a JSON file containing your license details and encrypted credentials.
  2. A passphrase — this passphrase unlocks the credentials inside your primary license so you can generate sub-licenses for your customers when necessary.

Keep both items secure. Ideally, the primary license file and passphrase should not be stored together.


Quick Start

Below shows the typical workflow from receiving your license to running a licensed deployment.

Before running any of these commands, save the primary license as a JSON file to your current working directory with name primary-license.json.

First, you can verify the validity of your primary license:

docker run --rm \
  -v ./primary-license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-verify /etc/synqly/license.json

Next, you can generate a sub-license for customer. This will write the sub-license to the licenses/ directory in your current working directory.

# 1. Generate a sub-license for a specific deployment
mkdir -p licenses
docker run --rm \
  -e SYNQLY_LICENSE_PASSPHRASE="$SYNQLY_PASSPHRASE" \
  -v ./primary-license.json:/etc/synqly/primary-license.json:ro \
  -v ./licenses:/out \
  quay.io/synqly/embedded:latest \
  --license-generate /etc/synqly/primary-license.json \
  --license-expires 2027-06-01 \
  --license-instance-id prod-east-1 \
  --license-output /out/sub-license.json

# 2. Verify the sub-license is valid
docker run --rm \
  -v ./licenses/sub-license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-verify /etc/synqly/license.json

# 3. Deploy the sub-license with the Embedded service
docker run \
  -v ./licenses/sub-license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest

Each of these steps is explained in detail below.


Generating a Sub-License

Use the --license-generate flag to create a sub-license from your primary license. The sub-license is what you deploy alongside the Embedded service. This is used when you deploy Embedded alongside your application in a customer environment, such as in an air gapped deployment. You should generate a unique sub-license for each of your on-prem customers that include Embedded.

The passphrase is read from the SYNQLY_LICENSE_PASSPHRASE environment variable. This avoids exposing the passphrase in process listings or shell history.

Usage:

docker run --rm \
  -e SYNQLY_LICENSE_PASSPHRASE="$SYNQLY_PASSPHRASE" \
  -v ./primary-license.json:/etc/synqly/primary-license.json:ro \
  -v ./licenses:/out \
  quay.io/synqly/embedded:latest \
  --license-generate /etc/synqly/primary-license.json \
  --license-expires 2027-06-01 \
  --license-instance-id prod-east-1 \
  --license-output /out/sub-license.json

Flags:

FlagRequiredDescription
--license-generateYesPath to your primary license file (inside the container)
--license-expiresYesExpiration date for this sub-license (YYYY-MM-DD format)
--license-instance-idYesAn identifier for this deployment (e.g., prod-east-1, staging)
--license-outputYesPath to write the generated sub-license file (inside the container)

Environment variables:

VariableRequiredDescription
SYNQLY_LICENSE_PASSPHRASEYesPassphrase provided by Synqly for the primary license

Rules:

  • The sub-license expiration date cannot be later than the primary license expiration date.
  • The sub-license expiration date cannot be in the past.
  • The primary license itself must not be expired.
  • The passphrase must match the one provided by Synqly.

Example:

$ docker run --rm \
    -e SYNQLY_LICENSE_PASSPHRASE="correct-horse-battery-staple" \
    -v ./primary-license.json:/etc/synqly/primary-license.json:ro \
    -v ./licenses:/out \
    quay.io/synqly/embedded:latest \
    --license-generate /etc/synqly/primary-license.json \
    --license-expires 2027-04-14 \
    --license-instance-id prod-east-1 \
    --license-output /out/prod-east-1-license.json

On success, the sub-license is written to the output path and the container exits. On failure, a descriptive error message is printed and the container exits with a non-zero status code.


Inspecting a License

Use the --license-inspect flag to view the metadata of any license file (primary or sub-license) without starting the service. This is useful for checking expiration dates, license type, and deployment details.

Usage:

docker run --rm \
  -v ./license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-inspect /etc/synqly/license.json

Example output:

License Information:
  Type:        sub
  License ID:  sub_a1b2c3d4e5f6
  Parent ID:   lic_f6e5d4c3b2a1
  Customer ID: cust_xyz
  Instance ID: prod-east-1
  Issued At:   2026-04-14T12:00:00Z
  Expires At:  2027-04-14T23:59:59Z

The inspect command never exposes private key material. It only displays the metadata fields that are safe to share.


Verifying a License

Use the --license-verify flag to perform the same verification checks that the Embedded service runs on startup. This lets you confirm a license is valid before deploying it.

Usage:

docker run --rm \
  -v ./license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-verify /etc/synqly/license.json

What it checks:

  • The license signature is valid and has not been tampered with.
  • The license has not expired.
  • For sub-licenses: the key attestation is valid, and the sub-license expiration does not exceed the primary license expiration.

Example output (valid license):

License verification: OK
  Type:       sub
  License ID: sub_a1b2c3d4e5f6
  Expires At: 2027-04-14T23:59:59Z

Example output (invalid license):

License verification: FAILED
  Error: license has expired

The container exits with status code 0 on success and a non-zero status code on failure.


Deploying a License

Once you have a valid sub-license, deploy it alongside the Embedded service by mounting it into the container.

Docker

Mount the license file as a read-only volume at the default path /etc/synqly/license.json:

docker run \
  -v ./prod-east-1-license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest

Or specify a custom path with the --license-file flag:

docker run \
  -v ./prod-east-1-license.json:/opt/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-file /opt/synqly/license.json

Docker Compose

services:
  embedded:
    image: quay.io/synqly/embedded:latest
    volumes:
      - ./license.json:/etc/synqly/license.json:ro

What Happens on Startup

When the Embedded service starts with a license file configured:

  1. The service loads and verifies the license before starting any other operations.
  2. If the license is valid, the service uses the license expiration date to govern its lifetime.
  3. If the license file is missing, unreadable, or fails verification, the service falls back to a 90-day expiration from the build date and logs a warning explaining why.

The service re-checks the license every 8 hours while running. If the license expires during operation, the service will shut down.


License Expiration and Renewal

Expiration Warnings

The Embedded service monitors license expiration and provides advance warning:

  • 15 days before expiration: The service logs a warning on each periodic check (every 8 hours), alerting you that the license is approaching expiry.
  • On expiration: The service shuts down.

These warnings appear in the service logs and in the audit trail, giving you time to renew before any disruption.

Checking Your License Expiration

You can check when a license expires at any time without starting the service:

docker run --rm \
  -v ./license.json:/etc/synqly/license.json:ro \
  quay.io/synqly/embedded:latest \
  --license-inspect /etc/synqly/license.json

Look for the Expires At field in the output.

Renewal Workflow

When your license is approaching expiration:

  1. Contact Synqly to request a renewed primary license. Synqly will issue a new primary license with an updated expiration date.

  2. Receive the new primary license and passphrase through the same secure delivery process as your original license.

  3. Generate new sub-licenses from the renewed primary license for each of your deployments:

    docker run --rm \
      -e SYNQLY_LICENSE_PASSPHRASE="new-passphrase" \
      -v ./new-primary-license.json:/etc/synqly/primary-license.json:ro \
      -v ./licenses:/out \
      quay.io/synqly/embedded:latest \
      --license-generate /etc/synqly/primary-license.json \
      --license-expires 2028-06-01 \
      --license-instance-id prod-east-1 \
      --license-output /out/new-sub-license.json
  4. Verify the new sub-license before deploying:

    docker run --rm \
      -v ./licenses/new-sub-license.json:/etc/synqly/license.json:ro \
      quay.io/synqly/embedded:latest \
      --license-verify /etc/synqly/license.json
  5. Replace the license file on each deployment and restart the container:

    cp ./licenses/new-sub-license.json ./license.json
    docker restart embedded

The service will pick up the new license on its next startup.


Troubleshooting

"private key decryption failed"

The passphrase you provided does not match the one associated with your primary license.

  • Double-check the passphrase for typos, trailing whitespace, or encoding issues.
  • Ensure you are using the passphrase that was delivered alongside this specific primary license.
  • If the passphrase is lost, contact Synqly to have a new primary license issued.

"license has expired"

The license expires_at date has passed.

  • Use --license-inspect to check the expiration date.
  • Follow the Renewal Workflow to obtain a new license.

"primary license has expired"

The primary license that was used to generate this sub-license has expired (the primary_expires_at date has passed), even if the sub-license's own expiration has not.

  • Contact Synqly for a renewed primary license.
  • Generate a new sub-license from the renewed primary.

"sub-license expiration exceeds primary expiration"

The sub-license's expiration date is later than the primary license allows.

  • Regenerate the sub-license with an --license-expires date that does not exceed the primary license expiration.
  • Use --license-inspect on the primary license to check its expiration date.

"signature verification failed"

The license file has been modified after it was signed. Even minor changes (whitespace, line endings) will break the signature.

  • Ensure the license file was transferred without modification (no line-ending conversion, no re-encoding).
  • If the file is corrupted, regenerate the sub-license from your primary license.

"key attestation verification failed"

The sub-license was generated from a primary license that does not match the public key compiled into this binary.

  • Ensure you are using a primary license issued for this version of the Embedded binary.
  • Contact Synqly if you believe there is a key mismatch.

Service falls back to build-date expiration

The service logs a warning about using the 90-day build-date fallback instead of the license.

Common causes:

  • The license file is not found at the expected path (default: /etc/synqly/license.json).
  • The license file has incorrect permissions (must be readable by the service process).
  • The license file does not match the public key compiled into the binary.

Resolution:

  • Check the --license-file flag or verify the file exists at the default path.
  • Check file permissions: ls -la /etc/synqly/license.json.
  • Review the service logs for the specific verification error.
  • For Docker deployments, confirm the volume mount is correct: ./license.json:/etc/synqly/license.json:ro.