feat: kms support
This commit is contained in:
61
src/api/endpoints/kms.ts
Normal file
61
src/api/endpoints/kms.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { ApiClient } from "../base";
|
||||
import {
|
||||
CreateKmsKeyOptions,
|
||||
CreateKmsKeyResponse,
|
||||
DeleteKmsKeyOptions,
|
||||
DeleteKmsKeyResponse,
|
||||
GetKmsKeyByNameOptions,
|
||||
GetKmsKeyByNameResponse,
|
||||
KmsDecryptDataOptions,
|
||||
KmsDecryptDataResponse,
|
||||
KmsEncryptDataOptions,
|
||||
KmsEncryptDataResponse,
|
||||
KmsGetPublicKeyOptions,
|
||||
KmsGetPublicKeyResponse,
|
||||
KmsListSigningAlgorithmsOptions,
|
||||
KmsListSigningAlgorithmsResponse,
|
||||
KmsSignDataOptions,
|
||||
KmsSignDataResponse,
|
||||
KmsVerifyDataOptions,
|
||||
KmsVerifyDataResponse
|
||||
} from "../types/kms";
|
||||
|
||||
export class KmsApi {
|
||||
constructor(private apiClient: ApiClient) {}
|
||||
|
||||
async createKmsKey(data: CreateKmsKeyOptions): Promise<CreateKmsKeyResponse> {
|
||||
return this.apiClient.post<CreateKmsKeyResponse>("/api/v1/kms/keys", data);
|
||||
}
|
||||
|
||||
async deleteKmsKey(data: DeleteKmsKeyOptions): Promise<DeleteKmsKeyResponse> {
|
||||
return this.apiClient.delete<DeleteKmsKeyResponse>(`/api/v1/kms/keys/${data.keyId}`);
|
||||
}
|
||||
|
||||
async getKmsKeyByName(data: GetKmsKeyByNameOptions): Promise<GetKmsKeyByNameResponse> {
|
||||
return this.apiClient.get<GetKmsKeyByNameResponse>(`/api/v1/kms/keys/key-name/${encodeURIComponent(data.name)}?projectId=${data.projectId}`);
|
||||
}
|
||||
|
||||
async encryptData(data: KmsEncryptDataOptions): Promise<KmsEncryptDataResponse> {
|
||||
return this.apiClient.post<KmsEncryptDataResponse>(`/api/v1/kms/keys/${data.keyId}/encrypt`, data);
|
||||
}
|
||||
|
||||
async decryptData(data: KmsDecryptDataOptions): Promise<KmsDecryptDataResponse> {
|
||||
return this.apiClient.post<KmsDecryptDataResponse>(`/api/v1/kms/keys/${data.keyId}/decrypt`, data);
|
||||
}
|
||||
|
||||
async signData(data: KmsSignDataOptions): Promise<KmsSignDataResponse> {
|
||||
return this.apiClient.post<KmsSignDataResponse>(`/api/v1/kms/keys/${data.keyId}/sign`, data);
|
||||
}
|
||||
|
||||
async verifyData(data: KmsVerifyDataOptions): Promise<KmsVerifyDataResponse> {
|
||||
return this.apiClient.post<KmsVerifyDataResponse>(`/api/v1/kms/keys/${data.keyId}/verify`, data);
|
||||
}
|
||||
|
||||
async listSigningAlgorithms(data: KmsListSigningAlgorithmsOptions): Promise<KmsListSigningAlgorithmsResponse> {
|
||||
return this.apiClient.get<KmsListSigningAlgorithmsResponse>(`/api/v1/kms/keys/${data.keyId}/signing-algorithms`);
|
||||
}
|
||||
|
||||
async getSigningPublicKey(data: KmsGetPublicKeyOptions): Promise<KmsGetPublicKeyResponse> {
|
||||
return this.apiClient.get<KmsGetPublicKeyResponse>(`/api/v1/kms/keys/${data.keyId}/public-key`);
|
||||
}
|
||||
}
|
||||
135
src/api/types/kms.ts
Normal file
135
src/api/types/kms.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
export enum EncryptionAlgorithm {
|
||||
RSA_4096 = "RSA_4096",
|
||||
ECC_NIST_P256 = "ECC_NIST_P256",
|
||||
AES_256_GCM = "aes-256-gcm",
|
||||
AES_128_GCM = "aes-128-gcm"
|
||||
}
|
||||
|
||||
export enum SigningAlgorithm {
|
||||
// RSA PSS algorithms
|
||||
// These are NOT deterministic and include randomness.
|
||||
// This means that the output signature is different each time for the same input.
|
||||
RSASSA_PSS_SHA_512 = "RSASSA_PSS_SHA_512",
|
||||
RSASSA_PSS_SHA_384 = "RSASSA_PSS_SHA_384",
|
||||
RSASSA_PSS_SHA_256 = "RSASSA_PSS_SHA_256",
|
||||
|
||||
// RSA PKCS#1 v1.5 algorithms
|
||||
// These are deterministic and the output is the same each time for the same input.
|
||||
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 algorithms
|
||||
// None of these are deterministic and include randomness like RSA PSS.
|
||||
ECDSA_SHA_512 = "ECDSA_SHA_512",
|
||||
ECDSA_SHA_384 = "ECDSA_SHA_384",
|
||||
ECDSA_SHA_256 = "ECDSA_SHA_256"
|
||||
}
|
||||
|
||||
export enum KeyUsage {
|
||||
ENCRYPTION = "encrypt-decrypt",
|
||||
SIGNING = "sign-verify"
|
||||
}
|
||||
|
||||
export interface KmsKey {
|
||||
id: string;
|
||||
description: string;
|
||||
isDisabled: boolean;
|
||||
orgId: string;
|
||||
name: string;
|
||||
projectId: string;
|
||||
keyUsage: KeyUsage;
|
||||
version: number;
|
||||
encryptionAlgorithm: EncryptionAlgorithm;
|
||||
}
|
||||
|
||||
export interface CreateKmsKeyOptions {
|
||||
projectId: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
|
||||
keyUsage: KeyUsage;
|
||||
encryptionAlgorithm: EncryptionAlgorithm;
|
||||
}
|
||||
|
||||
export interface CreateKmsKeyResponse {
|
||||
key: KmsKey;
|
||||
}
|
||||
|
||||
export interface DeleteKmsKeyOptions {
|
||||
keyId: string;
|
||||
}
|
||||
|
||||
export interface DeleteKmsKeyResponse {
|
||||
key: KmsKey;
|
||||
}
|
||||
|
||||
export interface GetKmsKeyByNameOptions {
|
||||
projectId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface GetKmsKeyByNameResponse {
|
||||
key: KmsKey;
|
||||
}
|
||||
|
||||
export interface KmsEncryptDataOptions {
|
||||
keyId: string;
|
||||
plaintext: string;
|
||||
}
|
||||
|
||||
export interface KmsEncryptDataResponse {
|
||||
ciphertext: string;
|
||||
}
|
||||
|
||||
export interface KmsDecryptDataOptions {
|
||||
keyId: string;
|
||||
ciphertext: string;
|
||||
}
|
||||
|
||||
export interface KmsDecryptDataResponse {
|
||||
plaintext: string;
|
||||
}
|
||||
|
||||
export interface KmsSignDataOptions {
|
||||
keyId: string;
|
||||
data: string;
|
||||
signingAlgorithm: SigningAlgorithm;
|
||||
isDigest?: boolean;
|
||||
}
|
||||
|
||||
export interface KmsSignDataResponse {
|
||||
signature: string;
|
||||
keyId: string;
|
||||
signingAlgorithm: SigningAlgorithm;
|
||||
}
|
||||
|
||||
export interface KmsVerifyDataOptions {
|
||||
keyId: string;
|
||||
data: string; // must be base64 encoded
|
||||
signature: string;
|
||||
signingAlgorithm: SigningAlgorithm;
|
||||
isDigest?: boolean;
|
||||
}
|
||||
|
||||
export interface KmsVerifyDataResponse {
|
||||
signatureValid: boolean;
|
||||
keyId: string;
|
||||
signingAlgorithm: SigningAlgorithm;
|
||||
}
|
||||
|
||||
export interface KmsListSigningAlgorithmsOptions {
|
||||
keyId: string;
|
||||
}
|
||||
|
||||
export interface KmsListSigningAlgorithmsResponse {
|
||||
signingAlgorithms: SigningAlgorithm[];
|
||||
}
|
||||
|
||||
export interface KmsGetPublicKeyOptions {
|
||||
keyId: string;
|
||||
}
|
||||
|
||||
export interface KmsGetPublicKeyResponse {
|
||||
publicKey: string;
|
||||
}
|
||||
124
src/custom/kms.ts
Normal file
124
src/custom/kms.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { newInfisicalError } from "./errors";
|
||||
import {
|
||||
CreateKmsKeyOptions,
|
||||
DeleteKmsKeyOptions,
|
||||
GetKmsKeyByNameOptions,
|
||||
KmsDecryptDataOptions,
|
||||
KmsEncryptDataOptions,
|
||||
KmsGetPublicKeyOptions,
|
||||
KmsListSigningAlgorithmsOptions,
|
||||
KmsSignDataOptions,
|
||||
KmsVerifyDataOptions
|
||||
} from "../api/types/kms";
|
||||
import { KmsApi } from "../api/endpoints/kms";
|
||||
|
||||
export default class KmsClient {
|
||||
constructor(private apiClient: KmsApi) {}
|
||||
|
||||
keys = () => {
|
||||
const create = async (options: CreateKmsKeyOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.createKmsKey(options);
|
||||
return res.key;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteKmsKey = async (options: DeleteKmsKeyOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.deleteKmsKey(options);
|
||||
return res.key;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const getByName = async (options: GetKmsKeyByNameOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.getKmsKeyByName(options);
|
||||
|
||||
console.log(res);
|
||||
return res.key;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
create,
|
||||
delete: deleteKmsKey,
|
||||
getByName
|
||||
};
|
||||
};
|
||||
|
||||
encryption = () => {
|
||||
const encrypt = async (options: KmsEncryptDataOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.encryptData(options);
|
||||
return res.ciphertext;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const decrypt = async (options: KmsDecryptDataOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.decryptData(options);
|
||||
return res.plaintext;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
encrypt,
|
||||
decrypt
|
||||
};
|
||||
};
|
||||
|
||||
signing = () => {
|
||||
const sign = async (options: KmsSignDataOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.signData(options);
|
||||
return res;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const verify = async (options: KmsVerifyDataOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.verifyData(options);
|
||||
return res;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const listSigningAlgorithms = async (options: KmsListSigningAlgorithmsOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.listSigningAlgorithms(options);
|
||||
return res.signingAlgorithms;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const getPublicKey = async (options: KmsGetPublicKeyOptions) => {
|
||||
try {
|
||||
const res = await this.apiClient.getSigningPublicKey(options);
|
||||
return res.publicKey;
|
||||
} catch (err) {
|
||||
throw newInfisicalError(err);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
sign,
|
||||
verify,
|
||||
listSigningAlgorithms,
|
||||
getPublicKey
|
||||
};
|
||||
};
|
||||
}
|
||||
122
src/index.ts
122
src/index.ts
@@ -12,89 +12,83 @@ import DynamicSecretsClient from "./custom/dynamic-secrets";
|
||||
import EnvironmentsClient from "./custom/environments";
|
||||
import ProjectsClient from "./custom/projects";
|
||||
import FoldersClient from "./custom/folders";
|
||||
import { KmsApi } from "./api/endpoints/kms";
|
||||
import KmsClient from "./custom/kms";
|
||||
|
||||
type InfisicalSDKOptions = {
|
||||
siteUrl?: string;
|
||||
siteUrl?: string;
|
||||
};
|
||||
|
||||
class InfisicalSDK {
|
||||
private apiClient: ApiClient;
|
||||
private apiClient: ApiClient;
|
||||
|
||||
// API instances
|
||||
private authApi: AuthApi;
|
||||
private secretsApi: SecretsApi;
|
||||
private dynamicSecretsApi: DynamicSecretsApi;
|
||||
private environmentsApi: EnvironmentsApi;
|
||||
private projectsApi: ProjectsApi;
|
||||
private foldersApi: FoldersApi;
|
||||
// API instances
|
||||
private authApi: AuthApi;
|
||||
private secretsApi: SecretsApi;
|
||||
private dynamicSecretsApi: DynamicSecretsApi;
|
||||
private environmentsApi: EnvironmentsApi;
|
||||
private projectsApi: ProjectsApi;
|
||||
private foldersApi: FoldersApi;
|
||||
private kmsApi: KmsApi;
|
||||
|
||||
// Domain clients
|
||||
private authClient: AuthClient;
|
||||
private secretsClient: SecretsClient;
|
||||
private dynamicSecretsClient: DynamicSecretsClient;
|
||||
private environmentsClient: EnvironmentsClient;
|
||||
private projectsClient: ProjectsClient;
|
||||
private foldersClient: FoldersClient;
|
||||
// Domain clients
|
||||
private authClient: AuthClient;
|
||||
private secretsClient: SecretsClient;
|
||||
private dynamicSecretsClient: DynamicSecretsClient;
|
||||
private environmentsClient: EnvironmentsClient;
|
||||
private projectsClient: ProjectsClient;
|
||||
private foldersClient: FoldersClient;
|
||||
private kmsClient: KmsClient;
|
||||
|
||||
constructor(options?: InfisicalSDKOptions) {
|
||||
const baseURL = options?.siteUrl || "https://app.infisical.com";
|
||||
constructor(options?: InfisicalSDKOptions) {
|
||||
const baseURL = options?.siteUrl || "https://app.infisical.com";
|
||||
|
||||
// Initialize the base API client
|
||||
this.apiClient = new ApiClient({ baseURL });
|
||||
// Initialize the base API client
|
||||
this.apiClient = new ApiClient({ baseURL });
|
||||
|
||||
// Initialize API service instances
|
||||
this.authApi = new AuthApi(this.apiClient);
|
||||
this.secretsApi = new SecretsApi(this.apiClient);
|
||||
this.dynamicSecretsApi = new DynamicSecretsApi(this.apiClient);
|
||||
this.environmentsApi = new EnvironmentsApi(this.apiClient);
|
||||
this.projectsApi = new ProjectsApi(this.apiClient);
|
||||
this.foldersApi = new FoldersApi(this.apiClient);
|
||||
// Initialize API service instances
|
||||
this.authApi = new AuthApi(this.apiClient);
|
||||
this.secretsApi = new SecretsApi(this.apiClient);
|
||||
this.dynamicSecretsApi = new DynamicSecretsApi(this.apiClient);
|
||||
this.environmentsApi = new EnvironmentsApi(this.apiClient);
|
||||
this.projectsApi = new ProjectsApi(this.apiClient);
|
||||
this.foldersApi = new FoldersApi(this.apiClient);
|
||||
this.kmsApi = new KmsApi(this.apiClient);
|
||||
|
||||
// Initialize domain clients
|
||||
this.authClient = new AuthClient(
|
||||
this.authenticate.bind(this),
|
||||
this.authApi
|
||||
);
|
||||
this.secretsClient = new SecretsClient(this.secretsApi);
|
||||
this.dynamicSecretsClient = new DynamicSecretsClient(
|
||||
this.dynamicSecretsApi
|
||||
);
|
||||
this.environmentsClient = new EnvironmentsClient(this.environmentsApi);
|
||||
this.projectsClient = new ProjectsClient(this.projectsApi);
|
||||
this.foldersClient = new FoldersClient(this.foldersApi);
|
||||
}
|
||||
// Initialize domain clients
|
||||
this.authClient = new AuthClient(this.authenticate.bind(this), this.authApi);
|
||||
this.secretsClient = new SecretsClient(this.secretsApi);
|
||||
this.dynamicSecretsClient = new DynamicSecretsClient(this.dynamicSecretsApi);
|
||||
this.environmentsClient = new EnvironmentsClient(this.environmentsApi);
|
||||
this.projectsClient = new ProjectsClient(this.projectsApi);
|
||||
this.foldersClient = new FoldersClient(this.foldersApi);
|
||||
this.kmsClient = new KmsClient(this.kmsApi);
|
||||
}
|
||||
|
||||
private authenticate(accessToken: string) {
|
||||
// Set the token on the API client
|
||||
this.apiClient.setAccessToken(accessToken);
|
||||
private authenticate(accessToken: string) {
|
||||
// Set the token on the API client
|
||||
this.apiClient.setAccessToken(accessToken);
|
||||
|
||||
// Reinitialize the auth client with the token
|
||||
this.authClient = new AuthClient(
|
||||
this.authenticate.bind(this),
|
||||
this.authApi,
|
||||
accessToken
|
||||
);
|
||||
// Reinitialize the auth client with the token
|
||||
this.authClient = new AuthClient(this.authenticate.bind(this), this.authApi, accessToken);
|
||||
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Public methods to access domain clients
|
||||
secrets = () => this.secretsClient;
|
||||
environments = () => this.environmentsClient;
|
||||
projects = () => this.projectsClient;
|
||||
folders = () => this.foldersClient;
|
||||
dynamicSecrets = () => this.dynamicSecretsClient;
|
||||
auth = () => this.authClient;
|
||||
// Public methods to access domain clients
|
||||
secrets = () => this.secretsClient;
|
||||
environments = () => this.environmentsClient;
|
||||
projects = () => this.projectsClient;
|
||||
folders = () => this.foldersClient;
|
||||
dynamicSecrets = () => this.dynamicSecretsClient;
|
||||
auth = () => this.authClient;
|
||||
kms = () => this.kmsClient;
|
||||
}
|
||||
|
||||
// Export main SDK class
|
||||
export { InfisicalSDK };
|
||||
|
||||
export * from './api/types'
|
||||
export * from "./api/types";
|
||||
|
||||
// Export types and enums from schemas
|
||||
export {
|
||||
TDynamicSecretProvider,
|
||||
DynamicSecretProviders,
|
||||
SqlProviders,
|
||||
} from "./custom/schemas";
|
||||
export { TDynamicSecretProvider, DynamicSecretProviders, SqlProviders } from "./custom/schemas";
|
||||
|
||||
Reference in New Issue
Block a user