chore: unify license key env variables

This commit is contained in:
Piyush Gupta
2025-11-14 19:34:33 +05:30
parent 627e6c87f3
commit 10a2d7e9ae
6 changed files with 76 additions and 19 deletions
+37 -1
View File
@@ -7,7 +7,43 @@ import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { UserAliasType } from "@app/services/user-alias/user-alias-types"; import { UserAliasType } from "@app/services/user-alias/user-alias-types";
import { TFeatureSet } from "./license-types"; import { TFeatureSet, TLicenseKeyConfig, TOfflineLicenseContents } from "./license-types";
const getOfflineLicenseContents = (licenseKey: string): TOfflineLicenseContents => {
return JSON.parse(Buffer.from(licenseKey, "base64").toString("utf8")) as TOfflineLicenseContents;
};
export const isOfflineLicenseKey = (licenseKey: string): boolean => {
const contents = getOfflineLicenseContents(licenseKey);
return "signature" in contents && "license" in contents;
};
export const getLicenseKeyConfig = (): TLicenseKeyConfig => {
const cfg = getConfig();
const licenseKey = cfg.LICENSE_KEY;
if (licenseKey) {
if (isOfflineLicenseKey(licenseKey)) {
return { isValid: true, licenseKey, type: "offline" };
}
return { isValid: true, licenseKey, type: "online" };
}
const offlineLicenseKey = cfg.LICENSE_KEY_OFFLINE;
// backwards compatibility
if (offlineLicenseKey) {
if (isOfflineLicenseKey(offlineLicenseKey)) {
return { isValid: true, licenseKey: offlineLicenseKey, type: "offline" };
}
return { isValid: false };
}
return { isValid: false };
};
export const getDefaultOnPremFeatures = (): TFeatureSet => ({ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
_id: null, _id: null,
@@ -22,7 +22,7 @@ import { OrgPermissionBillingActions, OrgPermissionSubjects } from "../permissio
import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TPermissionServiceFactory } from "../permission/permission-service-types";
import { BillingPlanRows, BillingPlanTableHead } from "./licence-enums"; import { BillingPlanRows, BillingPlanTableHead } from "./licence-enums";
import { TLicenseDALFactory } from "./license-dal"; import { TLicenseDALFactory } from "./license-dal";
import { getDefaultOnPremFeatures, setupLicenseRequestWithStore } from "./license-fns"; import { getDefaultOnPremFeatures, getLicenseKeyConfig, setupLicenseRequestWithStore } from "./license-fns";
import { import {
InstanceType, InstanceType,
TAddOrgPmtMethodDTO, TAddOrgPmtMethodDTO,
@@ -77,6 +77,7 @@ export const licenseServiceFactory = ({
let instanceType = InstanceType.OnPrem; let instanceType = InstanceType.OnPrem;
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures(); let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
let selfHostedLicense: TOfflineLicense | null = null; let selfHostedLicense: TOfflineLicense | null = null;
const licenseKeyConfig = getLicenseKeyConfig();
const licenseServerCloudApi = setupLicenseRequestWithStore( const licenseServerCloudApi = setupLicenseRequestWithStore(
envConfig.LICENSE_SERVER_URL || "", envConfig.LICENSE_SERVER_URL || "",
@@ -85,10 +86,13 @@ export const licenseServiceFactory = ({
envConfig.INTERNAL_REGION envConfig.INTERNAL_REGION
); );
const onlineLicenseKey =
licenseKeyConfig.isValid && licenseKeyConfig.type === "online" ? licenseKeyConfig.licenseKey : "";
const licenseServerOnPremApi = setupLicenseRequestWithStore( const licenseServerOnPremApi = setupLicenseRequestWithStore(
envConfig.LICENSE_SERVER_URL || "", envConfig.LICENSE_SERVER_URL || "",
LICENSE_SERVER_ON_PREM_LOGIN, LICENSE_SERVER_ON_PREM_LOGIN,
envConfig.LICENSE_KEY || "", onlineLicenseKey,
envConfig.INTERNAL_REGION envConfig.INTERNAL_REGION
); );
@@ -131,7 +135,7 @@ export const licenseServiceFactory = ({
return; return;
} }
if (envConfig.LICENSE_KEY) { if (licenseKeyConfig.isValid && licenseKeyConfig.type === "online") {
const token = await licenseServerOnPremApi.refreshLicense(); const token = await licenseServerOnPremApi.refreshLicense();
if (token) { if (token) {
await syncLicenseKeyOnPremFeatures(true); await syncLicenseKeyOnPremFeatures(true);
@@ -142,10 +146,10 @@ export const licenseServiceFactory = ({
return; return;
} }
if (envConfig.LICENSE_KEY_OFFLINE) { if (licenseKeyConfig.isValid && licenseKeyConfig.type === "offline") {
let isValidOfflineLicense = true; let isValidOfflineLicense = true;
const contents: TOfflineLicenseContents = JSON.parse( const contents: TOfflineLicenseContents = JSON.parse(
Buffer.from(envConfig.LICENSE_KEY_OFFLINE, "base64").toString("utf8") Buffer.from(licenseKeyConfig.licenseKey, "base64").toString("utf8")
); );
const isVerified = await verifyOfflineLicense(JSON.stringify(contents.license), contents.signature); const isVerified = await verifyOfflineLicense(JSON.stringify(contents.license), contents.signature);
@@ -184,7 +188,7 @@ export const licenseServiceFactory = ({
}; };
const initializeBackgroundSync = async () => { const initializeBackgroundSync = async () => {
if (envConfig.LICENSE_KEY) { if (licenseKeyConfig?.isValid && licenseKeyConfig?.type === "online") {
logger.info("Setting up background sync process for refresh onPremFeatures"); logger.info("Setting up background sync process for refresh onPremFeatures");
const job = new CronJob("*/10 * * * *", syncLicenseKeyOnPremFeatures); const job = new CronJob("*/10 * * * *", syncLicenseKeyOnPremFeatures);
job.start(); job.start();
@@ -136,3 +136,13 @@ export type TDelOrgTaxIdDTO = TOrgPermission & { taxId: string };
export type TOrgInvoiceDTO = TOrgPermission; export type TOrgInvoiceDTO = TOrgPermission;
export type TOrgLicensesDTO = TOrgPermission; export type TOrgLicensesDTO = TOrgPermission;
export type TLicenseKeyConfig =
| {
isValid: false;
}
| {
isValid: true;
licenseKey: string;
type: "offline" | "online";
};
+5 -1
View File
@@ -9,6 +9,7 @@ import {
SuperAdminSchema, SuperAdminSchema,
UsersSchema UsersSchema
} from "@app/db/schemas"; } from "@app/db/schemas";
import { getLicenseKeyConfig } from "@app/ee/services/license/license-fns";
import { getConfig, overridableKeys } from "@app/lib/config/env"; import { getConfig, overridableKeys } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto/cryptography"; import { crypto } from "@app/lib/crypto/cryptography";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
@@ -65,6 +66,9 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
const config = await getServerCfg(); const config = await getServerCfg();
const serverEnvs = getConfig(); const serverEnvs = getConfig();
const licenseKeyConfig = getLicenseKeyConfig();
const hasOfflineLicense = licenseKeyConfig.isValid && licenseKeyConfig.type === "offline";
return { return {
config: { config: {
...config, ...config,
@@ -73,7 +77,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
isSecretScanningDisabled: serverEnvs.DISABLE_SECRET_SCANNING, isSecretScanningDisabled: serverEnvs.DISABLE_SECRET_SCANNING,
kubernetesAutoFetchServiceAccountToken: serverEnvs.KUBERNETES_AUTO_FETCH_SERVICE_ACCOUNT_TOKEN, kubernetesAutoFetchServiceAccountToken: serverEnvs.KUBERNETES_AUTO_FETCH_SERVICE_ACCOUNT_TOKEN,
paramsFolderSecretDetectionEnabled: serverEnvs.PARAMS_FOLDER_SECRET_DETECTION_ENABLED, paramsFolderSecretDetectionEnabled: serverEnvs.PARAMS_FOLDER_SECRET_DETECTION_ENABLED,
isOfflineUsageReportsEnabled: !!serverEnvs.LICENSE_KEY_OFFLINE isOfflineUsageReportsEnabled: hasOfflineLicense
} }
}; };
} }
@@ -1,7 +1,7 @@
import crypto from "crypto"; import crypto from "crypto";
import { getLicenseKeyConfig } from "@app/ee/services/license/license-fns";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { TOfflineUsageReportDALFactory } from "./offline-usage-report-dal"; import { TOfflineUsageReportDALFactory } from "./offline-usage-report-dal";
@@ -30,10 +30,12 @@ export const offlineUsageReportServiceFactory = ({
}; };
const generateUsageReportCSV = async () => { const generateUsageReportCSV = async () => {
const cfg = getConfig(); const licenseKeyConfig = getLicenseKeyConfig();
if (!cfg.LICENSE_KEY_OFFLINE) { const hasOfflineLicense = licenseKeyConfig.isValid && licenseKeyConfig.type === "offline";
if (!hasOfflineLicense) {
throw new BadRequestError({ throw new BadRequestError({
message: "Offline usage reports are not enabled. LICENSE_KEY_OFFLINE must be configured." message: "Offline usage reports are not enabled. An offline license must be configured in LICENSE_KEY."
}); });
} }
+7 -6
View File
@@ -14,8 +14,7 @@ This guide walks through how you can use these paid features on a self-hosted in
Once purchased, you will be issued a license key. Once purchased, you will be issued a license key.
</Step> </Step>
<Step title="Activate the license"> <Step title="Activate the license">
Depending on whether or not the environment where Infisical is deployed has internet access, you may be issued a regular license or an offline license. Assign the issued license key to the `LICENSE_KEY` environment variable in your Infisical instance. The system will automatically detect whether the license is online or offline.
<Tabs> <Tabs>
<Tab title="Regular License"> <Tab title="Regular License">
@@ -29,16 +28,18 @@ This guide walks through how you can use these paid features on a self-hosted in
</Note> </Note>
</Tab> </Tab>
<Tab title="Offline License"> <Tab title="Offline License">
- Assign the issued license key to the `LICENSE_KEY_OFFLINE` environment variable in your Infisical instance. - Assign the issued offline license key to the `LICENSE_KEY` environment variable in your Infisical instance.
- The system will automatically detect that it's an offline license based on the key format.
<Note> <Note>
How you set the environment variable will depend on the deployment method you used. Please refer to the documentation of your deployment method for specific instructions. <b>Backwards Compatibility:</b> The `LICENSE_KEY_OFFLINE` environment variable is still supported for backwards compatibility, but we recommend using `LICENSE_KEY` for all license types going forward.
</Note> </Note>
</Tab> </Tab>
</Tabs> </Tabs>
Once your instance starts up, the license key will be validated and you’ll be able to use the paid features. Once your instance starts up, the license key will be validated and you'll be able to use the paid features.
However, when the license expires, Infisical will continue to run, but EE features will be disabled until the license is renewed or a new one is purchased. However, when the license expires, Infisical will continue to run, but EE features will be disabled until the license is renewed or a new one is purchased.
</Step> </Step>
</Steps>
</Steps>