Skip to main content

Resources

Security Best Practices

Recommendations for securely integrating with the Licentric platform.

API Key Management

Keep Keys Server-Side

API keys grant management access to your account. Never embed them in client-side code, mobile apps, or browser-accessible files.

  • Store API keys in environment variables or a secrets manager
  • Never commit keys to version control (add .env to your .gitignore)
  • Use a backend proxy if your frontend needs to validate licenses
Never expose API keys in client code
API keys in client-side JavaScript, mobile binaries, or desktop apps can be extracted and used to manage your entire account. Use license key authentication for client-side validation instead.

Separate Test and Live Keys

Use lk_test_ keys during development and testing. Switch to lk_live_ keys only in production. Test keys access an isolated test dataset, so mistakes during development never affect real customers.

Scope Keys to Minimum Permissions

When creating API keys, grant only the scopes required for that service’s function. A validation-only service does not need licenses:write access.

Rotate Keys Periodically

Rotate API keys on a regular schedule and immediately after any suspected exposure. Create a new key in the dashboard before revoking the old one to avoid downtime.

Webhook Security

All webhook payloads are signed with HMAC-SHA256 using your webhook secret. Always verify the signature before processing the payload.

  • Use a timing-safe comparison to prevent timing attacks
  • Reject requests with missing or invalid signatures
  • Process events idempotently — webhooks may be delivered more than once

Node.js Verification

verify-webhook.ts
import crypto from "node:crypto";

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string,
): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

Python Verification

verify_webhook.py
import hashlib
import hmac

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256,
    ).hexdigest()

    return hmac.compare_digest(signature, expected)

License Key Security

  • License keys are stored as SHA-256 hashes in the database — they cannot be recovered from a breach
  • The key format PREFIX-XXXX-XXXX-XXXX-XXXX uses cryptographically random segments, preventing enumeration
  • Instruct customers to store their license keys securely and never share them publicly

Encryption at Rest

Licentric uses AES-256-GCM to encrypt sensitive data at rest in the database, including raw license keys. The encryption keys are managed separately from the database credentials.

Offline License Files

Offline license files are signed with Ed25519, providing:

  • Authenticity — the file was issued by Licentric, not forged
  • Integrity — the file has not been tampered with since issuance
  • Expiration — each file has a configurable TTL (default 14 days)
  • Device binding — the file is bound to a specific machine fingerprint
Air-gapped environments
For deployments without network access, check out a license file periodically when connectivity is available. The file remains valid for its full TTL without needing to contact the API.

Transport Security

  • All API communication uses HTTPS (TLS 1.2+) — never use HTTP
  • The SDKs enforce HTTPS by default and will reject insecure connections
  • Certificate pinning is recommended for high-security environments

Security Checklist

PracticePriority
API keys stored in environment variables, not source codeCritical
Test and live keys separated by environmentCritical
Webhook signatures verified with timing-safe comparisonCritical
API keys scoped to minimum required permissionsHigh
All API communication over HTTPSHigh
API keys rotated on regular scheduleMedium
Webhook handlers are idempotentMedium