Build a render-preview endpoint
A preview endpoint should render a chart and return the manifest. It should not create a release, reach a cluster, or accept an arbitrary file-system path from a caller.
Install HelmSharp.Chart and HelmSharp.Engine, then resolve the requested chart through an application-owned catalog before calling the renderer:
app.MapPost("/preview", async (
PreviewRequest request,
ChartCatalog charts,
ValuesCatalog valuesCatalog,
CancellationToken cancellationToken) =>
{
var chartPath = charts.GetPath(request.ChartId); // Enforces your allowlist.
var valuesFilePaths = valuesCatalog.GetPaths(request.ValuesFileIds); // Resolve IDs, never caller-provided paths.
var chart = await HelmChartLoader.LoadAsync(chartPath, cancellationToken);
var values = await HelmValues.BuildAsync(
chart,
valuesFiles: valuesFilePaths,
valuesContent: request.ValuesContent,
setValues: request.SetValues,
setFileValues: null,
setStringValues: request.SetStringValues,
setJsonValues: request.SetJsonValues,
cancellationToken: cancellationToken);
var renderer = new HelmTemplateRenderer(
chart,
request.ReleaseName,
request.Namespace,
values,
kubeVersion: request.KubeVersion,
apiVersions: request.ApiVersions,
isUpgrade: false);
return Results.Text(renderer.Render(), "text/yaml");
});ChartCatalog and ValuesCatalog are intentionally application-specific. They might resolve IDs to versioned directories, extracted archives, or a tenant's authorized catalog entries. Keeping path resolution outside the request prevents path traversal and unintended server-side file reads, and makes every preview traceable to exact inputs.
For a production endpoint:
- accept values-file IDs rather than paths, limit uploaded/inline values size, and reject override paths your product does not support;
- persist the chart version, effective input set, target capabilities, and rendered artifact for later approval;
- keep manifest and values access-controlled because either can contain credentials;
- call
RenderNotes()only when the response has a separate field for human-facing notes.
The review-to-deployment example shows how to turn the stored preview into a cluster-changing operation without replacing this render-only boundary.