mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 15:28:25 +00:00
improvements: address requested changes
This commit is contained in:
@@ -75,9 +75,8 @@ We're on a mission to make security tooling more accessible to everyone, not jus
|
|||||||
|
|
||||||
### Key Management (KMS):
|
### Key Management (KMS):
|
||||||
|
|
||||||
- **[Cryptograhic Keys](https://infisical.com/docs/documentation/platform/kms)**: Manage and perform cryptographic operations with personally managed keys.
|
- **[Cryptograhic Keys](https://infisical.com/docs/documentation/platform/kms)**: Centrally manage keys across projects through a user-friendly interface or via the API.
|
||||||
- **[Encrypt and Decrypt Data](https://infisical.com/docs/documentation/platform/kms#guide-to-encrypting-data)**: Use symmetric keys to encrypt and decrypt data.
|
- **[Encrypt and Decrypt Data](https://infisical.com/docs/documentation/platform/kms#guide-to-encrypting-data)**: Use symmetric keys to encrypt and decrypt data.
|
||||||
- **[Audit Trail](https://infisical.com/docs/documentation/platform/kms)**: Maintain detailed logs of all key-related activities for compliance and security analysis.
|
|
||||||
|
|
||||||
### General Platform:
|
### General Platform:
|
||||||
- **Authentication Methods**: Authenticate machine identities with Infisical using a cloud-native or platform agnostic authentication method ([Kubernetes Auth](https://infisical.com/docs/documentation/platform/identities/kubernetes-auth), [GCP Auth](https://infisical.com/docs/documentation/platform/identities/gcp-auth), [Azure Auth](https://infisical.com/docs/documentation/platform/identities/azure-auth), [AWS Auth](https://infisical.com/docs/documentation/platform/identities/aws-auth), [OIDC Auth](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general), [Universal Auth](https://infisical.com/docs/documentation/platform/identities/universal-auth)).
|
- **Authentication Methods**: Authenticate machine identities with Infisical using a cloud-native or platform agnostic authentication method ([Kubernetes Auth](https://infisical.com/docs/documentation/platform/identities/kubernetes-auth), [GCP Auth](https://infisical.com/docs/documentation/platform/identities/gcp-auth), [Azure Auth](https://infisical.com/docs/documentation/platform/identities/azure-auth), [AWS Auth](https://infisical.com/docs/documentation/platform/identities/aws-auth), [OIDC Auth](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general), [Universal Auth](https://infisical.com/docs/documentation/platform/identities/universal-auth)).
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { dropConstraintIfExists } from "@app/db/migrations/utils/dropConstraintIfExists";
|
||||||
import { TableName } from "@app/db/schemas";
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
export async function up(knex: Knex): Promise<void> {
|
export async function up(knex: Knex): Promise<void> {
|
||||||
@@ -7,12 +8,14 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
const hasOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId");
|
const hasOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId");
|
||||||
const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug");
|
const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug");
|
||||||
|
|
||||||
|
// drop constraint if exists (won't exist if rolled back, see below)
|
||||||
|
await dropConstraintIfExists(TableName.KmsKey, "kms_keys_orgid_slug_unique", knex);
|
||||||
|
|
||||||
// projectId for CMEK functionality
|
// projectId for CMEK functionality
|
||||||
await knex.schema.alterTable(TableName.KmsKey, (table) => {
|
await knex.schema.alterTable(TableName.KmsKey, (table) => {
|
||||||
table.string("projectId").nullable().references("id").inTable(TableName.Project).onDelete("CASCADE");
|
table.string("projectId").nullable().references("id").inTable(TableName.Project).onDelete("CASCADE");
|
||||||
|
|
||||||
if (hasOrgId) {
|
if (hasOrgId) {
|
||||||
table.dropUnique(["orgId", "slug"]); // prevents using the same key name in different projects so swapping constraint
|
|
||||||
table.unique(["orgId", "projectId", "slug"]);
|
table.unique(["orgId", "projectId", "slug"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +39,6 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
|
|
||||||
if (hasOrgId) {
|
if (hasOrgId) {
|
||||||
table.dropUnique(["orgId", "projectId", "slug"]);
|
table.dropUnique(["orgId", "projectId", "slug"]);
|
||||||
table.unique(["orgId", "slug"]);
|
|
||||||
}
|
}
|
||||||
table.dropColumn("projectId");
|
table.dropColumn("projectId");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
|
export const dropConstraintIfExists = (tableName: TableName, constraintName: string, knex: Knex) =>
|
||||||
|
knex.raw(`ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`);
|
||||||
@@ -2,24 +2,13 @@ import { CreateKeyCommand, DecryptCommand, DescribeKeyCommand, EncryptCommand, K
|
|||||||
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||||
import { randomUUID } from "crypto";
|
import { randomUUID } from "crypto";
|
||||||
|
|
||||||
import { getConfig } from "@app/lib/config/env";
|
|
||||||
|
|
||||||
import { ExternalKmsAwsSchema, KmsAwsCredentialType, TExternalKmsAwsSchema, TExternalKmsProviderFns } from "./model";
|
import { ExternalKmsAwsSchema, KmsAwsCredentialType, TExternalKmsAwsSchema, TExternalKmsProviderFns } from "./model";
|
||||||
|
|
||||||
const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
||||||
const appCfg = getConfig();
|
|
||||||
|
|
||||||
if (providerInputs.credential.type === KmsAwsCredentialType.AssumeRole) {
|
if (providerInputs.credential.type === KmsAwsCredentialType.AssumeRole) {
|
||||||
const awsCredential = providerInputs.credential.data;
|
const awsCredential = providerInputs.credential.data;
|
||||||
const stsClient = new STSClient({
|
const stsClient = new STSClient({
|
||||||
region: providerInputs.awsRegion,
|
region: providerInputs.awsRegion
|
||||||
credentials:
|
|
||||||
appCfg.CLIENT_ID_AWS_INTEGRATION && appCfg.CLIENT_SECRET_AWS_INTEGRATION
|
|
||||||
? {
|
|
||||||
accessKeyId: appCfg.CLIENT_ID_AWS_INTEGRATION,
|
|
||||||
secretAccessKey: appCfg.CLIENT_SECRET_AWS_INTEGRATION
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
});
|
});
|
||||||
const command = new AssumeRoleCommand({
|
const command = new AssumeRoleCommand({
|
||||||
RoleArn: awsCredential.assumeRoleArn,
|
RoleArn: awsCredential.assumeRoleArn,
|
||||||
|
|||||||
@@ -24,17 +24,5 @@ export const isBase64 = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getBase64SizeInBytes = (base64String: string) => {
|
export const getBase64SizeInBytes = (base64String: string) => {
|
||||||
// Remove data URI scheme if present
|
return Buffer.from(base64String, "base64").length;
|
||||||
const base64 = base64String.replace(/^data:.*?;base64,/, "");
|
|
||||||
|
|
||||||
// Remove padding characters
|
|
||||||
const withoutPadding = base64.replace(/=+$/, "");
|
|
||||||
|
|
||||||
// Calculate bits: each base64 character represents 6 bits
|
|
||||||
const totalBits = withoutPadding.length * 6;
|
|
||||||
|
|
||||||
// Convert bits to bytes (8 bits = 1 byte)
|
|
||||||
const bytes = totalBits / 8;
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ const base64Schema = z.string().superRefine((val, ctx) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getBase64SizeInBytes(val) > 6144) {
|
if (getBase64SizeInBytes(val) > 4096) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
message: "data cannot exceed 6144 bytes"
|
message: "data cannot exceed 4096 bytes"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -65,7 +65,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
body: { projectId, name, description, encryptionAlgorithm },
|
body: { projectId, name, description, encryptionAlgorithm },
|
||||||
@@ -118,7 +118,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
params: { keyId },
|
params: { keyId },
|
||||||
@@ -162,7 +162,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
params: { keyId },
|
params: { keyId },
|
||||||
@@ -214,7 +214,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
query: { projectId, ...dto },
|
query: { projectId, ...dto },
|
||||||
@@ -259,7 +259,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
params: { keyId },
|
params: { keyId },
|
||||||
@@ -304,7 +304,7 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const {
|
const {
|
||||||
params: { keyId },
|
params: { keyId },
|
||||||
|
|||||||
@@ -67,16 +67,6 @@ export const kmsServiceFactory = ({
|
|||||||
}: TKmsServiceFactoryDep) => {
|
}: TKmsServiceFactoryDep) => {
|
||||||
let ROOT_ENCRYPTION_KEY = Buffer.alloc(0);
|
let ROOT_ENCRYPTION_KEY = Buffer.alloc(0);
|
||||||
|
|
||||||
const $getRootEncryptionKey = (encryptionAlgorithm: SymmetricEncryption) => {
|
|
||||||
switch (encryptionAlgorithm) {
|
|
||||||
case SymmetricEncryption.AES_GCM_128:
|
|
||||||
return ROOT_ENCRYPTION_KEY.subarray(0, 16); // taking first 128bits
|
|
||||||
case SymmetricEncryption.AES_GCM_256:
|
|
||||||
default:
|
|
||||||
return ROOT_ENCRYPTION_KEY;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate KMS Key
|
* Generate KMS Key
|
||||||
* This function is responsibile for generating the infisical internal KMS for various entities
|
* This function is responsibile for generating the infisical internal KMS for various entities
|
||||||
@@ -91,10 +81,11 @@ export const kmsServiceFactory = ({
|
|||||||
encryptionAlgorithm = SymmetricEncryption.AES_GCM_256,
|
encryptionAlgorithm = SymmetricEncryption.AES_GCM_256,
|
||||||
description
|
description
|
||||||
}: TGenerateKMSDTO) => {
|
}: TGenerateKMSDTO) => {
|
||||||
const cipher = symmetricCipherService(encryptionAlgorithm);
|
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
|
|
||||||
const kmsKeyMaterial = randomSecureBytes(getByteLengthForAlgorithm(encryptionAlgorithm));
|
const kmsKeyMaterial = randomSecureBytes(getByteLengthForAlgorithm(encryptionAlgorithm));
|
||||||
const encryptedKeyMaterial = cipher.encrypt(kmsKeyMaterial, $getRootEncryptionKey(encryptionAlgorithm));
|
|
||||||
|
const encryptedKeyMaterial = cipher.encrypt(kmsKeyMaterial, ROOT_ENCRYPTION_KEY);
|
||||||
const sanitizedName = name ? slugify(name) : slugify(alphaNumericNanoId(8).toLowerCase());
|
const sanitizedName = name ? slugify(name) : slugify(alphaNumericNanoId(8).toLowerCase());
|
||||||
const dbQuery = async (db: Knex) => {
|
const dbQuery = async (db: Knex) => {
|
||||||
const kmsDoc = await kmsDAL.create(
|
const kmsDoc = await kmsDAL.create(
|
||||||
@@ -308,17 +299,13 @@ export const kmsServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal KMS
|
// internal KMS
|
||||||
const encryptionAlgorithm =
|
const keyCipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
(kmsDoc.internalKms?.encryptionAlgorithm as SymmetricEncryption) ?? SymmetricEncryption.AES_GCM_256;
|
const dataCipher = symmetricCipherService(kmsDoc.internalKms?.encryptionAlgorithm as SymmetricEncryption);
|
||||||
const cipher = symmetricCipherService(encryptionAlgorithm);
|
const kmsKey = keyCipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||||
const kmsKey = cipher.decrypt(
|
|
||||||
kmsDoc.internalKms?.encryptedKey as Buffer,
|
|
||||||
$getRootEncryptionKey(encryptionAlgorithm)
|
|
||||||
);
|
|
||||||
|
|
||||||
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
||||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, kmsKey);
|
const decryptedBlob = dataCipher.decrypt(cipherTextBlob, kmsKey);
|
||||||
return Promise.resolve(decryptedBlob);
|
return Promise.resolve(decryptedBlob);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -374,15 +361,11 @@ export const kmsServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal KMS
|
// internal KMS
|
||||||
const encryptionAlgorithm =
|
const keyCipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
(kmsDoc.internalKms?.encryptionAlgorithm as SymmetricEncryption) ?? SymmetricEncryption.AES_GCM_256;
|
const dataCipher = symmetricCipherService(kmsDoc.internalKms?.encryptionAlgorithm as SymmetricEncryption);
|
||||||
const cipher = symmetricCipherService(encryptionAlgorithm);
|
|
||||||
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
||||||
const kmsKey = cipher.decrypt(
|
const kmsKey = keyCipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||||
kmsDoc.internalKms?.encryptedKey as Buffer,
|
const encryptedPlainTextBlob = dataCipher.encrypt(plainText, kmsKey);
|
||||||
$getRootEncryptionKey(encryptionAlgorithm)
|
|
||||||
);
|
|
||||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, kmsKey);
|
|
||||||
|
|
||||||
// Buffer#1 encrypted text + Buffer#2 version number
|
// Buffer#1 encrypted text + Buffer#2 version number
|
||||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description: "Learn how to authenticate with Infisical for EC2 instances, Lambda
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the AWS Auth workflow for authenticating AWS IAM principals with Infisical.
|
The following sequence diagram illustrates the AWS Auth workflow for authenticating AWS IAM principals with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description: "Learn how to authenticate with Infisical for services on Azure"
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the Azure Auth workflow for authenticating Azure [service principals](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser) with Infisical.
|
The following sequence diagram illustrates the Azure Auth workflow for authenticating Azure [service principals](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser) with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ description: "Learn how to authenticate with Infisical for services on Google Cl
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the GCP ID Token Auth workflow for authenticating GCP resources with Infisical.
|
The following sequence diagram illustrates the GCP ID Token Auth workflow for authenticating GCP resources with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
@@ -182,7 +182,7 @@ access the Infisical API using the GCP ID Token authentication method.
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the GCP IAM Auth workflow for authenticating GCP IAM service accounts with Infisical.
|
The following sequence diagram illustrates the GCP IAM Auth workflow for authenticating GCP IAM service accounts with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description: "Learn how to authenticate with Infisical in Kubernetes"
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the Kubernetes Auth workflow for authenticating applications running in pods with Infisical.
|
The following sequence diagram illustrates the Kubernetes Auth workflow for authenticating applications running in pods with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description: "Learn how to authenticate to Infisical from any platform or enviro
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the Token Auth workflow for authenticating clients with Infisical.
|
The following sequence diagram illustrates the Token Auth workflow for authenticating clients with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description: "Learn how to authenticate to Infisical from any platform or enviro
|
|||||||
|
|
||||||
## Diagram
|
## Diagram
|
||||||
|
|
||||||
The following sequence digram illustrates the Universal Auth workflow for authenticating clients with Infisical.
|
The following sequence diagram illustrates the Universal Auth workflow for authenticating clients with Infisical.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|||||||
@@ -26,8 +26,3 @@ For existing projects, you can configure the KMS from the Project Settings page.
|
|||||||
## External KMS
|
## External KMS
|
||||||
|
|
||||||
Infisical supports the use of external KMS solutions to enhance security and compliance. You can configure your project to use services like [AWS Key Management Service](./aws-kms) for managing encryption.
|
Infisical supports the use of external KMS solutions to enhance security and compliance. You can configure your project to use services like [AWS Key Management Service](./aws-kms) for managing encryption.
|
||||||
|
|
||||||
## Infisical KMS
|
|
||||||
|
|
||||||
Infisical exposes it's internal KMS solution, [Infisical KMS](../kms), enabling you to create and manage keys to perform cryptographic operations with.
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,20 +4,43 @@ sidebarTitle: "Key Management (KMS)"
|
|||||||
description: "Learn how to manage and use cryptographic keys with Infisical."
|
description: "Learn how to manage and use cryptographic keys with Infisical."
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduction
|
## Diagram
|
||||||
|
|
||||||
Infisical's <strong>Key Management System (KMS)</strong> allows you to create, store and manage cryptographic keys.
|
The following sequence diagram illustrates the KMS workflow for creating and using a cryptographic key.
|
||||||
These keys can be used to perform cryptographic operations such as data encryption. You can access
|
|
||||||
Infisical's KMS from the [project](./project) sidebar.
|
|
||||||
|
|
||||||
## Features
|
<div align="center">
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Client as Client
|
||||||
|
participant Infis as Infisical
|
||||||
|
|
||||||
1. <strong>Centralized Key Storage:</strong> Securely store all your organization's cryptographic keys in one location.
|
Note over Client,Infis: Step 1: Create KMS Key
|
||||||
2. <strong>Encryption and
|
Client->>Infis: create key request
|
||||||
Decryption:</strong> Provide on-demand encryption and decryption services without exposing the keys to
|
Infis->>Client: keyId
|
||||||
external applications.
|
|
||||||
3. <strong>Audit
|
Note over Client,Infis: Step 2: Encrypt Data
|
||||||
Trails:</strong> Maintain detailed logs of all key-related activities for compliance and security analysis.
|
Client->>Infis: plaintext and keyId
|
||||||
|
Infis->>Client: ciphertext
|
||||||
|
|
||||||
|
Note over Client,Infis: Step 3: Decrypt Data
|
||||||
|
Client->>Infis: ciphertext and keyId
|
||||||
|
Infis->>Client: plaintext
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Concept
|
||||||
|
|
||||||
|
At a high-level, Infisical generates a KMS key when requested, returning the `keyId` to the requester. This `keyId` can then be used
|
||||||
|
to perform cryptographic operations such as encrypting and decrypting data.
|
||||||
|
|
||||||
|
To be more specific:
|
||||||
|
|
||||||
|
1. The client requests to create a key using the `/api/v1/kms/keys` endpoint.
|
||||||
|
2. Infisical generates a KMS key and returns the `keyId` to the requester.
|
||||||
|
3. The client requests to encrypt `plaintext` data (base64 encoded) with the specified `keyId` using the `/api/v1/kms/keys/<key-id>/encrypt` endpoint.
|
||||||
|
4. Infisical returns the encrypted data or `ciphertext` (base64 encoded).
|
||||||
|
3. The client requests to decrypt the `ciphertext` data with the original `keyId` using the `/api/v1/kms/keys/<key-id>/decrypt` endpoint.
|
||||||
|
4. Infisical returns the decrypted `plaintext` data (base64 encoded).
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
Your keys will never be used or viewable outside of Infisical KMS.
|
Your keys will never be used or viewable outside of Infisical KMS.
|
||||||
@@ -38,7 +61,8 @@ In the following steps, we'll explore how to generate a cryptographic key and en
|
|||||||
Specify your key details. Here's some guidance on each field:
|
Specify your key details. Here's some guidance on each field:
|
||||||
|
|
||||||
- Name: A slug-friendly name for the key.
|
- Name: A slug-friendly name for the key.
|
||||||
- Type: The encryption algorithm associated with this key. By default symmetric `AES-GCM-256` is selected,
|
- Type: The encryption algorithm associated with this key. By default symmetric `AES-GCM-256` is
|
||||||
|
selected,
|
||||||
but
|
but
|
||||||
Infisical will continue to add more options down the road.
|
Infisical will continue to add more options down the road.
|
||||||
- Description: An optional description of what this key is used for.
|
- Description: An optional description of what this key is used for.
|
||||||
@@ -113,7 +137,8 @@ In the following steps, we'll explore how to generate a cryptographic key and en
|
|||||||
|
|
||||||
```bash Request
|
```bash Request
|
||||||
curl --request POST \
|
curl --request POST \
|
||||||
--url https://app.infisical.com/api/v1/kms/keys/<key-id>/encrypt \
|
--url https://app.infisical.com/api/v1/kms/keys/
|
||||||
|
<key-id>/encrypt \
|
||||||
--header 'Content-Type: application/json' \
|
--header 'Content-Type: application/json' \
|
||||||
--data '{
|
--data '{
|
||||||
"plaintext": "lUFHM5Ggwo6TOfpuN1S==" // base64 encoded plaintext
|
"plaintext": "lUFHM5Ggwo6TOfpuN1S==" // base64 encoded plaintext
|
||||||
@@ -168,7 +193,8 @@ In the following steps, we'll explore how to decrypt data.
|
|||||||
|
|
||||||
```bash Request
|
```bash Request
|
||||||
curl --request POST \
|
curl --request POST \
|
||||||
--url https://app.infisical.com/api/v1/kms/keys/<key-id>/decrypt \
|
--url https://app.infisical.com/api/v1/kms/keys/
|
||||||
|
<key-id>/decrypt \
|
||||||
--header 'Content-Type: application/json' \
|
--header 'Content-Type: application/json' \
|
||||||
--data '{
|
--data '{
|
||||||
"ciphertext": "HwFHwSFHwlMF6TOfp==" // base64 encoded ciphertext
|
"ciphertext": "HwFHwSFHwlMF6TOfp==" // base64 encoded ciphertext
|
||||||
@@ -197,4 +223,8 @@ In the following steps, we'll explore how to decrypt data.
|
|||||||
<Accordion title="Can key material be accessed outside of Infisical KMS?">
|
<Accordion title="Can key material be accessed outside of Infisical KMS?">
|
||||||
No. Infisical's KMS will never expose your keys, encrypted or decrypted, to external sources.
|
No. Infisical's KMS will never expose your keys, encrypted or decrypted, to external sources.
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
<Accordion title="What algorithms does Infisical KMS support?">
|
||||||
|
Currently, Infisical only supports AES-128-GCM and AES-256-GCM for encryption operations. We anticipate
|
||||||
|
supporting more algorithms and cryptographic operations in the coming months.
|
||||||
|
</Accordion>
|
||||||
</AccordionGroup>
|
</AccordionGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user