Add configure sshd flag to infisical ssh add-host command, update issue user cert permissioning

This commit is contained in:
Tuan Dang
2025-04-09 14:41:10 -07:00
parent 5a114586dc
commit 2382937385
5 changed files with 167 additions and 56 deletions
@@ -631,7 +631,6 @@ const buildAdminPermissionRules = () => {
ProjectPermissionSshHostActions.Edit,
ProjectPermissionSshHostActions.Create,
ProjectPermissionSshHostActions.Delete,
ProjectPermissionSshHostActions.IssueUserCert,
ProjectPermissionSshHostActions.IssueHostCert
],
ProjectPermissionSub.SshHosts
@@ -885,8 +884,6 @@ const buildMemberPermissionRules = () => {
can([ProjectPermissionActions.Create], ProjectPermissionSub.SshCertificates);
can([ProjectPermissionActions.Read], ProjectPermissionSub.SshCertificateTemplates);
can([ProjectPermissionSshHostActions.IssueUserCert], ProjectPermissionSub.SshHosts);
can(
[
ProjectPermissionCmekActions.Create,
@@ -92,11 +92,11 @@ export const sshHostServiceFactory = ({
userDAL
});
const allAllowedHosts = [];
const allowedHosts = [];
for await (const project of sshProjects) {
try {
const { permission } = await permissionService.getProjectPermission({
await permissionService.getProjectPermission({
actor,
actorId,
projectId: project.id,
@@ -107,20 +107,13 @@ export const sshHostServiceFactory = ({
const projectHosts = await sshHostDAL.findSshHostsWithPrincipalsAcrossProjects([project.id], principals);
const allowedHosts = projectHosts.filter((host) =>
permission.can(
ProjectPermissionSshHostActions.IssueUserCert,
subject(ProjectPermissionSub.SshHosts, { hostname: host.hostname })
)
);
allAllowedHosts.push(...allowedHosts);
allowedHosts.push(...projectHosts);
} catch {
// intentionally ignore projects where user lacks access
}
}
return allAllowedHosts;
return allowedHosts;
};
const createSshHost = async ({
@@ -370,7 +363,7 @@ export const sshHostServiceFactory = ({
});
}
const { permission } = await permissionService.getProjectPermission({
await permissionService.getProjectPermission({
actor,
actorId,
projectId: host.projectId,
@@ -379,13 +372,22 @@ export const sshHostServiceFactory = ({
actionProjectType: ActionProjectType.SSH
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionSshHostActions.IssueUserCert,
subject(ProjectPermissionSub.SshHosts, {
hostname: host.hostname
})
const internalPrincipals = await convertActorToPrincipals({
actor,
actorId,
userDAL
});
const mapping = host.loginMappings.find(
(m) => m.loginUser === loginUser && m.allowedPrincipals.some((allowed) => internalPrincipals.includes(allowed))
);
if (!mapping) {
throw new UnauthorizedError({
message: `You are not allowed to login as ${loginUser} on this host`
});
}
const keyId = `${actor}-${actorId}`;
const sshCaSecret = await sshCertificateAuthoritySecretDAL.findOne({ sshCaId: host.userSshCaId });
@@ -403,22 +405,6 @@ export const sshHostServiceFactory = ({
const keyAlgorithm = SshCertKeyAlgorithm.ED25519;
const { publicKey, privateKey } = await createSshKeyPair(keyAlgorithm);
const internalPrincipals = await convertActorToPrincipals({
actor,
actorId,
userDAL
});
const mapping = host.loginMappings.find(
(m) => m.loginUser === loginUser && m.allowedPrincipals.some((allowed) => internalPrincipals.includes(allowed))
);
if (!mapping) {
throw new UnauthorizedError({
message: `You are not allowed to login as ${loginUser} on this host`
});
}
// (dangtony98): include the loginUser as a principal on the issued certificate
const principals = [...internalPrincipals, loginUser];
@@ -519,7 +505,7 @@ export const sshHostServiceFactory = ({
});
const principals = [host.hostname];
const keyId = `host:${host.hostname}`;
const keyId = `host-${host.id}`;
const { serialNumber, signedPublicKey, ttl } = await createSshCert({
caPrivateKey: decryptedCaPrivateKey.toString("utf8"),