Security and privacy

We store what licensing needs. Nothing else.

A licensing service sits between your customers and your app. This page lists exactly what Keyrail keeps, what it never sees, and how the sensitive parts are protected. It is written for you and for the privacy policy you owe your own customers.

What we store

  • Your account: the email and name of the people who sign in to the dashboard.
  • Your Keyrail subscription: the Paddle customer and subscription IDs, your plan, billing status and the end of the current period. Paddle, our merchant of record, keeps your billing details.
  • Your customers: email and name, received from your payment provider’s webhooks or entered by you.
  • Licenses: status, plan, seats and dates. The license key is kept as a SHA-256 hash for lookup, and encrypted (AES-256-GCM) so you and your customer can see it again.
  • Activations: a hashed machine fingerprint, plus the machine name, platform and app version if your app sends them, and the last time it was seen.
  • Rate limiting: salted SHA-256 hashes of IP addresses, kept 30 days.
  • Audit log: webhooks received, status changes and activations, so you can answer “why is this license suspended?”.

What we never store

  • Card or bank details. Your payment provider takes your customers’ payments, and Paddle takes yours; we only receive the events.
  • Raw hardware identifiers. The SDK hashes the machine ID with your product ID before sending it. Two vendors can’t correlate the same machine.
  • Telemetry. No usage analytics, crash reports, file names or feature tracking. The SDK calls us only to activate, refresh and deactivate.
  • Plain IP addresses in our database.
  • Third-party trackers on this website, the dashboard or the customer portal. The dashboard loads Paddle’s checkout script only when you click Upgrade.

Where the data lives

Keyrail runs on Cloudflare Workers. The database is Cloudflare D1 created with the EU jurisdiction, so licensing data is stored in the European Union. Requests are received by Cloudflare’s network close to the caller, then processed against the EU database. Transactional email (license keys, sign-in links) goes through an EU-based provider. The full list is on the subprocessors page.

Signing keys and secrets

  • Each product has its own Ed25519 signing key pair. The private key is encrypted with AES-256-GCM. No list, log or API key can read it; the only way out is the owner-only, audited export described under continuity below.
  • Only the public key ships in your app. It can verify certificates, not create them.
  • Signing keys can be rotated in two phases: the new public key is published first, so you ship it in an app update before it signs anything; older keys stay valid for verification. See key rotation.
  • Secret API keys (kr_sk_…) and session tokens are stored as SHA-256 hashes. A secret key is shown once, at creation.
  • Secrets and signatures are compared in constant time. License keys and tokens are never written to logs.

Web and API

  • Dashboard and portal sign-in by single-use email links; session cookies are HttpOnly, Secure, SameSite=Lax and host-only (__Host- prefix).
  • Browser routes check the Origin header.
  • Webhooks are verified with your provider’s signature (HMAC-SHA256) before anything is processed, and processed once per event.
  • The public client API is rate-limited per license key and IP address.
  • This site loads no third-party resources and ships a strict Content Security Policy.

If Keyrail shuts down

Keyrail is a young service run by a small team. Depending on it for the licenses of your own product is a real question, so here is the exit path, built into the service rather than promised in a support reply. Each point is something you can do today, without asking us.

  1. Certificates already issued keep working. Your app verifies them offline with the public key it embeds, until their expiresAt: at most your product’s offlineDays (30 by default, up to 365) after the last refresh. No call to Keyrail is involved.
  2. Your data is yours, at any time. The account owner downloads everything from the dashboard: customers, licenses with their keys, activations, plans, products and public keys, integrations without secrets, the recent audit log. The vendor API gives the same data to your own scripts.
  3. Your signing keys are yours too. The account owner can export the private signing keys of each product (every key, pending, active and retired, as a raw seed and as PKCS#8). With them you sign certificates yourself, and your app, unchanged, accepts them. The export is owner-only, audited and rate-limited; do it once when you create the product and keep the file in a vault.
  4. The format and the SDKs are open. The certificate format is documented with public test vectors and a reference verifier; the Rust, Tauri and Node SDKs are MIT-licensed and take any API base URL, so an app update can point to an issuer you run.
  5. 90 days’ notice. Our terms of service commit us to at least 90 days’ notice by email to every account owner before the service, or a material part of it, is discontinued, with the exports and the vendor API available throughout. Closing a single account follows the 30-day transition described in the terms.

What this does not cover, said plainly: the hosted service itself (dashboard, APIs, portal, webhooks) is proprietary and not offered for self-hosting. After a shutdown, the SDKs’ silent refreshes fail and apps keep their cached certificate until it expires, so you would need your own issuer, or an app update, in place before the notice period ends. The exports above are what make that possible; the notice period is what makes it feasible.

GDPR

For your customers’ data, you are the controller and Keyrail is your processor. Our data processing agreement covers it, and our privacy policy covers the data about you. Requests about personal data: hello@keyrail.tech.

Reporting a vulnerability

Write to support@keyrail.tech with “security” in the subject. We will acknowledge within a few working days and keep you informed until it is fixed. Please give us reasonable time before any public disclosure.