Skip to main content
CID222 Docs

Licence tiers and feature keys

Every licence FeatureKey, the tier that grants it, and the controllers and pages it switches off.

  • Type: reference

Every capability the product can sell, the tier that grants it, and exactly what an operator loses when the key is absent. Regenerate with make docs-generate.

Entitlements resolve as union(payload.features, featuresOfTier(tier)), so a key added to a tier after a licence was signed is still granted to that licence — an upgrade never silently revokes.

Tiers (3)

TierLabelAliasesKeys
starterStarter11
professionalProfessionalmedium13
enterpriseEnterprise17

Feature keys (17)

FeatureKeyLabelGroupstarterprofessionalenterpriseWhat it switches offControllersPages
chatChat gatewaycoreThe chat gateway itself. Not gated: refusing it is refusing the product, which is what the expiry block (LicenseGuard) already does.
proxyAPI proxycoreProvider-passthrough API traffic. Same reasoning as chat — it is the product, not a module.
icapICAP / inline proxycoreThe inline-proxy / ICAP inspection admin surface: policy, attribution and proxy management. The /inspect/v1 data path is deliberately outside the gate.InspectionAdminController, AttributionAdminController, InlineProxyManagementController/inspection
ocrImage OCRcoreImage OCR inside image-analysis. A pipeline stage, reached only through endpoints chat/documents already cover.
documentsDocument analysiscorePDF/DOCX extraction inside document-analysis. Pipeline stage, as above.
redactionRedactioncoreImage/document redaction. Pipeline stage, as above.
ext.browserBrowser extensioncoreThe browser extension end to end: enrolment, attestation, deployment, the firewall EDL, and the AI-usage feed the extension produces.AdminEventsController, AiUsageAdminController, AttestationController, BrowserExtensionAuthController, BrowserExtensionManagementController, EdlController, EdlTokensAdminController, ExtensionDeploymentAdminController, ExtensionDevicesAdminController/browser-extension, /ai-usage
cost.calculatorToken cost calculatorcoreToken cost and savings reporting, including the PDF export.CostReportController/cost-savings
complianceCompliance & GRCcoreGDPR/HIPAA tracking, compliance findings, reports, snapshots, evidence packs and the GRC/CRQ simulator.ComplianceController, ComplianceFindingsController, ComplianceReportController, ComplianceSnapshotController, EvidencePackController, GrcSimulatorController/compliance, /compliance-reports
governanceAI governance inventorycoreThe AI asset inventory: shadow/unowned discovery, ownership, and EU AI Act risk tiers.GovernanceController/governance, /governance/inventory, /governance/risk, /governance/ownership
endpoint.agentEndpoint agent fleetcoreFleet administration for the OS-level endpoint agent. The device-facing enroll/policy/heartbeat API is NOT gated — see the file comment.EndpointAgentAdminController/endpoint-agent
mcp.serverMCP serveraddonThe read-only MCP server (a separate container, opt-in by compose profile). Nothing in the gateway fronts it, so there is no route to gate; the key stays as the commercial flag.
cost.token_reductionToken cost reductionaddonPrompt compression ahead of the provider call. Runs inside the chat path, so it has no route of its own — gating it belongs in prompt-compression/, not here.
codesafetyCode SafetyenterpriseCode Safety: repo tracking admin and the auditor model-redaction console. The detection path checks the same key in code-safety-detection.service.ts.RepoConnectorAdminController, RepoAssignmentAdminController, ModelRedactionController/repo-connector
risk.detailedDetailed risk analysisenterpriseThe Risk Analysis findings store and review API. It has no page row of its own — the dashboard reaches it from /llm-review, which risk.llm_review gates.RiskAnalysisController
risk.llm_reviewLLM Risk AnalystenterpriseThe LLM Risk Analyst: review pipeline, attack knowledge, the group-leader view, and the ATLAS/OWASP reference tables the analyst reasons over.AdminLlmReviewController, AttackKnowledgeController, TeamController, AtlasController, OwaspController/llm-review, /analyst, /my-team
integrations.siemSIEM exportenterpriseOutbound SIEM export (syslog/CEF + webhook). Configured from a Settings pane, which is not a registry-governed page of its own; the export processor checks the same key.IntegrationsController

Keys that gate nothing by design

chat, proxy, ocr, documents, redaction, mcp.server, cost.token_reduction carry empty controller and page lists. They are pipeline stages or the product itself, reached through the chat and analysis endpoints rather than through a module of their own; naming a controller to make the table look complete would be exactly the drift module-features.ts exists to prevent. Expiry still blocks them, via LicenseGuard.

Deliberately ungated controllers (53)

Being on this list is a claim that the absence of a licence gate is correct — not that the controller is unprotected. Most carry @Roles; several carry a callback token, a private-address check or an HMAC. Licence gating is a separate axis from access control.

ControllerFileAxisWhy
AppControllercid-nestjs-gateway/app.controller.tsfix_pathRoot + /health. The healthcheck a licence-blocked box is judged by.
AuthControllercid-nestjs-gateway/auth/auth.controller.tsfix_pathLogin. Nobody can upload a renewal without signing in first.
LicenseControllercid-nestjs-gateway/license/license.controller.tsfix_pathStatus, activation request and licence upload — the renewal itself.
EntitlementsControllercid-nestjs-gateway/license/entitlements.controller.tsfix_pathThe probe every screen reads to know what is licensed. Gating it would make the answer depend on itself.
LicenseAdminControllercid-nestjs-gateway/license-admin/license-admin.controller.tsfix_pathThe owner console issues licences. It is gated on being the hub (OwnerConsoleGuard), a stronger and more specific condition than any tier.
SetupControllercid-nestjs-gateway/setup/setup.controller.tsfix_pathFirst-boot wizard. It runs before a licence exists.
SystemUpdateControllercid-nestjs-gateway/system-update/system-update.controller.tsfix_pathInstalling a new version can be the fix for a licensing bug; a licence must not be able to block its own remedy.
DiagnosticsControllercid-nestjs-gateway/diagnostics/diagnostics.controller.tsfix_pathAppliance self-diagnostics (snapshot, support bundle). It exists to explain a broken box — including a box whose licence state is the problem — so it must never be behind an entitlement.
CertificatesControllercid-nestjs-gateway/certificates/certificates.controller.tsfix_pathThe appliance's own HTTPS certificate. A box whose certificate expired or whose site proxy re-signs TLS cannot reach the licence hub or show the dashboard without a warning; HTTPS is platform plumbing every tier needs, never an entitlement.
ProvisionControllercid-nestjs-gateway/provision/provision.controller.tsfix_pathExternal tenant provisioning, authenticated by PROVISION_TOKEN. Not a product page and not reachable by a user.
ChatControllercid-nestjs-gateway/chat/chat.controller.tsdata_planeThe product. chat is in every tier; refusing it is what the expiry block (LicenseGuard) already does, at the right layer and with the right status code.
SessionsControllercid-nestjs-gateway/sessions/sessions.controller.tsdata_planeContext for the chat path; same key, same reasoning.
GuardrailsControllercid-nestjs-gateway/guardrails/guardrails.controller.tsdata_planeDetection API. Gating detection is gating the safety control itself, which is never the right answer to a billing state.
ImageAnalysisControllercid-nestjs-gateway/image-analysis/image-analysis.controller.tsdata_planeocr is a pipeline stage in every tier, reached through this endpoint rather than a module of its own.
DocumentAnalysisControllercid-nestjs-gateway/document-analysis/document-analysis.controller.tsdata_planedocuments/redaction are pipeline stages in every tier — same reasoning as image analysis.
HttpCalloutControllercid-nestjs-gateway/inline-proxy-inspect/http-callout.controller.tsdata_planeThe SWG inline callout (/inspect/v1). A 403 fails the proxy either open (traffic passes uninspected) or closed (the customer stops browsing); both are worse than an expired-licence banner.
FileRedactionControllercid-nestjs-gateway/inline-proxy-inspect/file-redaction.controller.tsdata_planeThe file half of the same callout, and the same failure either way.
InternalControllercid-nestjs-gateway/internal/internal.controller.tsdata_planeService-to-service (key validation, code-safety assess), authenticated by shared secret. Breaking it breaks the pipeline, not a page.
EndpointAgentControllercid-nestjs-gateway/endpoint-agent/endpoint-agent.controller.tsdevice_apiEnroll/policy/heartbeat. A deployed fleet must not brick mid-cycle because a renewal is late — the ADMIN surface goes dark (EndpointAgentAdminController, endpoint.agent), the agents keep enforcing policy.
PacFileControllercid-nestjs-gateway/inline-proxy-inspect/inline-proxy-management.controller.tsbootstrapUnauthenticated PAC file for client browsers. There is no actor to have an entitlement.
ApplianceCaPublicControllercid-nestjs-gateway/certificates/certificates.controller.tsbootstrapUnauthenticated download of the appliance root CA — what a machine needs before it can trust the dashboard at all. No actor, no entitlement.
InlineProxyReloadControllercid-nestjs-gateway/inline-proxy-inspect/reload.controller.tsbootstrapInternal reload hook for the inline proxy container.
RepoWebhookControllercid-nestjs-gateway/repo-connector/webhook.controller.tsbootstrapInbound git webhook, authenticated by HMAC. Dropping deliveries on a lapsed licence loses events that are never resent; the admin surface is gated by codesafety instead.
GithubManifestControllercid-nestjs-gateway/repo-connector/github-manifest.controller.tsbootstrapGitHub App manifest exchange (OAuth state-authenticated), part of connector setup rather than the product.
LlmReviewInternalControllercid-nestjs-gateway/llm-review/llm-review-internal.controller.tsbootstrapWhere cid-risk-analyst posts a finished review, authenticated by private address + a one-time callback token. It has no JWT and no tier.
AllDetectionsControllercid-nestjs-gateway/inline-proxy-inspect/all-detections.controller.tsno_single_keyThe unified feed spans extension, ICAP and chat traffic, so no one key owns it and gating on any of them would blank rows the box is licensed to show.
LlmReviewUserControllercid-nestjs-gateway/llm-review/llm-review-user.controller.tsno_single_keyWhat a LOCKED user can reach: read their own lock, ask for it to be lifted. A lock keeps enforcing after a licence lapses, so the route that explains it cannot be gated on the same licence.
FiltersControllercid-nestjs-gateway/filters/filters.controller.tsalways_onInput filter rules — core configuration, sold with every tier.
FilterImportExportControllercid-nestjs-gateway/filters/import-export/filter-import-export.controller.tsalways_onImport/export of those same always-on rules; a customer must be able to take their own filter configuration with them.
FilterOverridesControllercid-nestjs-gateway/guardrails/overrides/filter-overrides.controller.tsalways_onPer-detection overrides for those same rules.
DetectionEscalationControllercid-nestjs-gateway/guardrails/escalation/detection-escalation.controller.tsalways_onThe count rule that turns a bulk MASK into a REJECT. Part of the always-on detection policy: gating it would let a billing state decide whether bulk personal data leaves the building.
OutputFiltersControllercid-nestjs-gateway/output-filters/output-filters.controller.tsalways_onResponse-side filter rules — the output half of the same always-on module.
DetectionsControllercid-nestjs-gateway/detections/detections.controller.tsalways_onQuerying what the always-on detection pipeline found.
EventLoggingControllercid-nestjs-gateway/event-logging/event-logging.controller.tsalways_onThe audit trail. Hiding audit evidence behind a tier is not something to sell.
TenantsControllercid-nestjs-gateway/tenants/tenants.controller.tsalways_onAccount management. Seat COUNT is licensed (limits.users, AccountLimitService); the ability to manage accounts is not.
TenantGroupsControllercid-nestjs-gateway/tenant-groups/tenant-groups.controller.tsalways_onGroup membership and group credentials — core account management.
CredentialsControllercid-nestjs-gateway/credentials/credentials.controller.tsalways_onProvider API keys. Without them no tier works at all.
LlmReadinessControllercid-nestjs-gateway/credentials/llm-readiness.controller.tsalways_onWhether those credentials actually reach a provider.
ApiKeysControllercid-nestjs-gateway/api-keys/api-keys.controller.tsalways_onGateway API keys (cid_key_*) — the other way to reach chat/proxy, which every tier includes.
ModelsControllercid-nestjs-gateway/models/models.controller.tsalways_onModel discovery for the chat path — which models a tenant may pick. Every tier has chat, so every tier needs this.
AdminModelsControllercid-nestjs-gateway/models/admin-models.controller.tsalways_onAdmin side of the same model inventory: adding and pricing the models the always-on chat path routes to.
ModelRoutingControllercid-nestjs-gateway/model-routing/model-routing.controller.tsalways_onWhich model a request goes to — a setting on the always-on chat path.
MlEngineControllercid-nestjs-gateway/ml-engine/ml-engine.controller.tsalways_onHealth and control of the detection ML services, which every tier runs.
MlTuningControllercid-nestjs-gateway/ml-tuning/ml-tuning.controller.tsalways_onDetection thresholds for those same always-on detectors — tuning a safety control, not a capability anyone buys separately.
DocumentRedactionSettingsControllercid-nestjs-gateway/document-analysis/document-redaction-settings.controller.tsalways_onSettings for redaction, which is in every tier.
OcrSettingsControllercid-nestjs-gateway/ocr-settings/ocr-settings.controller.tsalways_onWhich one OCR engine image analysis runs. OCR itself is gated where it runs (image analysis); this is only the superadmin pane that picks the engine, and a tier without images sees a setting with nothing to apply to rather than a 403.
TenantAnalyticsControllercid-nestjs-gateway/tenant-analytics/tenant-analytics.controller.tsalways_onUsage statistics for the box. cost.calculator gates the cost REPORT (CostReportController); raw usage is not sold separately.
LdapControllercid-nestjs-gateway/ldap/ldap.controller.tsalways_onAD/LDAP authentication. Gating it would lock every AD user out of a box whose licence lapsed, including the admin coming to renew it.
PasswordDeliveryControllercid-nestjs-gateway/password-delivery/password-delivery.controller.tsalways_onHow reset links are delivered — part of getting back into the box.
HelpControllercid-nestjs-gateway/help/help.controller.tsalways_onThe in-product support assistant, which exists precisely to explain states like an expired licence.
RbacAdminControllercid-nestjs-gateway/rbac/rbac.controller.tsalways_onPage-access matrix administration. Access control is not a tier feature.
RbacManifestControllercid-nestjs-gateway/rbac/rbac.controller.tsalways_onThe my-pages manifest every dashboard route guard reads.
PromptCompressionControllercid-nestjs-gateway/prompt-compression/prompt-compression.controller.tsalways_onSuperadmin runtime settings for prompt compression. The CAPABILITY is sold as cost.token_reduction and enforced where it runs, in the chat path — this is only the pane that toggles it. Left ungated deliberately: on a tier without the key the switch is inert rather than hidden, which is a settings pane that does nothing rather than a 403 with no explanation. Gating it is a defensible product change; make it deliberately if at all.

TS ↔ issuer drift

cid-nestjs-gateway/license/tiers.ts and appliance/licensing/tiers.json agree on every key and every tier.

On this page

Download PDF