{"record":{"id":"c46ebff8e8009c7d","repo":"microsoft/aspire","slug":"aspireradius063","errorCode":"ASPIRERADIUS063","errorMessage":"Secret store '{storeName}' references a SealedSecret manifest at '{manifestPath}' whose '{LastAppliedConfigurationAnnotation}' annotation embeds a plaintext Kubernetes Secret (kind 'Secret' with 'data'/'stringData'), or content that cannot be verified as sealed. Such annotations are copied verbatim into publish artifacts and applied to the cluster, so the cleartext would leak. Re-seal from a clean manifest without the annotation. Diagnostic: ASPIRERADIUS063.","messagePattern":"Secret store '(.+?)' references a SealedSecret manifest at '(.+?)' whose '(.+?)' annotation embeds a plaintext Kubernetes Secret \\(kind 'Secret' with 'data'/'stringData'\\), or content that cannot be verified as sealed\\. Such annotations are copied verbatim into publish artifacts and applied to the cluster, so the cleartext would leak\\. Re-seal from a clean manifest without the annotation\\. Diagnostic: ASPIRERADIUS063\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Aspire.Hosting.Radius/Secrets/SealedSecretManifest.cs","lineNumber":351,"sourceCode":"    }\n\n    private static void CheckLastAppliedAnnotation(\n        string storeName, string manifestPath, YamlMappingNode owner)\n    {\n        if (!TryGetNode(owner, \"metadata\", out var metadataNode) || metadataNode is not YamlMappingNode metadata ||\n            !TryGetNode(metadata, \"annotations\", out var annotationsNode) || annotationsNode is not YamlMappingNode annotations ||\n            !TryGetNode(annotations, LastAppliedConfigurationAnnotation, out var valueNode))\n        {\n            return;\n        }\n\n        // The annotation is present. A legitimate value is always a JSON string scalar (Kubernetes\n        // annotation values are `map[string]string`). Anything else — a YAML mapping/sequence, or a\n        // null/empty scalar where we expected JSON — cannot be verified free of cleartext, so fail\n        // closed rather than skip it.\n        if (valueNode is not YamlScalarNode { Value: { } lastApplied } || EmbedsPlaintextSecret(lastApplied))\n        {\n            throw new InvalidOperationException(\n                $\"Secret store '{storeName}' references a SealedSecret manifest at '{manifestPath}' whose \" +\n                $\"'{LastAppliedConfigurationAnnotation}' annotation embeds a plaintext Kubernetes Secret \" +\n                \"(kind 'Secret' with 'data'/'stringData'), or content that cannot be verified as sealed. Such \" +\n                \"annotations are copied verbatim into publish artifacts and applied to the cluster, so the \" +\n                \"cleartext would leak. Re-seal from a clean manifest without the annotation. \" +\n                \"Diagnostic: ASPIRERADIUS063.\");\n        }\n    }\n\n    // Example annotation value (a single JSON string):\n    //   {\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{...},\"data\":{\"password\":\"cGFzcw==\"}}\n    // Returns true when that JSON is a plaintext Secret carrying data/stringData, or when it cannot\n    // be parsed as the expected object (fail closed). An embedded SealedSecret returns false.\n    private static bool EmbedsPlaintextSecret(string lastAppliedJson)\n    {\n        try\n        {\n            using var document = JsonDocument.Parse(lastAppliedJson);","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Radius/Secrets/SealedSecretManifest.cs#L333-L369","documentation":"The sealed-secrets workflow can leave a last-applied-configuration annotation embedding the original plaintext Secret JSON (with data/stringData). Since Aspire copies the SealedSecret manifest verbatim into publish artifacts, such an annotation would leak cleartext credentials; validation fails closed when the annotation exists and either is not a JSON string scalar or embeds a plaintext Secret.","triggerScenarios":"CheckLastAppliedAnnotation (called by RejectPlaintextLastAppliedAnnotation during manifest validation) finds the last-applied-configuration annotation whose value is not a plain JSON string scalar, or whose embedded JSON contains a 'Secret' kind with data/stringData.","commonSituations":"Manifest created by 'kubectl apply -f secret.yaml && kubeseal' without cleaning the recorded annotation (kubectl apply records it), or an annotation value that is a YAML mapping/null rather than a JSON string.","solutions":["Remove the last-applied-configuration annotation from the SealedSecret and re-seal from a clean manifest.","Re-generate with kubeseal from a fresh source Secret: 'kubectl create secret generic x --from-literal=... -o yaml --dry-run=client | kubeseal -o yaml > sealed.yaml' (dry-run output carries no recorded annotation).","If the annotation is intentionally non-secret JSON that fails the check, remove it anyway — the validator cannot verify it is sealed and fails closed."],"exampleFix":"// before (metadata.annotations contains)\nkubectl.kubernetes.io/last-applied-configuration: '{\"kind\":\"Secret\",\"data\":{\"password\":\"cGFzcw==\"}}'\n// after\nmetadata:\n  name: my-secret  # annotation removed; re-sealed from clean manifest","handlingStrategy":"validation","validationCode":"var annotations = doc[\"metadata\"]?[\"annotations\"];\nif (annotations?[\"kubectl.kubernetes.io/last-applied-configuration\"] is { }) throw new InvalidOperationException(\"SealedSecret embeds last-applied-configuration annotation; re-seal from a clean manifest.\");","typeGuard":"bool HasLastAppliedAnnotation(YamlNode root) => root is YamlMappingNode m && m[\"metadata\"] is YamlMappingNode md && md[\"annotations\"] is YamlMappingNode a && a.Children.ContainsKey(new YamlScalarNode(\"kubectl.kubernetes.io/last-applied-configuration\"));","tryCatchPattern":"try { store = ReadValidated(...); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"ASPIRERADIUS063\")) { // strip the annotation and re-seal; do NOT commit the manifest }","preventionTips":["Create sealed secrets from 'kubectl create ... --dry-run=client -o yaml | kubeseal' so no last-applied annotation is recorded.","Never kubectl-apply plaintext Secrets into the objects you later seal.","Scan sealed manifests for 'last-applied-configuration' in CI."],"tags":["security","credentials","kubernetes","sealed-secrets"],"backgroundTag":"plaintext-secret-leak","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}