Move mtls routes to private

This commit is contained in:
Owen
2026-10-16 12:16:51 -04:00
parent 7a2808daa2
commit 2817af1816
11 changed files with 110 additions and 89 deletions
+1 -1
View File
@@ -72,5 +72,5 @@ export const tierMatrix: Record<TierFeature, Tier[]> = {
[TierFeature.NewtAutoUpdate]: ["tier1", "tier2", "tier3", "enterprise"],
[TierFeature.ResourcePolicies]: ["tier3", "enterprise"],
[TierFeature.RoleBasedSSHControls]: ["tier3", "enterprise"],
[TierFeature.Mtls]: ["tier1", "tier2", "tier3", "enterprise"]
[TierFeature.Mtls]: ["tier3", "enterprise"]
};
+25 -1
View File
@@ -35,6 +35,7 @@ import * as eventStreamingDestination from "#private/routers/eventStreamingDesti
import * as alertRule from "#private/routers/alertRule";
import * as healthChecks from "#private/routers/healthChecks";
import * as policy from "#private/routers/policy";
import * as resource from "#private/routers/resource";
import {
verifyOrgAccess,
@@ -49,7 +50,8 @@ import {
verifySiteProvisioningKeyAccess,
verifyIsLoggedInUser,
verifyAdmin,
verifyResourcePolicyAccess
verifyResourcePolicyAccess,
verifyResourceAccess
} from "@server/middlewares";
import { ActionsEnum } from "@server/auth/actions";
import {
@@ -893,3 +895,25 @@ authenticated.post(
verifyOrgAccess,
logs.logAccessAuditAttempt
);
authenticated.put(
"/resource/:resourceId/mtls/certificate",
verifyResourceAccess,
verifyLimits,
verifyUserHasAction(ActionsEnum.createResourceMtlsCertificate),
logActionAudit(ActionsEnum.createResourceMtlsCertificate),
resource.createResourceMtlsCertificate
);
authenticated.get(
"/resource/:resourceId/mtls/certificates",
verifyResourceAccess,
verifyUserHasAction(ActionsEnum.listResourceMtlsCertificates),
resource.listResourceMtlsCertificates
);
authenticated.delete(
"/resource/:resourceId/mtls/certificate/:mtlsCertificateId",
verifyResourceAccess,
verifyUserHasAction(ActionsEnum.deleteResourceMtlsCertificate),
logActionAudit(ActionsEnum.deleteResourceMtlsCertificate),
resource.deleteResourceMtlsCertificate
);
+36 -2
View File
@@ -21,7 +21,7 @@ import * as policy from "#private/routers/policy";
import * as eventStreamingDestination from "#private/routers/eventStreamingDestination";
import * as alertRule from "#private/routers/alertRule";
import * as healthChecks from "#private/routers/healthChecks";
import * as resource from "#private/routers/resource";
import {
verifyApiKeyHasAction,
verifyApiKeyIsRoot,
@@ -32,7 +32,8 @@ import {
verifyApiKeyClientAccess,
verifyApiKeySiteProvisioningKeyAccess,
verifyApiKeyResourcePolicyAccess,
verifyLimits
verifyLimits,
verifyApiKeyResourceAccess
} from "@server/middlewares";
import * as user from "#private/routers/user";
import * as client from "#private/routers/client";
@@ -466,3 +467,36 @@ authenticated.get(
verifyApiKeyHasAction(ActionsEnum.getTarget),
healthChecks.getHealthCheckStatusHistory
);
authenticated.put(
[
"/resource/:resourceId/mtls/certificate",
"/public-resource/:resourceId/mtls/certificate"
],
verifyApiKeyResourceAccess,
verifyLimits,
verifyApiKeyHasAction(ActionsEnum.createResourceMtlsCertificate),
logActionAudit(ActionsEnum.createResourceMtlsCertificate),
resource.createResourceMtlsCertificate
);
authenticated.get(
[
"/resource/:resourceId/mtls/certificates",
"/public-resource/:resourceId/mtls/certificates"
],
verifyApiKeyResourceAccess,
verifyApiKeyHasAction(ActionsEnum.listResourceMtlsCertificates),
resource.listResourceMtlsCertificates
);
authenticated.delete(
[
"/resource/:resourceId/mtls/certificate/:mtlsCertificateId",
"/public-resource/:resourceId/mtls/certificate/:mtlsCertificateId"
],
verifyApiKeyResourceAccess,
verifyApiKeyHasAction(ActionsEnum.deleteResourceMtlsCertificate),
logActionAudit(ActionsEnum.deleteResourceMtlsCertificate),
resource.deleteResourceMtlsCertificate
);
@@ -14,6 +14,7 @@ import {
MAX_MTLS_CERTIFICATES_PER_RESOURCE,
parseCaCertificates
} from "@server/lib/mtlsCertificate";
import { CreateResourceMtlsCertificateResponse } from "@server/routers/resource/types";
const createResourceMtlsCertificateParamsSchema = z.strictObject({
resourceId: z.coerce.number().int().positive()
@@ -24,21 +25,6 @@ const createResourceMtlsCertificateBodySchema = z.strictObject({
certificate: z.string().min(1).max(100_000)
});
export type CreateResourceMtlsCertificateResponse = {
certificates: {
mtlsCertificateId: number;
resourceId: number;
name: string | null;
subject: string | null;
issuer: string | null;
serialNumber: string | null;
fingerprint: string | null;
notBefore: number | null;
notAfter: number | null;
createdAt: number;
}[];
};
const description =
"Add a trusted CA certificate that clients must present a certificate signed by when mTLS is enabled on a resource. Accepts a PEM bundle; each certificate in the bundle is stored separately.";
@@ -164,7 +150,9 @@ export async function createResourceMtlsCertificate(
.from(resourceMtlsCertificates)
.where(eq(resourceMtlsCertificates.resourceId, resourceId));
const existingFingerprints = new Set(existing.map((c) => c.fingerprint));
const existingFingerprints = new Set(
existing.map((c) => c.fingerprint)
);
const newCerts = parsedCerts.filter(
(c) => !existingFingerprints.has(c.fingerprint)
);
@@ -8,6 +8,7 @@ import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { DeleteResourceMtlsCertificateResponse } from "@server/routers/resource/types";
const deleteResourceMtlsCertificateParamsSchema = z.strictObject({
resourceId: z.coerce.number().int().positive(),
@@ -39,11 +40,6 @@ registry.registerPath({
responses: {}
});
export type DeleteResourceMtlsCertificateResponse = {
// true when removing the last CA certificate forced mTLS off
mtlsDisabled: boolean;
};
export async function deleteResourceMtlsCertificate(
req: Request,
res: Response,
+3
View File
@@ -12,3 +12,6 @@
*/
export * from "./getMaintenanceInfo";
export * from "./deleteResourceMtlsCertificate";
export * from "./createResourceMtlsCertificate";
export * from "./listResourceMtlsCertificates";
@@ -8,6 +8,7 @@ import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { ListResourceMtlsCertificatesResponse } from "@server/routers/resource/types";
const listResourceMtlsCertificatesParamsSchema = z.strictObject({
resourceId: z.coerce.number().int().positive()
@@ -32,10 +33,6 @@ function queryResourceMtlsCertificates(resourceId: number) {
.orderBy(asc(resourceMtlsCertificates.mtlsCertificateId));
}
export type ListResourceMtlsCertificatesResponse = {
certificates: Awaited<ReturnType<typeof queryResourceMtlsCertificates>>;
};
const description = "List the trusted CA certificates for a resource's mTLS.";
registry.registerPath({
@@ -66,8 +63,9 @@ export async function listResourceMtlsCertificates(
next: NextFunction
): Promise<any> {
try {
const parsedParams =
listResourceMtlsCertificatesParamsSchema.safeParse(req.params);
const parsedParams = listResourceMtlsCertificatesParamsSchema.safeParse(
req.params
);
if (!parsedParams.success) {
return next(
createHttpError(
-22
View File
@@ -849,28 +849,6 @@ authenticated.delete(
resource.deleteResourceRule
);
authenticated.put(
"/resource/:resourceId/mtls/certificate",
verifyResourceAccess,
verifyLimits,
verifyUserHasAction(ActionsEnum.createResourceMtlsCertificate),
logActionAudit(ActionsEnum.createResourceMtlsCertificate),
resource.createResourceMtlsCertificate
);
authenticated.get(
"/resource/:resourceId/mtls/certificates",
verifyResourceAccess,
verifyUserHasAction(ActionsEnum.listResourceMtlsCertificates),
resource.listResourceMtlsCertificates
);
authenticated.delete(
"/resource/:resourceId/mtls/certificate/:mtlsCertificateId",
verifyResourceAccess,
verifyUserHasAction(ActionsEnum.deleteResourceMtlsCertificate),
logActionAudit(ActionsEnum.deleteResourceMtlsCertificate),
resource.deleteResourceMtlsCertificate
);
authenticated.get(
"/target/:targetId",
verifyTargetAccess,
-33
View File
@@ -740,39 +740,6 @@ authenticated.delete(
resource.deleteResourceRule
);
authenticated.put(
[
"/resource/:resourceId/mtls/certificate",
"/public-resource/:resourceId/mtls/certificate"
],
verifyApiKeyResourceAccess,
verifyLimits,
verifyApiKeyHasAction(ActionsEnum.createResourceMtlsCertificate),
logActionAudit(ActionsEnum.createResourceMtlsCertificate),
resource.createResourceMtlsCertificate
);
authenticated.get(
[
"/resource/:resourceId/mtls/certificates",
"/public-resource/:resourceId/mtls/certificates"
],
verifyApiKeyResourceAccess,
verifyApiKeyHasAction(ActionsEnum.listResourceMtlsCertificates),
resource.listResourceMtlsCertificates
);
authenticated.delete(
[
"/resource/:resourceId/mtls/certificate/:mtlsCertificateId",
"/public-resource/:resourceId/mtls/certificate/:mtlsCertificateId"
],
verifyApiKeyResourceAccess,
verifyApiKeyHasAction(ActionsEnum.deleteResourceMtlsCertificate),
logActionAudit(ActionsEnum.deleteResourceMtlsCertificate),
resource.deleteResourceMtlsCertificate
);
authenticated.get(
"/target/:targetId",
verifyApiKeyTargetAccess,
+1 -3
View File
@@ -21,9 +21,6 @@ export * from "./createResourceRule";
export * from "./deleteResourceRule";
export * from "./listResourceRules";
export * from "./updateResourceRule";
export * from "./createResourceMtlsCertificate";
export * from "./deleteResourceMtlsCertificate";
export * from "./listResourceMtlsCertificates";
export * from "./getUserResources";
export * from "./listUserResourceAliases";
export * from "./setResourceHeaderAuth";
@@ -47,3 +44,4 @@ export * from "./setResourceAiProviders";
export * from "./addAiProviderToResource";
export * from "./removeAiProviderFromResource";
export * from "./exportResourceBlueprint";
export * from "./types";
+35
View File
@@ -27,3 +27,38 @@ export type ResourcePolicyWithResources = Pick<
export type ListResourcePoliciesResponse = PaginatedResponse<{
policies: Array<ResourcePolicyWithResources>;
}>;
export type DeleteResourceMtlsCertificateResponse = {
// true when removing the last CA certificate forced mTLS off
mtlsDisabled: boolean;
};
export type CreateResourceMtlsCertificateResponse = {
certificates: {
mtlsCertificateId: number;
resourceId: number;
name: string | null;
subject: string | null;
issuer: string | null;
serialNumber: string | null;
fingerprint: string | null;
notBefore: number | null;
notAfter: number | null;
createdAt: number;
}[];
};
export type ListResourceMtlsCertificatesResponse = {
certificates: {
mtlsCertificateId: number;
resourceId: number;
name: string | null;
subject: string | null;
issuer: string | null;
serialNumber: string | null;
fingerprint: string | null;
notBefore: number | null;
notAfter: number | null;
createdAt: number;
}[];
};