From 6e0d33b5b954fa0b027dfd5851c2fc22d536e85c Mon Sep 17 00:00:00 2001 From: Andrew Stoltz <1578013+astoltz@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:56:41 -0500 Subject: [PATCH] deploy(tenant): add bluejay.dev edge controls --- .../ingressroute-andrew-web.json | 30 ++++++++++++++----- .../middleware-andrew-tenant-rate-limit.json | 15 ++++++++++ ...ddleware-andrew-tenant-secure-headers.json | 18 +++++++++++ .../tlsoption-andrew-tenant-tls13.json | 11 +++++++ .../FleetManifestLintTests.cs | 30 +++++++++++++++++-- 5 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-rate-limit.json create mode 100644 apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-secure-headers.json create mode 100644 apps-gx10/fc-tenant-andrew/tlsoption-andrew-tenant-tls13.json diff --git a/apps-gx10/fc-tenant-andrew/ingressroute-andrew-web.json b/apps-gx10/fc-tenant-andrew/ingressroute-andrew-web.json index a508e87..3f86a8f 100644 --- a/apps-gx10/fc-tenant-andrew/ingressroute-andrew-web.json +++ b/apps-gx10/fc-tenant-andrew/ingressroute-andrew-web.json @@ -11,8 +11,18 @@ ], "routes": [ { - "kind": "Rule", - "match": "Host(`bluejay.dev`) || Host(`www.bluejay.dev`)", + "kind": "Rule", + "match": "Host(`bluejay.dev`) || Host(`www.bluejay.dev`)", + "middlewares": [ + { + "name": "andrew-tenant-rate-limit", + "namespace": "fc-tenant-andrew" + }, + { + "name": "andrew-tenant-secure-headers", + "namespace": "fc-tenant-andrew" + } + ], "priority": 100, "services": [ { @@ -21,9 +31,13 @@ } ] } - ], - "tls": { - "secretName": "cf-origin-bluejay-dev" - } - } -} + ], + "tls": { + "options": { + "name": "andrew-tenant-tls13", + "namespace": "fc-tenant-andrew" + }, + "secretName": "cf-origin-bluejay-dev" + } + } +} diff --git a/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-rate-limit.json b/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-rate-limit.json new file mode 100644 index 0000000..5ed8fff --- /dev/null +++ b/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-rate-limit.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "andrew-tenant-rate-limit", + "namespace": "fc-tenant-andrew" + }, + "spec": { + "rateLimit": { + "average": 120, + "burst": 240, + "period": "1m" + } + } +} diff --git a/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-secure-headers.json b/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-secure-headers.json new file mode 100644 index 0000000..b0d2c41 --- /dev/null +++ b/apps-gx10/fc-tenant-andrew/middleware-andrew-tenant-secure-headers.json @@ -0,0 +1,18 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "andrew-tenant-secure-headers", + "namespace": "fc-tenant-andrew" + }, + "spec": { + "headers": { + "contentTypeNosniff": true, + "browserXssFilter": true, + "referrerPolicy": "strict-origin-when-cross-origin", + "stsSeconds": 31536000, + "stsIncludeSubdomains": true, + "stsPreload": false + } + } +} diff --git a/apps-gx10/fc-tenant-andrew/tlsoption-andrew-tenant-tls13.json b/apps-gx10/fc-tenant-andrew/tlsoption-andrew-tenant-tls13.json new file mode 100644 index 0000000..e0858f2 --- /dev/null +++ b/apps-gx10/fc-tenant-andrew/tlsoption-andrew-tenant-tls13.json @@ -0,0 +1,11 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "TLSOption", + "metadata": { + "name": "andrew-tenant-tls13", + "namespace": "fc-tenant-andrew" + }, + "spec": { + "minVersion": "VersionTLS13" + } +} diff --git a/tests/bluejay-infra-lint/FleetManifestLintTests.cs b/tests/bluejay-infra-lint/FleetManifestLintTests.cs index 0bbf73c..3bc5ca9 100644 --- a/tests/bluejay-infra-lint/FleetManifestLintTests.cs +++ b/tests/bluejay-infra-lint/FleetManifestLintTests.cs @@ -1110,9 +1110,10 @@ public sealed class FleetManifestLintTests servicePort.GetProperty("targetPort").GetInt32().Should().Be(8080); using var ingressRoute = JsonDocument.Parse(File.ReadAllText(Path.Combine(appRoot, "ingressroute-andrew-web.json"))); - var serviceRef = ingressRoute.RootElement + var route = ingressRoute.RootElement .GetProperty("spec") - .GetProperty("routes")[0] + .GetProperty("routes")[0]; + var serviceRef = route .GetProperty("services") .EnumerateArray() .Should() @@ -1120,6 +1121,31 @@ public sealed class FleetManifestLintTests .Subject; serviceRef.GetProperty("name").GetString().Should().Be("andrew-web-waf"); serviceRef.GetProperty("port").GetInt32().Should().Be(8080); + + route.GetProperty("middlewares") + .EnumerateArray() + .Select(item => item.GetProperty("name").GetString()) + .Should() + .Equal("andrew-tenant-rate-limit", "andrew-tenant-secure-headers"); + + using var rateLimit = JsonDocument.Parse(File.ReadAllText(Path.Combine(appRoot, "middleware-andrew-tenant-rate-limit.json"))); + rateLimit.RootElement.GetProperty("spec").GetProperty("rateLimit").GetProperty("average").GetInt32().Should().Be(120); + + using var headers = JsonDocument.Parse(File.ReadAllText(Path.Combine(appRoot, "middleware-andrew-tenant-secure-headers.json"))); + var headerSpec = headers.RootElement.GetProperty("spec").GetProperty("headers"); + headerSpec.GetProperty("contentTypeNosniff").GetBoolean().Should().BeTrue(); + headerSpec.GetProperty("stsSeconds").GetInt32().Should().Be(31536000); + + using var tlsOption = JsonDocument.Parse(File.ReadAllText(Path.Combine(appRoot, "tlsoption-andrew-tenant-tls13.json"))); + tlsOption.RootElement.GetProperty("spec").GetProperty("minVersion").GetString().Should().Be("VersionTLS13"); + ingressRoute.RootElement + .GetProperty("spec") + .GetProperty("tls") + .GetProperty("options") + .GetProperty("name") + .GetString() + .Should() + .Be("andrew-tenant-tls13"); } [Fact]