mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +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 getLicenseKeyConfig = () => {
|
||||
return {
|
||||
isValid: false
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,13 +1,56 @@
|
||||
import axios, { AxiosError } from "axios";
|
||||
|
||||
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 { BadRequestError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
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 => ({
|
||||
_id: null,
|
||||
|
||||
@@ -22,9 +22,10 @@ import { OrgPermissionBillingActions, OrgPermissionSubjects } from "../permissio
|
||||
import { TPermissionServiceFactory } from "../permission/permission-service-types";
|
||||
import { BillingPlanRows, BillingPlanTableHead } from "./licence-enums";
|
||||
import { TLicenseDALFactory } from "./license-dal";
|
||||
import { getDefaultOnPremFeatures, setupLicenseRequestWithStore } from "./license-fns";
|
||||
import { getDefaultOnPremFeatures, getLicenseKeyConfig, setupLicenseRequestWithStore } from "./license-fns";
|
||||
import {
|
||||
InstanceType,
|
||||
LicenseType,
|
||||
TAddOrgPmtMethodDTO,
|
||||
TAddOrgTaxIdDTO,
|
||||
TCreateOrgPortalSession,
|
||||
@@ -77,6 +78,7 @@ export const licenseServiceFactory = ({
|
||||
let instanceType = InstanceType.OnPrem;
|
||||
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
|
||||
let selfHostedLicense: TOfflineLicense | null = null;
|
||||
const licenseKeyConfig = getLicenseKeyConfig(envConfig);
|
||||
|
||||
const licenseServerCloudApi = setupLicenseRequestWithStore(
|
||||
envConfig.LICENSE_SERVER_URL || "",
|
||||
@@ -85,10 +87,13 @@ export const licenseServiceFactory = ({
|
||||
envConfig.INTERNAL_REGION
|
||||
);
|
||||
|
||||
const onlineLicenseKey =
|
||||
licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Online ? licenseKeyConfig.licenseKey : "";
|
||||
|
||||
const licenseServerOnPremApi = setupLicenseRequestWithStore(
|
||||
envConfig.LICENSE_SERVER_URL || "",
|
||||
LICENSE_SERVER_ON_PREM_LOGIN,
|
||||
envConfig.LICENSE_KEY || "",
|
||||
onlineLicenseKey,
|
||||
envConfig.INTERNAL_REGION
|
||||
);
|
||||
|
||||
@@ -131,7 +136,7 @@ export const licenseServiceFactory = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (envConfig.LICENSE_KEY) {
|
||||
if (licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Online) {
|
||||
const token = await licenseServerOnPremApi.refreshLicense();
|
||||
if (token) {
|
||||
await syncLicenseKeyOnPremFeatures(true);
|
||||
@@ -142,10 +147,10 @@ export const licenseServiceFactory = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (envConfig.LICENSE_KEY_OFFLINE) {
|
||||
if (licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Offline) {
|
||||
let isValidOfflineLicense = true;
|
||||
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);
|
||||
|
||||
@@ -184,7 +189,7 @@ export const licenseServiceFactory = ({
|
||||
};
|
||||
|
||||
const initializeBackgroundSync = async () => {
|
||||
if (envConfig.LICENSE_KEY) {
|
||||
if (licenseKeyConfig?.isValid && licenseKeyConfig?.type === LicenseType.Online) {
|
||||
logger.info("Setting up background sync process for refresh onPremFeatures");
|
||||
const job = new CronJob("*/10 * * * *", syncLicenseKeyOnPremFeatures);
|
||||
job.start();
|
||||
|
||||
@@ -136,3 +136,18 @@ export type TDelOrgTaxIdDTO = TOrgPermission & { taxId: string };
|
||||
export type TOrgInvoiceDTO = 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.startAggregatedEventsJob();
|
||||
await dailyResourceCleanUp.init();
|
||||
@@ -2443,7 +2444,6 @@ export const registerRoutes = async (
|
||||
await pkiSubscriberQueue.startDailyAutoRenewalJob();
|
||||
await pkiAlertV2Queue.init();
|
||||
await certificateV3Queue.init();
|
||||
await kmsService.startService(hsmStatus);
|
||||
await microsoftTeamsService.start();
|
||||
await dynamicSecretQueueService.init();
|
||||
await eventBusService.init();
|
||||
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
SuperAdminSchema,
|
||||
UsersSchema
|
||||
} 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 { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
@@ -65,6 +67,9 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
||||
const config = await getServerCfg();
|
||||
const serverEnvs = getConfig();
|
||||
|
||||
const licenseKeyConfig = getLicenseKeyConfig();
|
||||
const hasOfflineLicense = licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Offline;
|
||||
|
||||
return {
|
||||
config: {
|
||||
...config,
|
||||
@@ -73,7 +78,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
||||
isSecretScanningDisabled: serverEnvs.DISABLE_SECRET_SCANNING,
|
||||
kubernetesAutoFetchServiceAccountToken: serverEnvs.KUBERNETES_AUTO_FETCH_SERVICE_ACCOUNT_TOKEN,
|
||||
paramsFolderSecretDetectionEnabled: serverEnvs.PARAMS_FOLDER_SECRET_DETECTION_ENABLED,
|
||||
isOfflineUsageReportsEnabled: !!serverEnvs.LICENSE_KEY_OFFLINE
|
||||
isOfflineUsageReportsEnabled: hasOfflineLicense
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
import { getLicenseKeyConfig } from "@app/ee/services/license/license-fns";
|
||||
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 { TOfflineUsageReportDALFactory } from "./offline-usage-report-dal";
|
||||
@@ -30,10 +31,13 @@ export const offlineUsageReportServiceFactory = ({
|
||||
};
|
||||
|
||||
const generateUsageReportCSV = async () => {
|
||||
const cfg = getConfig();
|
||||
if (!cfg.LICENSE_KEY_OFFLINE) {
|
||||
const licenseKeyConfig = getLicenseKeyConfig();
|
||||
const hasOfflineLicense = licenseKeyConfig.isValid && licenseKeyConfig.type === LicenseType.Offline;
|
||||
|
||||
if (!hasOfflineLicense) {
|
||||
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,14 +14,13 @@ 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.
|
||||
</Step>
|
||||
<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>
|
||||
<Tab title="Regular License">
|
||||
- Assign the issued license key to the `LICENSE_KEY` environment variable in your Infisical instance.
|
||||
|
||||
- Your Infisical instance will need to communicate with the Infisical license server to validate the license key.
|
||||
- Your Infisical instance will need to communicate with the Infisical license server to validate the license key.
|
||||
If you want to limit outgoing connections only to the Infisical license server, you can use the following IP addresses: `13.248.249.247` and `35.71.190.59`
|
||||
|
||||
<Note>
|
||||
@@ -29,16 +28,18 @@ This guide walks through how you can use these paid features on a self-hosted in
|
||||
</Note>
|
||||
</Tab>
|
||||
<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>
|
||||
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>
|
||||
</Tab>
|
||||
</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.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
</Steps>
|
||||
|
||||
Reference in New Issue
Block a user