mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 22:27:48 +00:00
Merge pull request #4868 from Infisical/chore/unify-license-key
[ENG-4019] chore: unify license key env variables
This commit is contained in:
@@ -39,3 +39,9 @@ export const getDefaultOnPremFeatures = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const setupLicenseRequestWithStore = () => {};
|
export const setupLicenseRequestWithStore = () => {};
|
||||||
|
|
||||||
|
export const getLicenseKeyConfig = () => {
|
||||||
|
return {
|
||||||
|
isValid: false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,13 +1,56 @@
|
|||||||
import axios, { AxiosError } from "axios";
|
import axios, { AxiosError } from "axios";
|
||||||
|
|
||||||
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 { getConfig, TEnvConfig } from "@app/lib/config/env";
|
||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
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 { LicenseType, TFeatureSet, TLicenseKeyConfig, TOfflineLicenseContents } from "./license-types";
|
||||||
|
|
||||||
|
export const isOfflineLicenseKey = (licenseKey: string): boolean => {
|
||||||
|
try {
|
||||||
|
const contents = JSON.parse(Buffer.from(licenseKey, "base64").toString("utf8")) as TOfflineLicenseContents;
|
||||||
|
|
||||||
|
return "signature" in contents && "license" in contents;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLicenseKeyConfig = (
|
||||||
|
config?: Pick<TEnvConfig, "LICENSE_KEY" | "LICENSE_KEY_OFFLINE">
|
||||||
|
): TLicenseKeyConfig => {
|
||||||
|
const cfg = config || getConfig();
|
||||||
|
|
||||||
|
if (!cfg) {
|
||||||
|
return { isValid: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
const licenseKey = cfg.LICENSE_KEY;
|
||||||
|
|
||||||
|
if (licenseKey) {
|
||||||
|
if (isOfflineLicenseKey(licenseKey)) {
|
||||||
|
return { isValid: true, licenseKey, type: LicenseType.Offline };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { isValid: true, licenseKey, type: LicenseType.Online };
|
||||||
|
}
|
||||||
|
|
||||||
|
const offlineLicenseKey = cfg.LICENSE_KEY_OFFLINE;
|
||||||
|
|
||||||
|
// backwards compatibility
|
||||||
|
if (offlineLicenseKey) {
|
||||||
|
if (isOfflineLicenseKey(offlineLicenseKey)) {
|
||||||
|
return { isValid: true, licenseKey: offlineLicenseKey, type: LicenseType.Offline };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { isValid: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { isValid: false };
|
||||||
|
};
|
||||||
|
|
||||||
export const getDefaultOnPremFeatures = (): TFeatureSet => ({
|
export const getDefaultOnPremFeatures = (): TFeatureSet => ({
|
||||||
_id: null,
|
_id: null,
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ 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,
|
||||||
|
LicenseType,
|
||||||
TAddOrgPmtMethodDTO,
|
TAddOrgPmtMethodDTO,
|
||||||
TAddOrgTaxIdDTO,
|
TAddOrgTaxIdDTO,
|
||||||
TCreateOrgPortalSession,
|
TCreateOrgPortalSession,
|
||||||
@@ -77,6 +78,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(envConfig);
|
||||||
|
|
||||||
const licenseServerCloudApi = setupLicenseRequestWithStore(
|
const licenseServerCloudApi = setupLicenseRequestWithStore(
|
||||||
envConfig.LICENSE_SERVER_URL || "",
|
envConfig.LICENSE_SERVER_URL || "",
|
||||||
@@ -85,10 +87,13 @@ export const licenseServiceFactory = ({
|
|||||||
envConfig.INTERNAL_REGION
|
envConfig.INTERNAL_REGION
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onlineLicenseKey =
|
||||||
|
licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.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 +136,7 @@ export const licenseServiceFactory = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (envConfig.LICENSE_KEY) {
|
if (licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Online) {
|
||||||
const token = await licenseServerOnPremApi.refreshLicense();
|
const token = await licenseServerOnPremApi.refreshLicense();
|
||||||
if (token) {
|
if (token) {
|
||||||
await syncLicenseKeyOnPremFeatures(true);
|
await syncLicenseKeyOnPremFeatures(true);
|
||||||
@@ -142,10 +147,10 @@ export const licenseServiceFactory = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (envConfig.LICENSE_KEY_OFFLINE) {
|
if (licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.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 +189,7 @@ export const licenseServiceFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const initializeBackgroundSync = async () => {
|
const initializeBackgroundSync = async () => {
|
||||||
if (envConfig.LICENSE_KEY) {
|
if (licenseKeyConfig?.isValid && licenseKeyConfig?.type === LicenseType.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,18 @@ export type TDelOrgTaxIdDTO = TOrgPermission & { taxId: string };
|
|||||||
export type TOrgInvoiceDTO = TOrgPermission;
|
export type TOrgInvoiceDTO = TOrgPermission;
|
||||||
|
|
||||||
export type TOrgLicensesDTO = TOrgPermission;
|
export type TOrgLicensesDTO = TOrgPermission;
|
||||||
|
|
||||||
|
export enum LicenseType {
|
||||||
|
Offline = "offline",
|
||||||
|
Online = "online"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TLicenseKeyConfig =
|
||||||
|
| {
|
||||||
|
isValid: false;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
isValid: true;
|
||||||
|
licenseKey: string;
|
||||||
|
type: LicenseType;
|
||||||
|
};
|
||||||
|
|||||||
@@ -2431,6 +2431,7 @@ export const registerRoutes = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await kmsService.startService(hsmStatus);
|
||||||
await telemetryQueue.startTelemetryCheck();
|
await telemetryQueue.startTelemetryCheck();
|
||||||
await telemetryQueue.startAggregatedEventsJob();
|
await telemetryQueue.startAggregatedEventsJob();
|
||||||
await dailyResourceCleanUp.init();
|
await dailyResourceCleanUp.init();
|
||||||
@@ -2443,7 +2444,6 @@ export const registerRoutes = async (
|
|||||||
await pkiSubscriberQueue.startDailyAutoRenewalJob();
|
await pkiSubscriberQueue.startDailyAutoRenewalJob();
|
||||||
await pkiAlertV2Queue.init();
|
await pkiAlertV2Queue.init();
|
||||||
await certificateV3Queue.init();
|
await certificateV3Queue.init();
|
||||||
await kmsService.startService(hsmStatus);
|
|
||||||
await microsoftTeamsService.start();
|
await microsoftTeamsService.start();
|
||||||
await dynamicSecretQueueService.init();
|
await dynamicSecretQueueService.init();
|
||||||
await eventBusService.init();
|
await eventBusService.init();
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import {
|
|||||||
SuperAdminSchema,
|
SuperAdminSchema,
|
||||||
UsersSchema
|
UsersSchema
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
|
import { getLicenseKeyConfig } from "@app/ee/services/license/license-fns";
|
||||||
|
import { LicenseType } from "@app/ee/services/license/license-types";
|
||||||
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 +67,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 === LicenseType.Offline;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
config: {
|
config: {
|
||||||
...config,
|
...config,
|
||||||
@@ -73,7 +78,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,8 @@
|
|||||||
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 { LicenseType } from "@app/ee/services/license/license-types";
|
||||||
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 +31,13 @@ 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 === LicenseType.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. Usage reports are only available for self-hosted offline instances"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
Set your license key as the value of the **LICENSE_KEY** environment variable within your Infisical instance.
|
||||||
|
|
||||||
|
|
||||||
<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.
|
While the LICENSE_KEY_OFFLINE environment variable continues to be supported for compatibility with existing configurations, we recommend transitioning to 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>
|
||||||
|
|||||||
Reference in New Issue
Block a user