Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/api/endpoints/kms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { ApiClient } from "../base";
import { CreateKmsKeyRequest, DecryptKmsKeyOptions, DecryptKmsKeyResponse, EncryptKmsKeyOptions, EncryptKmsKeyResponse, GetKmsKeyByNameOptions, KmsKeyResponse, KmsPublicKeyReponse, KmsSignDataOptions, KmsSignDataResponse, KmsSigningAlgorithmsResponse, KmsVerifySignatureOptions, KmsVerifySignatureResponse, ListKmsKeyRequest, ListKmsKeysResponse, UpdateKmsKeyRequest } from "../types";

export class KmsApi {
constructor(private apiClient: ApiClient){}

async ListKeys(params: ListKmsKeyRequest) : Promise<ListKmsKeysResponse>{
return this.apiClient.get<ListKmsKeysResponse>("/api/v1/kms/keys", {
params: params,
});
}

async GetKeyById(keyId: string) : Promise<KmsKeyResponse> {
return this.apiClient.get<KmsKeyResponse>(`/api/v1/kms/keys/${keyId}`);
}

async GetKeyByName(options: GetKmsKeyByNameOptions): Promise<KmsKeyResponse> {
return this.apiClient.get<KmsKeyResponse>(`/api/v1/kms/keys/key-name/${options.keyName}`, {
params: { projectId: options.projectId },
});
}

async CreateKey(data: CreateKmsKeyRequest): Promise<KmsKeyResponse> {
return this.apiClient.post<KmsKeyResponse>(`/api/v1/kms/keys`, data);
}

async updateKey(options: UpdateKmsKeyRequest): Promise<KmsKeyResponse> {
const { keyId, ...updateData } = options;
return this.apiClient.patch<KmsKeyResponse>(`/api/v1/kms/keys/${keyId}`, updateData);
}

async deleteKey(keyId: string): Promise<KmsKeyResponse> {
return this.apiClient.delete<KmsKeyResponse>(`/api/v1/kms/keys/${keyId}`);
}

async encryptData(options: EncryptKmsKeyOptions): Promise<EncryptKmsKeyResponse>{
const { keyId, plaintext } = options;
return this.apiClient.post<EncryptKmsKeyResponse>(`/api/v1/kms/keys/${keyId}/encrypt`, { plaintext });
}

async decryptData(options: DecryptKmsKeyOptions): Promise<DecryptKmsKeyResponse>{
const { keyId, ciphertext } = options;
return this.apiClient.post<DecryptKmsKeyResponse>(`/api/v1/kms/keys/${keyId}/decrypt`, { ciphertext });
}

async signData(options: KmsSignDataOptions): Promise<KmsSignDataResponse>{
const {keyId, ...payloadOptions} = options;
return this.apiClient.post<KmsSignDataResponse>(`/api/v1/kms/keys/${keyId}/sign`, payloadOptions);
}

async verifySignature(options: KmsVerifySignatureOptions): Promise<KmsVerifySignatureResponse> {
const { keyId, ...payloadOptions } = options;
return this.apiClient.post<KmsVerifySignatureResponse>(`/api/v1/kms/keys/${keyId}/verify`, payloadOptions);
}

async getPublicKey(keyId: string): Promise<KmsPublicKeyReponse> {
return this.apiClient.get<KmsPublicKeyReponse>(`/api/v1/kms/keys/${keyId}/public-key`);
}

async listSigningAlgorithms(keyId: string): Promise<KmsSigningAlgorithmsResponse> {
return this.apiClient.get<KmsSigningAlgorithmsResponse>(`/api/v1/kms/keys/${keyId}/signing-algorithms`);
}
}
1 change: 1 addition & 0 deletions src/api/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from "./dynamic-secrets";
export * from "./environments";
export * from "./projects";
export * from "./folders";
export * from "./kms";

export interface ApiResponse<T> {
statusCode: number;
Expand Down
142 changes: 142 additions & 0 deletions src/api/types/kms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@


export interface KmsKey {
id: string;
orgId: string;
name: string;
createdAt: string;
updatedAt: string;
encryptionAlgorithm: string;
description?: string;
isDisabled?: boolean;
projectId?: string;
keyUsage?: string;
version?: number;
}

export interface KmsKeyResponse {
key: KmsKey;
}

export interface GetKmsKeyByNameOptions {
keyName: string;
projectId: string;
}

export interface ListKmsKeysResponse {
keys: KmsKey[];
totalCount: number;
}

export enum KmsKeyUsage {
EncryptDecrypt = "encrypt-decrypt",
SignVerify = "sign-verify"
}

export enum KmsKeyEncryptionAlgorithm {
AES256 = "aes-256-gcm",
AES128 = "aes-128-gcm",
RSA_4096 = "RSA_4096",
ECC_NIST_P256 = "ECC_NIST_P256",
}
export interface CreateKmsKeyRequest {
projectId: string;
name: string;
description?: string;
keyUsage?: KmsKeyUsage;
encryptionAlgorithm?: KmsKeyEncryptionAlgorithm;
}

export type CreateKmsOptions = {
projectId: string;
name: string;
description?: string;
keyUsage?: KmsKeyUsage;
encryptionAlgorithm?: KmsKeyEncryptionAlgorithm;
}
export interface UpdateKmsKeyRequest {
keyId: string;
name?: string;
isDisabled?: boolean;
description?: string;
}
export interface ListKmsKeyRequest {
projectId: string;
offset?: number;
limit?: number;
orderBy?: "name";
orderDirection?: "asc"|"desc";
search?: string;
}

export type ListKmsOptions = {
projectId: string;
offset?: number;
limit?: number;
orderBy?: "name";
orderDirection?: "asc" | "desc";
search?: string;
}

export interface EncryptKmsKeyOptions {
keyId: string;
plaintext: string;
}

export interface DecryptKmsKeyOptions {
keyId: string;
ciphertext: string;
}
export interface EncryptKmsKeyResponse {
ciphertext: string;
}
export interface DecryptKmsKeyResponse {
plaintext: string;
}

export enum KmsSigningAlgorithm{
RSASSA_PSS_SHA_512 = "RSASSA_PSS_SHA_512",
RSASSA_PSS_SHA_384 = "RSASSA_PSS_SHA_384",
RSASSA_PSS_SHA_256 = "RSASSA_PSS_SHA_256",
RSASSA_PKCS1_V1_5_SHA_512 = "RSASSA_PKCS1_V1_5_SHA_512",
RSASSA_PKCS1_V1_5_SHA_384 = "RSASSA_PKCS1_V1_5_SHA_384",
RSASSA_PKCS1_V1_5_SHA_256 = "RSASSA_PKCS1_V1_5_SHA_256",
ECDSA_SHA_512 = "ECDSA_SHA_512",
ECDSA_SHA_384 = "ECDSA_SHA_384",
ECDSA_SHA_256 = "ECDSA_SHA_256",
}

export interface KmsSignDataOptions {
keyId: string;
signingAlgorithm: KmsSigningAlgorithm;
data: string;
isDigest?:boolean;
}

export interface KmsSignDataResponse {
signature: string;
keyId: string;
signingAlgorithm: KmsSigningAlgorithm;
}

export interface KmsVerifySignatureOptions {
keyId: string;
data: string;
signature: string;
signingAlgorithm: KmsSigningAlgorithm;
isDigest?: boolean;
}

export interface KmsVerifySignatureResponse {
signatureValid: boolean;
keyId: string;
signingAlgorithm: KmsSigningAlgorithm;
}

export interface KmsPublicKeyReponse {
publicKey: string;
}

export interface KmsSigningAlgorithmsResponse {
signingAlgorithms: KmsSigningAlgorithm[];
}
151 changes: 151 additions & 0 deletions src/custom/kms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { KmsApi } from "../api/endpoints/kms";
import { CreateKmsOptions, DecryptKmsKeyOptions, EncryptKmsKeyOptions, GetKmsKeyByNameOptions, KmsKeyEncryptionAlgorithm, KmsKeyUsage, KmsSignDataOptions, KmsVerifySignatureOptions, ListKmsOptions } from "../api/types";
import { newInfisicalError } from "./errors";

export default class KmsClient {
constructor(private apiClient: KmsApi) {}

listKeys = async (options: ListKmsOptions) => {
try {
const res = await this.apiClient.ListKeys({
projectId: options.projectId,
offset: options.offset ? options.offset : 0,
limit: options.limit ? options.limit : 100,
orderBy: options.orderBy,
orderDirection: options.orderDirection,
search: options.search,
})
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

getKeyById = async (keyId: string) => {
try {
const res = await this.apiClient.GetKeyById(keyId);
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

getKeyByName = async (options: GetKmsKeyByNameOptions) => {
try {
const res = await this.apiClient.GetKeyByName(options);
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

createKey = async (data: CreateKmsOptions) =>{
try {
const res = await this.apiClient.CreateKey({
projectId: data.projectId,
name: data.name,
description: data.description,
keyUsage: data.keyUsage ? data.keyUsage : KmsKeyUsage.EncryptDecrypt,
encryptionAlgorithm: data.encryptionAlgorithm ? data.encryptionAlgorithm : KmsKeyEncryptionAlgorithm.AES256,
});
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

updateKey = async (options: { keyId: string; name?: string; isDisabled?: boolean; description?: string }) => {
try {
const res = await this.apiClient.updateKey({
keyId: options.keyId,
name: options.name,
isDisabled: options.isDisabled,
description: options.description,
});
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

deleteKey = async (keyId: string) => {
try {
const res = await this.apiClient.deleteKey(keyId);
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

encryptData = async (options: EncryptKmsKeyOptions) => {
try {
const res = await this.apiClient.encryptData({
keyId: options.keyId,
plaintext: Buffer.from(options.plaintext).toString('base64'),
});
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

decryptData = async (options: DecryptKmsKeyOptions) => {
try {
const res = await this.apiClient.decryptData({
keyId: options.keyId,
ciphertext: options.ciphertext,
});
res.plaintext = Buffer.from(res.plaintext, 'base64').toString('utf-8');
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

signData = async (options: KmsSignDataOptions) => {
try {
const res = await this.apiClient.signData({
keyId: options.keyId,
signingAlgorithm: options.signingAlgorithm,
data: Buffer.from(options.data).toString('base64'),
isDigest: options.isDigest ? options.isDigest : false,
});
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

verifySignature = async (options: KmsVerifySignatureOptions ) => {
try {
const res = await this.apiClient.verifySignature({
keyId: options.keyId,
signature: Buffer.from(options.signature).toString('base64'),
signingAlgorithm: options.signingAlgorithm,
data: Buffer.from(options.data).toString('base64'),
isDigest: options.isDigest ? options.isDigest : false,
});
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

getPublicKey = async (keyId: string) => {
try {
const res = await this.apiClient.getPublicKey(keyId);
return res;
} catch (err) {
throw newInfisicalError(err);
}
}

listSigningAlgorithms = async (keyId: string) => {
try {
const res = await this.apiClient.listSigningAlgorithms(keyId);
return res;
} catch (err) {
throw newInfisicalError(err);
}
}
}
Loading