Skip to main content

Documentation Index

Fetch the complete documentation index at: https://qwady.wiki/llms.txt

Use this file to discover all available pages before exploring further.

ThornGuard now uses a single THORN-... Polar license key plus one activation per browser, CLI install, or device. It no longer issues separate THORN-TEAM-... child secrets for self-service access.

Activation Model

  • Individual licenses support up to 3 active activations.
  • Enterprise licenses support up to 30 active activations.
  • Internal licenses are private to Qwady operations and can use a separately configured activation limit.
For public plans, ThornGuard derives tier from Polar’s activation limits and uses the live license validation result to decide what the current client may do. Internal licenses are an explicitly allowlisted operational tier.

Why This Changed

Using a single Polar license key plus tracked activations keeps the enforcement model aligned with the actual subscription:
  • the same Polar key is always the source of truth
  • active-seat counts match Polar’s activation inventory
  • browser and CLI instances can be deactivated without rotating the main key
  • ThornGuard does not mint a second layer of long-lived credentials just to represent the same subscription

Current Dashboard Surface

The dashboard page at thorns.qwady.io/dashboard/activations shows:
  • the current number of active seats
  • the seat limit returned by Polar
  • the current browser activation
  • the list of active browser, CLI, or device instances
  • per-activation labels and metadata
  • a deactivation action for stale instances
  • role assignments for enterprise tier operators (see below)
The dashboard’s Platform page is separate. It tracks saved protected connections and advisory metadata for MCP targets you configured through ThornGuard, but it does not consume or free activation seats. If you deactivate the current browser, ThornGuard signs that browser out and it must reactivate before it can continue.

MCP Header Model

For MCP traffic, ThornGuard currently expects three auth headers:
  • x-thornguard-license: Bearer THORN-...
  • x-thornguard-activation-id: <activation-id>
  • x-thornguard-activation-proof: <activation-proof>
  • x-thornguard-session-id: <runtime-session-id>
Preferred routing path:
  • connect to a managed protected URL such as https://thorns.qwady.app/mcp/42
Legacy compatibility path:
  • connect to https://thorns.qwady.app/mcp
  • include x-mcp-target-url: https://your-upstream-mcp-server/mcp
Example:
{
  "mcpServers": {
    "Protected Server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://thorns.qwady.app/mcp/42",
        "--header",
        "x-thornguard-license: Bearer THORN-YOUR_LICENSE_KEY",
        "--header",
        "x-thornguard-activation-id: YOUR_ACTIVATION_ID",
        "--header",
        "x-thornguard-activation-proof: YOUR_ACTIVATION_PROOF",
        "--header",
        "x-thornguard-session-id: YOUR_RUNTIME_SESSION_ID"
      ]
    }
  }
}
In practice, the ThornGuard CLI creates and stores the activation for you, then injects the activation ID plus activation proof automatically when it launches the protected connection. For older clients still on the legacy route, the CLI also handles x-mcp-target-url injection during migration.

Role Assignments (Enterprise)

Enterprise tier operators can assign granular roles to specific activations. This replaces the retired team token system with activation-bound role management.

Available Roles

RoleAccess Level
ownerFull access (implicit for the license holder — no row needed)
super_adminFull administrative access including team management
adminManage policies, integrations, connections, approvals, and redaction rules
policy_adminManage policies and approval profiles
developerRead access to tools, connections, and audit logs
auditorRead-only access to audit logs and compliance data
viewerRead-only access to dashboard data

How It Works

  • Activations default to owner if no role assignment row exists for that activation
  • Role assignments are stored in D1 and checked during license-key authentication
  • Only applies to license-key auth — OAuth/SSO derives roles from claims instead
  • The license holder is always owner regardless of role assignment table contents
  • One role per activation (enforced by a unique constraint on license + activation ID)

Managing Roles

The dashboard Activations page (enterprise tier only) provides:
  • A table of current role assignments with label, activation ID, role, and creation date
  • A form to create new assignments by selecting an activation from the inventory
  • Edit and delete actions for existing assignments
  • Color-coded role badges for quick scanning
Roles can also be managed via the API:
GET    /api/roles                  → list role assignments
POST   /api/roles                  → create role assignment
PATCH  /api/roles/:id              → update role
DELETE /api/roles/:id              → remove role assignment
All /api/roles mutations require owner, admin, or super_admin permissions.

Deactivating an Instance

Use the dashboard’s Activations page to deactivate an old browser, laptop, or CLI install when you need to free a seat. Deactivation is immediate. The next request from that client will fail until it reactivates with the primary THORN-... license key.

Legacy Notes

The Worker still recognizes the old THORN-TEAM-... prefix only so it can return a clear retirement error. The historical team_tokens D1 table may still exist in older deployments, but it is no longer part of the live self-service licensing model.