Skip to content

security: publish immutable runtime package integrity contract for consumers #2610

Open

Description

@seonghobae

Security boundary

ContextualWisdomLab/appguardrail#1424 found that the protected consumer workflow .github/workflows/security-process.yml assigns a versioned registry package to CODEGRAPH_PACKAGE and later executes it with npx -y. Version pinning constrains package selection but does not authenticate the fetched bytes.

Central PR #532 repaired the central repository's own workflow. It does not publish a released, reusable, immutable contract that an appguardrail pull request can consume without trusting PR-owned bootstrap files or executing mutable consumer source. The initial appguardrail repair attempted a PR-owned lockfile and was rejected during independent review because the same untrusted PR could modify that lock.

Owner responsibility

The central .github repository owns the reusable CI/security contract. appguardrail owns detector rule github-actions-runtime-package-without-integrity and must retain the protected workflow as a positive regression incident until the owner contract is released and consumed.

RED

  • consumer: ContextualWisdomLab/appguardrail/.github/workflows/security-process.yml
  • detector PR: feat(security): detect GitHub Actions execution integrity risks appguardrail#1424
  • exact detector head: 1a923ea9659462f95e6e8d333acb4186f6e6e80c
  • observable signal: a versioned registry package assigned to a named *_PACKAGE variable, followed by npx or npm exec with -y/--yes
  • current expected result: one HIGH finding in the protected workflow

Required GREEN contract

  1. Publish a reusable workflow or independently released tool contract from protected main, referenced immutably by consumers.
  2. Install the security tool from repository-independent trusted bytes with byte-level integrity verification (lock hash, release digest/signature/provenance, or equivalent).
  3. Treat pull-request source as scan input only; do not execute PR-owned bootstrap scripts, package manifests, lockfiles, or workflow code before admission.
  4. Bind receipts to repository, PR, protected base, and exact source head; fail closed on mismatch, missing evidence, mutable references, or stale/predecessor receipts.
  5. Add RED/GREEN fixtures for modified PR lockfiles, local tarballs, registry byte substitution, mutable tags/branches, and exact-head mismatch.
  6. Release/version the contract immutably before appguardrail consumes it through a thin caller.
  7. Preserve current security gates; no continue-on-error, suppression, or dependency downgrade.

Completion

This issue is complete only after the canonical owner contract is merged on protected main, released immutably, and appguardrail consumes that release with exact-head GREEN evidence. Documentation or the central repository's internal-only repair is not sufficient.

Activity

  1. seonghobae commented on Oct 9, 2026

    @seonghobae
    ContributorAuthor

    Appguardrail detector stabilized

    The consumer-side detector is now Draft ContextualWisdomLab/appguardrail#1424 exact a0fab92ab9f854e641b2f7de46a3e39fea2562e3, tree 0c7c7f5b0705ca9d5c30625ac0ebb5591a2c5513.

    It retains appguardrail's protected security-process.yml as exactly one HIGH incident and has no workflow, package manifest, lockfile, bootstrap, dependency, or gate change. Verification is 1,115 full / 69 focused tests and independent final read-only Critical 0 / Important 0.

    This preserves the owner boundary: #2610 still owns the immutable released consumer contract. Detector evidence does not complete the owner repair, and no PR-owned lockfile is accepted as trust.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions