Guide 165 workflow

How to review a service with generated and vendor code

Review generated and vendor code through its contracts, provenance and callers, then place repairs where regeneration or a dependency refresh will preserve them.

Do not treat “generated” or “vendor” as a blanket security exception. Inventory those files, identify what produces or supplies them, and trace where their behavior reaches a protected action. Review the generator inputs, schema, templates, local modifications and integration code. Use dependency and provenance review for copied third-party material. If you exclude mechanical output from line-by-line source analysis, record the exact paths, reason, alternative control and owner. The final report should still show that those bytes were present but not directly reviewed.

The answer changes when generated output contains hand-written edits, the generator is unavailable, or vendor code has been forked. Such code may need direct review because the supposed source of truth is incomplete. GitHub's guidance on alerts in generated code explains ways to limit CodeQL analysis, but a tool configuration choice is not an assurance that excluded code is safe. The platform engineer should make the choice visible to AppSec and service owners.

Sort origin before setting exclusions

At a pinned revision, classify the service's files into four useful groups:

Group Evidence to collect Primary review question
Hand-written application code Owner, routes, data access and deployment binding Does it enforce the intended security invariant?
Generated output Generator name/version, input schema, templates, output path, change detection Could generated behavior expose data or weaken a boundary?
Vendored source or binaries Supplier, version/hash, license and update path, local patch record Which known risks and local changes affect this exact copy?
Link or submodule Target, pinned commit and access to its content Was the child actually acquired and assessed?

Do not identify origin only from a directory name. A file under generated/ may have been edited after generation; a file under vendor/ may be a local fork. Compare the current output to a documented regeneration process only in an authorized development environment. A security review of untrusted source should inspect files as data; it need not execute repository hooks, build scripts, plugins or dependencies. If the generator cannot be trusted or obtained, record that uncertainty and decide whether direct output inspection is required.

Vendor code needs a separate question from locally generated code. For a package represented in a supported manifest or lockfile, a dependency graph can show its recorded version and known vulnerability information; GitHub's dependency graph documentation says its graph is based on manifests, lockfiles and submitted dependency data. A hand-copied file may not appear there. Check the actual imported bytes and the deployable artifact rather than assuming the graph is complete. OWASP's software supply chain guidance recommends understanding and monitoring dependencies and their build path.

Illustrative case: a payment webhook service

Illustrative case. Fictional MeadowPay has a webhook service in a monorepo. It contains hand-written handler.ts, an OpenAPI-generated request client, a copied vendor signature helper and generated SQL bindings. The service accepts payment events and updates customer invoices. The names and observations are invented; no real source was executed or tested.

The platform engineer's first concern is the trust boundary: an external webhook must be authenticated before its invoice ID and account ID affect a customer-owned row. The generated client is mostly transport code, but the schema controls which fields are accepted and whether an account_id can be supplied. The copied signature helper is security critical, regardless of the vendor/ label. The generated SQL binding could scope updates by invoice ID alone or by both account and invoice; the query definition and call site need inspection.

The schema is safe; the emitted query is not the same program

The fictional SQL source contains the intended restriction:

-- queries/mark_invoice_paid.sql: generator input
UPDATE invoices SET paid = true
WHERE account_id = :account_id AND invoice_id = :invoice_id;

The generated binding should pass both parameters. But MeadowPay's release process includes a hand-edited generated file, justified in an old comment as a performance workaround. The deployed binding in the example contains:

markInvoicePaid(accountId, invoiceId):
  execute("UPDATE invoices SET paid = true WHERE invoice_id = ?", invoiceId)

The unused accountId parameter makes the call site look scoped. The missing predicate breaks the accessor's intended account-scoping contract. Whether it permits an unauthorized update still depends on the caller's authenticated event, invoice selection and other mandatory controls; the fragment alone is not a demonstrated cross-account exploit. Reviewing only the query input would give the wrong answer; reviewing only the generated output would find the defect but miss why the next regeneration might restore or reintroduce it.

The review follows input → generator/configuration → local modification → call site → shipped artifact. It does not run the generator on untrusted source. The owner supplies the documented generation process and build mapping; the reviewer compares relevant source and emitted behavior as data. The initial disposition changes from “mechanical output, bounded sample” to “directly review this binding and remove the uncontrolled post-generation edit.” The fix must leave one maintained source of truth. A local predicate repair that is overwritten at the next generation is unfinished.

A vendor version does not explain a local signature patch

The copied signature helper has a second provenance problem. The owner first says it is “upstream version 4.” An upstream commit later matches most files, but a local patch changes which request bytes enter signature verification: it parses JSON and serializes it again before calling the verifier. Whether that is correct depends on the provider's exact signed-message contract. The handler's successful call to verifySignature does not settle it.

In this illustrative contract, the provider signs the original request bytes. The local transformation may change whitespace or field representation, causing legitimate signatures to fail; the article does not infer a signature bypass from that alone. The required repair is to preserve the bytes specified by the provider and review the failure path. If failure triggers an “accept for compatibility” branch, that branch becomes a separate authentication concern. Without that branch, the supported issue may be rejected webhooks and invoice state divergence. Check the actual provider's current primary documentation before adopting either conclusion in a real review.

Revised origin register after both discoveries

Item Evidence that changes the review Filled disposition and follow-through
src/handler.ts Passes account and invoice, then trusts generated update result Review authentication, authoritative account derivation and effect together. Correct arguments alone did not protect the query.
gen/db/markInvoicePaid Output diverges from scoped SQL input Direct review required; repair source/process, inspect new emitted binding, match new artifact.
vendor/signature/** Upstream commit identified; security-sensitive local patch remains Upstream version alone insufficient. Check provider byte contract and reject/fallback behavior; retain patch provenance.
gen/client/** Schema/configuration identified; selected output agrees for this path Sampled review of relevant selectors retained; other transport methods inventoried, not reviewed.
optional-fraud-module Gitlink only; no authorized child content Record unavailable content; decide separately whether the webhook path can call it.

This register shows why “exclude generated and vendor code” is the wrong first decision. Most client transport may remain a sensible deferral, while a tiny generated database binding and a copied helper deserve the deepest reading.

SLSA provenance provides a structured way to describe build inputs and outputs. A provenance document is useful only when its artifact and materials match this release; it does not prove that a local transformation preserves authorization. For MeadowPay, the acceptance evidence is the scoped emitted update in the new artifact, a documented regeneration path that retains it, and signature handling checked against the actual provider contract. None of those checks is claimed to have been executed here.

Choose a repair that survives regeneration

MeadowPay has two places where a quick edit could be lost. The SQL binding is generated from an input query, while the signature helper is copied from an upstream project and locally patched. Before changing either, the owner should decide which source is maintained and how its output reaches the release. Otherwise, the next routine regeneration or vendor refresh can overwrite the repair or reproduce the original divergence.

For the SQL binding, the intended account predicate already exists in the input. The missing step is a trustworthy relationship between that input and the shipped output, including removal of the uncontrolled edit. The repair record should show the relevant emitted operation, its call contract and the build that contains it. It need not claim that every generated client method was reviewed. The question is whether this security-sensitive binding now implements the intended operation and remains governed by the documented process.

For the copied signature helper, preserve the local patch as an explicit difference from the identified upstream commit. Decide whether to remove it, replace it with a maintained integration wrapper, or retain a reviewed change with a named owner. A version label that hides the patch will mislead future advisory and update work. The patch rationale should name the provider byte contract and the behavior it is intended to preserve, including failure handling.

A later vendor update should compare both upstream changes and local modifications. If an upstream release changes the verification API, an old local adaptation may no longer be appropriate even when it still compiles. Conversely, an unchanged local patch remains part of the application's security review surface after the vendor version advances.

When direct source access to a generator or proprietary component is unavailable, state the alternate evidence used: a relevant contract, a matched output sample, supplier provenance or a controlled authorized observation. Each may support a bounded conclusion. None should be described as a complete review of unseen implementation. The origin register makes that limit visible while still allowing engineers to make a practical release decision.

Configure tools without hiding scope

When scan cost or alert noise requires path exclusion, write an exclusion manifest with the glob, reason, origin, alternative review, owner, expiry or review trigger, and the scan configuration version. Confirm what the setting does. GitHub's CodeQL workflow options distinguish source-analysis paths and paths-ignore from workflow event filters; for build-based analysis, build steps can determine which compiled code is analyzed. A workflow triggered by a change is not proof that its changed file was examined.

For the webhook example, gen/client/** could be excluded from routine line-level alerts only after the schema, generator and representative security-sensitive output are assigned to named review steps. vendor/signature/** should remain in a separate manual/supply-chain review until the provider contract and patch behavior are resolved. The report must say which paths were merely inventoried, acquired, searched, sampled or actually examined. If the provider truncates the file list, the exclusion analysis itself is incomplete.

At the end, give service owners a precise decision: “The webhook event-to-invoice path was examined at this revision. The signature helper's upstream commit is known, but its local patch still needs a provider-contract check; the optional submodule was not acquired. Generated client output received a bounded sample review, not whole-output assurance.” If the missing helper proof affects release safety, make the release owner decide with that uncertainty visible. No absence of alerts should erase it.

Next step: Pick one generated directory and one vendored component and fill the origin register at a pinned revision. Use the monorepo boundary guide to decide which emitted behavior can cross a trust boundary, then the budget guide to schedule deeper work.