Skip to content

Add resource budgets to manifest template evaluation #651

Description

@leynos

Summary

Manifest template evaluation has no explicit application-level execution, output, or expansion budget.

The original Codex finding described an older implementation that rendered the entire YAML document twice. main no longer has that exact shape: Netsuke now parses YAML first and renders recognized fields individually. The underlying availability defect remains at ac10b783f33661a0af27bd8f5d19065f095f98db:

  • each rendered field calls MiniJinja Environment::render_str() and materializes an owned String without a Netsuke output limit;
  • manifest macro invocation uses the same unbounded render path;
  • foreach expressions call try_iter() and collect the complete sequence;
  • expansion clones a target/action map once per item with no cardinality or aggregate expansion limit;
  • no shared per-manifest fuel/iteration budget constrains repeated expressions, loops, macro calls, when evaluation, or rendering across fields.

Any MiniJinja internal defaults are library implementation details; Netsuke currently defines no product-level resource contract or localized limit failure.

Examples

A compact recipe field can request enormous output before any build command runs:

targets:
  - name: generated
    command: "{% for _ in range(1000000000) %}x{% endfor %}"

A compact foreach expression can request an enormous number of expanded entries, each cloning the source mapping and later flowing through rendering and IR generation.

These paths affect build/generate operations before recipe execution. foreach, when, and discovery-field rendering can also affect manifest-query operations intended only to inspect metadata.

Impact

A small attacker-controlled Netsukefile can consume unbounded CPU and memory on a developer machine or CI worker during parsing, expansion, and rendering. External cgroup/job limits may eventually kill the process, but Netsuke should fail deterministically and diagnostically before exhausting its host.

Required change

Introduce a coherent resource budget covering the whole manifest evaluation pipeline, not a collection of unrelated local caps.

The design should include:

  • an instruction/fuel or equivalent evaluation-work budget shared across template rendering, expressions, when, and macro invocation;
  • a maximum rendered byte count per value and across the complete manifest;
  • a maximum foreach cardinality and maximum aggregate expanded target/action count;
  • early termination while consuming iterators rather than collecting an unbounded sequence first;
  • checked accounting for source size, macro imports, cloned expansion data, and rendered output;
  • localized errors that identify the exhausted budget and evaluation stage without echoing secret-bearing template/context values;
  • operator-controlled configuration whose limits cannot be raised by an untrusted project configuration layer.

Use MiniJinja's supported fuel/output facilities where they provide the required guarantees; retain Netsuke-owned accounting for expansion and aggregate limits that the template engine cannot observe.

Acceptance criteria

  • A compact large-loop template fails with a deterministic resource-limit diagnostic before allocating output proportional to the requested loop size.
  • foreach iteration stops at a configured bound without first collecting or cloning every item.
  • A per-manifest aggregate budget prevents many individually small fields from bypassing the per-field limit.
  • Macro calls, when expressions, normal field rendering, and query-mode evaluation consume the appropriate shared budget.
  • Limits have safe defaults and may be narrowed by more-trusted operator configuration; project configuration cannot widen them implicitly.
  • Ordinary existing manifests below the limits retain byte-for-byte rendered behaviour.
  • Tests exercise exact-boundary success, one-unit-over failure, many-field aggregate exhaustion, large foreach, nested macro/loop work, and manifest-query mode using deliberately small test budgets rather than huge allocations.
  • Limit diagnostics and telemetry are bounded and do not include raw template text, context values, or rendered secrets.
  • The users guide and design document specify defaults, accounting units, configuration precedence, and failure behaviour.
  • make check-fmt, make lint, make test, make markdownlint, and make nixie pass.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or requesthighUnblocks delivery within the current sprint or release window. Reaction time is days, not hours.performancetestingTest coverage, test infrastructure, and verification tooling work.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions