โ—† Oryn
Docs โ€บ Admin โ€บ Admin: Billing, Tiers & Licensing

๐Ÿ’ณ Admin: Billing, Tiers & Licensing

Control who can use Oryn, what they can do, and how usage is metered and billed.

Overview

Oryn uses a layered system to control access and enforce limits. Every install begins with a 14-day free trial; after that, an activated license key is required to unlock the desktop app. Tier entitlements (Free, Team, Business, Enterprise, OnPrem) determine what features and infrastructure each organization receives. Usage is recorded per-session and can be pushed to Stripe for subscription billing, with invoices generated automatically at the end of each billing period.

How it works

When the Oryn desktop app launches, the LicenseGate component reads a locally stored license record, verifies its RSA-signed activation token against the machine's hardware fingerprint, and checks a trusted server clock to prevent clock-rollback attacks. For paid tiers, the desktop sends a heartbeat to the licensing server every 24 hours (every 4 hours when expiry is within 7 days, every 30 minutes on the final day); if the server has not been reached within 7 days the app locks. On the backend, the Gateway's LicenseGuard middleware validates the signed token and fingerprint on every sensitive request (completions, agent hub, codebase access), caching results for 5 minutes to keep per-request overhead low. Revoking a license immediately purges the in-memory cache so the seat stops working within seconds. Subscription billing is handled by an hourly AutoBillingService that detects period rollovers, generates invoices from recorded usage events, and optionally forwards usage records to Stripe's metered billing API.

What you can do

14-day free trialNew installs automatically start a 14-day trial (50 K tokens/day, 3 concurrent sessions, read-only cloud, 5 test runs) with no license key required.
Enterprise pilot trialA 30-day pilot with 200 K tokens/day, full Tests and Cloud modules, SSO, and 25 concurrent sessions โ€” reserved for enterprise sales conversations.
Tier entitlementsFive tiers (Free, Team, Business, Enterprise, OnPrem) gate tokens per day, concurrent sessions, module access (Tests, Cloud, Meetings), SSO, audit log retention, backup cadence, on-prem deploy, and support SLA.
License key issuanceAdmins issue RSA-signed license keys via the license API, specifying customer email, tier, seat count, expiry date, and optional payment metadata.
Machine-bound activationA license key is activated against a specific machine fingerprint; each activation consumes one seat. Re-activating on the same machine refreshes the token without consuming another seat.
Seat managementAdmins can remotely deactivate individual machines to free seats, or revoke/cancel an entire license to immediately block all machines on it.
License heartbeatThe desktop polls the server on a schedule (24h / 4h / 30min depending on proximity to expiry) and receives a fresh server-signed token each time, preventing client-side clock manipulation.
Automatic renewal remindersA daily background scan flags licenses expiring within 30, 14, 7, or 1 days and queues renewal_pending activity log entries; admins can then generate and send templated reminder emails (30-day, 14-day, 7-day, expired, invoice).
Bulk license managementAdmins can extend expiry or send reminders to multiple license keys in a single API call.
Usage meteringThe agent loop records usage events (seat-day, LLM tokens, agent runs, background runs, marketplace installs) which are aggregated into period invoices.
Stripe subscription billingStripeBillingService creates Stripe Checkout sessions, pushes metered usage records to Stripe, and processes lifecycle webhooks (checkout.session.completed, invoice.paid, customer.subscription.deleted) to keep subscription state in sync.
Automatic invoice generationAutoBillingService runs hourly, detects billing period rollovers, generates PDF invoices from usage events, and rolls the subscription period forward; failed invoices mark the subscription past-due instead of silently dropping it.
Customer CRMThe license store tracks customer name, company, phone, address, tax ID, payment reference, total revenue, and a full timestamped activity log per license key, exportable as CSV.
Entitlements APIGET /api/v1/entitlements/tier/{tier} and /compare let the desktop and dashboard query what a given tier can do, so the UI can show or hide features dynamically.
License lockout screenWhen the desktop detects an expired trial, expired license, missed heartbeat, revoked key, tampered token, wrong machine, or clock skew, it replaces the entire UI with a lockout screen showing the specific reason and an activation field.
Dev bypassSetting ORYN_LICENSE_DEV_BYPASS=true skips license checks for loopback-only requests, so local development works without a license key; non-loopback callers are always checked even with the flag set.

How to use it

  1. Start or verify a trial
    On first launch the desktop automatically creates a 14-day trial with no action needed. To check how many days remain, open Settings > License. The trial banner shows token usage and a link to upgrade.
  2. Purchase and receive a license key
    Complete checkout (via Stripe or direct invoice). Your license key is emailed to the address used at purchase. It looks like ORYN-TEAM-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  3. Activate the license key in the desktop app
    When the trial expires (or from Settings > License at any time), paste the license key into the activation field and click Activate. The app sends the key along with your machine fingerprint to the licensing server and stores the resulting signed activation token locally.
  4. Verify your tier and seat count
    After activation, Settings > License shows the tier (e.g. Team), seats used vs total, and the expiry date. Features unavailable on your tier appear greyed out with an upgrade prompt.
  5. Add more seats or upgrade tier (admin)
    Admins use the admin dashboard or the license API (POST /api/v1/license/extend or the Stripe checkout URL) to add seats or change tier. A tier change takes effect immediately; the entitlements cache refreshes within 5 minutes on the gateway.
  6. Deactivate a machine to reclaim a seat
    In the admin dashboard go to Clients, find the license, expand Activated Machines, and click Deactivate next to the machine you want to remove. The seat is freed instantly and the machine's next request will be refused.
  7. Revoke or cancel a license
    To permanently block a license use Revoke (fraud, chargeback) or Cancel (customer request, optionally with a refund amount). Both actions clear all activations and immediately purge the in-memory validation cache on the gateway so access stops within seconds.
  8. Monitor usage and generate invoices
    The admin dashboard's Billing section shows token consumption by provider and model. Invoices are generated automatically at each billing period end, or on demand via POST /api/v1/billing/invoices/generate. PDF invoices can be downloaded from the invoice list.

Example

A Team plan customer on three machines activates on machine A, B, and C (consuming all three seats). They decommission machine B. The admin opens the Clients view, finds the license key, and deactivates machine B's fingerprint. Machine B's next agent request returns 401 LICENSE_INVALID within seconds (the cache was purged on revocation). Machine A and C continue working normally, and the freed seat can be activated on a new machine D by the customer running the license key entry flow in the desktop app.

Admin notes

RSA key pair: On first use the licensing server auto-generates a 2048-bit RSA key pair and writes it to .oryn/license-private.pem and .oryn/license-public.pem. The gateway loads only the public half for verification, so the private key never needs to be on the gateway host. After rotating the key pair call LicenseGuard.ResetRsa() (or restart the gateway) so the old public key is not used for verification. License store: All issued licenses are persisted to .oryn/licenses.json; back this file up โ€” losing it means no license can be validated. Stripe setup: Configure Stripe:SecretKey, Stripe:WebhookSecret, and Stripe:SubscriptionItemByOrg (org-id to Stripe subscription-item-id mapping) in appsettings or environment variables. Without a SecretKey, Stripe is disabled and checkout sessions return placeholder URLs. The ORYN_LICENSE_DEV_BYPASS=true environment variable bypasses license checks for loopback connections only and must never be set in production. The admin license API (issue, revoke, extend, list, clients, stats, etc.) requires the X-Admin-Key header; the key is stored in .oryn/admin-key.txt and auto-generated on first use. Rate limiting on /activate and /heartbeat is 10 requests per IP per minute (in-memory, resets on restart).

Related