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
| State | Behaviour |
|---|---|
| Valid, > 7 days remaining | Normal operation |
| Valid, ≤ 7 days remaining | Warning logged at startup; entitlements active |
| Expired, within 7-day grace window | Warning logged; entitlements still active; grace_remaining_seconds non-zero in /admin/license |
| Expired, beyond grace window | Entitlement-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):
- Obtain the new license key from your Alexandria account representative.
- 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)'"}]'
- 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
| Entitlement | Feature |
|---|---|
multi_tenant | Multi-tenancy, per-tenant isolation, tenant ceiling |
oidc | OIDC/SAML federation and JIT provisioning |
scim | SCIM 2.0 user/group provisioning |
audit_export | Audit log bulk export (GET /admin/audit/export) |
memcached_cache | Memcached blob-cache backend (cache_strategy=alexandria) |
vault | Vault KV v2 secrets backend |
backend_autoscaling | HPA-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.