mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 15:41:27 +00:00
Add SSH certificate tab + data structure
This commit is contained in:
@@ -7,15 +7,6 @@ export enum OrgPermissionActions {
|
||||
Delete = "delete"
|
||||
}
|
||||
|
||||
export enum OrgPermissionSshCertificateTemplateActions {
|
||||
Read = "read",
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
SignSshKey = "sign-ssh-key",
|
||||
IssueSshCredentials = "issue-ssh-credentials"
|
||||
}
|
||||
|
||||
export enum OrgPermissionAdminConsoleAction {
|
||||
AccessAllProjects = "access-all-projects"
|
||||
}
|
||||
@@ -37,6 +28,7 @@ export enum OrgPermissionSubjects {
|
||||
AdminConsole = "organization-admin-console",
|
||||
AuditLogs = "audit-logs",
|
||||
ProjectTemplates = "project-templates",
|
||||
SshCertificates = "ssh-certificates",
|
||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||
SshCertificateTemplates = "ssh-certificate-templates"
|
||||
}
|
||||
@@ -59,7 +51,8 @@ export type OrgPermissionSet =
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.ProjectTemplates]
|
||||
| [OrgPermissionAdminConsoleAction, OrgPermissionSubjects.AdminConsole]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificateAuthorities]
|
||||
| [OrgPermissionSshCertificateTemplateActions, OrgPermissionSubjects.SshCertificateTemplates];
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificates]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificateTemplates];
|
||||
|
||||
const buildAdminPermission = () => {
|
||||
const { can, rules } = new AbilityBuilder<MongoAbility<OrgPermissionSet>>(createMongoAbility);
|
||||
@@ -136,22 +129,18 @@ const buildAdminPermission = () => {
|
||||
can(OrgPermissionActions.Edit, OrgPermissionSubjects.ProjectTemplates);
|
||||
can(OrgPermissionActions.Delete, OrgPermissionSubjects.ProjectTemplates);
|
||||
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificates);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificates);
|
||||
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificateAuthorities);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificateAuthorities);
|
||||
can(OrgPermissionActions.Edit, OrgPermissionSubjects.SshCertificateAuthorities);
|
||||
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SshCertificateAuthorities);
|
||||
|
||||
can(
|
||||
[
|
||||
OrgPermissionSshCertificateTemplateActions.Read,
|
||||
OrgPermissionSshCertificateTemplateActions.Create,
|
||||
OrgPermissionSshCertificateTemplateActions.Edit,
|
||||
OrgPermissionSshCertificateTemplateActions.Delete,
|
||||
OrgPermissionSshCertificateTemplateActions.SignSshKey,
|
||||
OrgPermissionSshCertificateTemplateActions.IssueSshCredentials
|
||||
],
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionActions.Edit, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
|
||||
can(OrgPermissionAdminConsoleAction.AccessAllProjects, OrgPermissionSubjects.AdminConsole);
|
||||
|
||||
@@ -184,9 +173,9 @@ const buildMemberPermission = () => {
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.AuditLogs);
|
||||
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificateAuthorities);
|
||||
can(OrgPermissionSshCertificateTemplateActions.Read, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionSshCertificateTemplateActions.SignSshKey, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionSshCertificateTemplateActions.IssueSshCredentials, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificates);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificates);
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.SshCertificateTemplates);
|
||||
|
||||
return rules;
|
||||
};
|
||||
|
||||
+5
-8
@@ -1,10 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import ms from "ms";
|
||||
|
||||
import {
|
||||
OrgPermissionSshCertificateTemplateActions,
|
||||
OrgPermissionSubjects
|
||||
} from "@app/ee/services/permission/org-permission";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
|
||||
@@ -61,7 +58,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.Create,
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
|
||||
@@ -124,7 +121,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.Edit,
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
|
||||
@@ -183,7 +180,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.Delete,
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
|
||||
@@ -209,7 +206,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.Read,
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify } from "@app/lib/knex";
|
||||
|
||||
export type TSshCertificateDALFactory = ReturnType<typeof sshCertificateDALFactory>;
|
||||
|
||||
export const sshCertificateDALFactory = (db: TDbClient) => {
|
||||
const sshCertificateOrm = ormify(db, TableName.SshCertificate);
|
||||
|
||||
const countSshCertificatesInOrg = async (orgId: string) => {
|
||||
try {
|
||||
interface CountResult {
|
||||
count: string;
|
||||
}
|
||||
|
||||
const query = db
|
||||
.replicaNode()(TableName.SshCertificate)
|
||||
.join(
|
||||
TableName.SshCertificateAuthority,
|
||||
`${TableName.SshCertificate}.sshCaId`,
|
||||
`${TableName.SshCertificateAuthority}.id`
|
||||
)
|
||||
.join(TableName.Organization, `${TableName.SshCertificateAuthority}.orgId`, `${TableName.Organization}.id`)
|
||||
.where(`${TableName.Organization}.id`, orgId);
|
||||
|
||||
const count = await query.count("*").first();
|
||||
|
||||
return parseInt((count as unknown as CountResult).count || "0", 10);
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Count all SSH certificates in organization" });
|
||||
}
|
||||
};
|
||||
return {
|
||||
...sshCertificateOrm,
|
||||
countSshCertificatesInOrg
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
import { SshCertificatesSchema } from "@app/db/schemas";
|
||||
|
||||
export const sanitizedSshCertificate = SshCertificatesSchema.pick({
|
||||
id: true,
|
||||
sshCaId: true,
|
||||
sshCertificateTemplateId: true,
|
||||
serialNumber: true,
|
||||
certType: true,
|
||||
publicKey: true,
|
||||
principals: true,
|
||||
keyId: true
|
||||
});
|
||||
@@ -1,15 +1,12 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSshCertificateTemplateActions,
|
||||
OrgPermissionSubjects
|
||||
} from "@app/ee/services/permission/org-permission";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal";
|
||||
import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal";
|
||||
import { TSshCertificateDALFactory } from "@app/ee/services/ssh-certificate/ssh-certificate-dal";
|
||||
import { TSshCertificateTemplateDALFactory } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-dal";
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
|
||||
import {
|
||||
@@ -38,6 +35,7 @@ type TSshCertificateAuthorityServiceFactoryDep = {
|
||||
>;
|
||||
sshCertificateAuthoritySecretDAL: Pick<TSshCertificateAuthoritySecretDALFactory, "create" | "findOne">;
|
||||
sshCertificateTemplateDAL: Pick<TSshCertificateTemplateDALFactory, "find" | "getByName">;
|
||||
sshCertificateDAL: Pick<TSshCertificateDALFactory, "create">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey" | "getOrgKmsKeyId">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||
};
|
||||
@@ -48,6 +46,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
sshCertificateAuthorityDAL,
|
||||
sshCertificateAuthoritySecretDAL,
|
||||
sshCertificateTemplateDAL,
|
||||
sshCertificateDAL,
|
||||
kmsService,
|
||||
permissionService
|
||||
}: TSshCertificateAuthorityServiceFactoryDep) => {
|
||||
@@ -252,10 +251,13 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
actorOrgId
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.IssueSshCredentials,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificates);
|
||||
|
||||
if (sshCertificateTemplate.caStatus === SshCaStatus.DISABLED) {
|
||||
throw new BadRequestError({
|
||||
message: "SSH CA is disabled"
|
||||
});
|
||||
}
|
||||
|
||||
// validate if the requested [certType] is allowed under the template configuration
|
||||
validateSshCertificateType(sshCertificateTemplate, certType);
|
||||
@@ -295,6 +297,18 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
certType
|
||||
});
|
||||
|
||||
await sshCertificateDAL.create({
|
||||
sshCaId: sshCertificateTemplate.sshCaId,
|
||||
sshCertificateTemplateId: sshCertificateTemplate.id,
|
||||
serialNumber,
|
||||
certType,
|
||||
publicKey,
|
||||
principals,
|
||||
keyId,
|
||||
notBefore: new Date(),
|
||||
notAfter: new Date(Date.now() + ttl * 1000)
|
||||
});
|
||||
|
||||
return {
|
||||
serialNumber,
|
||||
signedPublicKey,
|
||||
@@ -337,10 +351,13 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
actorOrgId
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.SignSshKey,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SshCertificates);
|
||||
|
||||
if (sshCertificateTemplate.caStatus === SshCaStatus.DISABLED) {
|
||||
throw new BadRequestError({
|
||||
message: "SSH CA is disabled"
|
||||
});
|
||||
}
|
||||
|
||||
// validate if the requested [certType] is allowed under the template configuration
|
||||
validateSshCertificateType(sshCertificateTemplate, certType);
|
||||
@@ -377,6 +394,18 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
certType
|
||||
});
|
||||
|
||||
await sshCertificateDAL.create({
|
||||
sshCaId: sshCertificateTemplate.sshCaId,
|
||||
sshCertificateTemplateId: sshCertificateTemplate.id,
|
||||
serialNumber,
|
||||
certType,
|
||||
publicKey,
|
||||
principals,
|
||||
keyId,
|
||||
notBefore: new Date(),
|
||||
notAfter: new Date(Date.now() + ttl * 1000)
|
||||
});
|
||||
|
||||
return { serialNumber, signedPublicKey, certificateTemplate: sshCertificateTemplate, ttl, keyId };
|
||||
};
|
||||
|
||||
@@ -399,7 +428,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionSshCertificateTemplateActions.Read,
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.SshCertificateTemplates
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user