From 5ce4f0d1e77bf698ac14adc5188aa268e84e1b4d Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 19 Jun 2026 06:45:09 -0500 Subject: [PATCH] deploy(gx10): add DeviceManagement enrollment CA runtime --- apps-gx10/fc-devicemgmt/README.md | 10 ++++++--- .../deployment-fc-devicemgmt-web.json | 22 ++++++++++++++++++- .../FleetManifestLintTests.cs | 6 +++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps-gx10/fc-devicemgmt/README.md b/apps-gx10/fc-devicemgmt/README.md index f4c0fc5..24aeb59 100644 --- a/apps-gx10/fc-devicemgmt/README.md +++ b/apps-gx10/fc-devicemgmt/README.md @@ -21,6 +21,8 @@ values to clear readiness checks. | `DEVICE_MANAGEMENT_OPERATOR_API_KEY` | Required operator API key for authenticated REST/MCP write operations, including Android command queueing. | | `DEVICE_MANAGEMENT_ADMIN_API_KEY` | Required admin API key for privileged DeviceManagement operations. | | `DEVICE_MANAGEMENT_AGENT_API_KEY` | Required scoped agent credential for REST agent callbacks when TLS terminates before Kestrel; maps to `Auth:AgentApiKey` and `FlowerCore:Auth:AgentApiKey`. | +| `DEVICE_MANAGEMENT_ENROLLMENT_CA_CERTIFICATE_PEM` | Optional persistent enrollment CA certificate PEM; maps to `FlowerCore:DeviceManagement:EnrollmentCertificateAuthorityCertificatePem`. Required before ingress can verify agent client-cert chains. | +| `DEVICE_MANAGEMENT_ENROLLMENT_CA_PRIVATE_KEY_PEM` | Optional private key PEM matching the persistent enrollment CA certificate; maps to `FlowerCore:DeviceManagement:EnrollmentCertificateAuthorityPrivateKeyPem`. | | `NANOHUB_API_KEY` | NanoHUB API password for HTTP Basic user `nanohub`. | | `APPLE_MDM_APNS_TOPIC` | MDM APNs topic returned after uploading the Apple MDM push certificate to NanoHUB/NanoMDM. | | `APPLE_MDM_SCEP_URL` | Live SCEP URL included in the enrollment profile. | @@ -49,9 +51,11 @@ validates Traefik-forwarded client certificates only on The agent-only Traefik route currently uses `RequireAnyClientCert`; the application remains the authorization boundary by matching the forwarded client -certificate thumbprint to the enrolled device record. Once DeviceManagement -exports a persistent enrollment CA bundle, switch this TLSOption to -`RequireAndVerifyClientCert` with that CA secret. +certificate thumbprint to the enrolled device record. Once +`DEVICE_MANAGEMENT_ENROLLMENT_CA_CERTIFICATE_PEM` and +`DEVICE_MANAGEMENT_ENROLLMENT_CA_PRIVATE_KEY_PEM` are present and newly enrolled +agents prove they chain to that CA, create the matching Traefik CA secret and +switch this TLSOption to `RequireAndVerifyClientCert`. ## Readiness Check diff --git a/apps-gx10/fc-devicemgmt/deployment-fc-devicemgmt-web.json b/apps-gx10/fc-devicemgmt/deployment-fc-devicemgmt-web.json index 7f64bf6..f870ba6 100644 --- a/apps-gx10/fc-devicemgmt/deployment-fc-devicemgmt-web.json +++ b/apps-gx10/fc-devicemgmt/deployment-fc-devicemgmt-web.json @@ -155,6 +155,26 @@ } } }, + { + "name": "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityCertificatePem", + "valueFrom": { + "secretKeyRef": { + "key": "DEVICE_MANAGEMENT_ENROLLMENT_CA_CERTIFICATE_PEM", + "name": "fc-devicemgmt-runtime", + "optional": true + } + } + }, + { + "name": "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityPrivateKeyPem", + "valueFrom": { + "secretKeyRef": { + "key": "DEVICE_MANAGEMENT_ENROLLMENT_CA_PRIVATE_KEY_PEM", + "name": "fc-devicemgmt-runtime", + "optional": true + } + } + }, { "name": "FlowerCore__DeviceManagement__AgentMtls__ForwardedCertificateHosts__0", "value": "devices-agent.iamworkin.lan" @@ -321,7 +341,7 @@ "value": "true" } ], - "image": "localhost/fc-devicemgmt-web:v20260619-mtlsder-5131f32", + "image": "localhost/fc-devicemgmt-web:v20260619-enrollca-c54623d", "imagePullPolicy": "Never", "livenessProbe": { "failureThreshold": 3, diff --git a/tests/bluejay-infra-lint/FleetManifestLintTests.cs b/tests/bluejay-infra-lint/FleetManifestLintTests.cs index f652257..68430b9 100644 --- a/tests/bluejay-infra-lint/FleetManifestLintTests.cs +++ b/tests/bluejay-infra-lint/FleetManifestLintTests.cs @@ -1017,6 +1017,12 @@ public sealed class FleetManifestLintTests JsonEnvSecretName(web, "FlowerCore__Auth__AdminApiKey").Should().Be("fc-devicemgmt-runtime"); JsonEnvSecretKey(web, "FlowerCore__Auth__AdminApiKey").Should().Be("DEVICE_MANAGEMENT_ADMIN_API_KEY"); JsonEnvSecretOptional(web, "FlowerCore__Auth__AdminApiKey").Should().BeNull(); + JsonEnvSecretName(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityCertificatePem").Should().Be("fc-devicemgmt-runtime"); + JsonEnvSecretKey(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityCertificatePem").Should().Be("DEVICE_MANAGEMENT_ENROLLMENT_CA_CERTIFICATE_PEM"); + JsonEnvSecretOptional(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityCertificatePem").Should().BeTrue(); + JsonEnvSecretName(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityPrivateKeyPem").Should().Be("fc-devicemgmt-runtime"); + JsonEnvSecretKey(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityPrivateKeyPem").Should().Be("DEVICE_MANAGEMENT_ENROLLMENT_CA_PRIVATE_KEY_PEM"); + JsonEnvSecretOptional(web, "FlowerCore__DeviceManagement__EnrollmentCertificateAuthorityPrivateKeyPem").Should().BeTrue(); } [Fact]