StackGuardian / StackGuardian/tirith

docs(cookbook): engine-verified path idioms — membership, at-least-one, and the traps

Open
#324 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

documentation
Dominant language
Python
Stars
165
Forks
42
Avg merge
1d 3h
Merged PRs (30d)
11

Description

A cookbook page of zero-code recipes, each verified against the running engine. House rule: every
path idiom names which of the two path engines it holds for
— the shared json/kubernetes engine
and terraform_plan disagree more often than they agree, and "true idiom, wrong engine" fails
silently.

  • Collection membership: drop the trailing .* and the provider emits the whole collection as
    one value per resource; Contains with an element dict is membership. Limit: exact element
    equality (fails where elements carry extra keys, e.g. aws_db_parameter_group.parameter with
    apply_method).
  • At-least-one via guard && !none: !id is existential in eval_expression, so De Morgan
    applies — an IsNotEmpty guard on the collection, a Not* condition on
    <collection>.*.<field>, and eval_expression: "guard && !none". Verified across matching /
    non-matching / empty-array / absent-key / empty-document cases. The guard is load-bearing:
    without it an absent collection satisfies the negation vacuously. Caveat, measured: on
    terraform_plan this is plan-wide, not per-resource (the provider flattens instances into one
    stream — two resources where only one matches returns true); sound for single-instance json
    documents and genuinely plan-wide intent only. It cannot bind two attributes of the same element,
    and the negated condition cannot be a regex.
  • Scalar-or-list: a trailing .* unwraps a scalar on the shared json/kubernetes engine, so one
    path covers a scalar-or-list union (Statement.*.Action.*). It does not hold on
    terraform_plan, where a scalar under .* is a severity-2 miss.
  • * iterates dict values, so CloudFormation's Resources map addresses exactly like ARM's
    array.
  • An empty list pads None at inner wildcard levels; only the outermost segment is a severity-2
    miss — this decides error_tolerance for nested-block-inside-repeated-block checks.
  • When every id is deleted from the AST the result is null, not true — the trap for
    all-absence policies, whose compliant case is exactly "every path misses".
  • The type-guard idiom is polarity-specific: type present + attribute absent FAILS at every inner
    tolerance, so omit the guard when upstream passes on absence; use !selected || check for
    sibling-attribute scoping.
  • nullable.TypeNullableBool provider arguments arrive in the plan as the strings
    "true"/"false", so Equals: true silently never fires — use ContainedIn: [true, "true"].

Related bug, fileable separately: a mixed-type list in ContainedIn/Equals evaluates correctly
but logs a full traceback from utils.sort_collections — cosmetic, noisy, ~2-line fix.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the cookbook documentation and the running-engine verification entry points, then compare each recipe across the shared json/kubernetes engine and terraform_plan. Use eval_expression for the guard behavior and preserve the listed edge cases, engine limitations, and type handling; the completed page should label every idiom with the engines it supports. Keep the utils.sort_collections traceback as a separate bug.

Written by the indexing model from the issue text.

Assessment

Tech stack
kubernetes, python, terraform
Domain
documentation
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.