Skip to main content

Alexandria EE — Licensing

License Model

Alexandria EE uses a signed JWT license key that encodes the entitlements your subscription includes. The key is verified at startup against the embedded Alexandria public key; it requires no outbound network calls.


Applying the License

Helm (Kubernetes)

At install time — pass the key as a Helm value:

helm upgrade --install alexandria-ee k8s/helm/alexandria-ee/ \
--set license.key='<YOUR_LICENSE_KEY>'

Or store it in a Kubernetes Secret and reference it:

kubectl create secret generic alexandria-ee-license \
--from-literal=license.key='<YOUR_LICENSE_KEY>' \
--namespace alexandria \
--dry-run=client -o yaml | kubectl apply -f -

Then in values.yaml:

license:
secretName: alexandria-ee-license

Post-install (replacing the key):

kubectl create secret generic alexandria-ee-license \
--from-literal=license.key='<NEW_LICENSE_KEY>' \
--namespace alexandria \
--dry-run=client -o yaml | kubectl apply -f -

# Restart the API to pick up the new key
kubectl rollout restart deployment/alexandria-ee -n alexandria

Quadlet (Linux host)

Set LICENSE_KEY in the API container unit file:

# /etc/containers/systemd/alexandria-api.container
[Container]
Environment=LICENSE_KEY=<YOUR_LICENSE_KEY>

Reload and restart:

sudo systemctl daemon-reload
sudo systemctl restart alexandria-api

Verify:

curl -s http://localhost:8080/admin/license \
-H "Authorization: Bearer <admin-token>" | jq .

Verifying the License

The API exposes current license state at GET /admin/license (requires admin JWT):

{
"tier": "enterprise",
"entitlements": ["multi_tenant", "oidc", "scim", "audit_export", "memcached_cache", "vault"],
"expires_at": "2027-05-01T00:00:00Z",
"days_remaining": 359,
"grace_remaining_seconds": 0
}

The startup log also prints license state:

INFO license loaded tier=enterprise expires_at=2027-05-01 entitlements=[multi_tenant oidc ...]

Expiry Behaviour

StateBehaviour
Valid, > 7 days remainingNormal operation
Valid, ≤ 7 days remainingWarning logged at startup; entitlements active
Expired, within 7-day grace windowWarning logged; entitlements still active; grace_remaining_seconds non-zero in /admin/license
Expired, beyond grace windowEntitlement-gated features return HTTP 402; the core API remains operational

Known gap: The dashboard does not yet display an in-UI expiry warning banner. When the license expires the API will return 402 on gated routes but the UI will show no explanation. A warning banner is planned.


Runtime License Renewal

To renew a license without downtime (Helm):

  1. Obtain the new license key from your Alexandria account representative.
  2. Update the Secret:
kubectl patch secret alexandria-ee-license -n alexandria \
--type='json' \
-p='[{"op":"replace","path":"/data/license.key","value":"'$(echo -n '<NEW_KEY>' | base64 -w0)'"}]'
  1. Trigger a rolling restart:
kubectl rollout restart deployment/alexandria-ee -n alexandria

The restart window is the same as an upgrade (15–60 seconds with Recreate strategy).


Entitlement Reference

EntitlementFeature
multi_tenantMulti-tenancy, per-tenant isolation, tenant ceiling
oidcOIDC/SAML federation and JIT provisioning
scimSCIM 2.0 user/group provisioning
audit_exportAudit log bulk export (GET /admin/audit/export)
memcached_cacheMemcached blob-cache backend (cache_strategy=alexandria)
vaultVault KV v2 secrets backend
backend_autoscalingHPA-driven LLM backend autoscaling

License Key Security

  • Store the key in a Kubernetes Secret or environment variable — never in values.yaml committed to version control.
  • Rotate the key if it is exposed. Revocation requires issuing a new key; expired keys self-invalidate.
  • The key is a signed JWT — it cannot be modified by the holder without breaking the signature.