Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/security/dependency-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ Every bootstrap, PR, or release report that claims this baseline is enforced mus
- any failed command or GitHub API call when enforcement could not be completed
- any remaining manual review item that still needs repository-admin action

## Named dependency-path authority

`scripts/checks/verify_supply_chain.py` treats a Cargo owner chain as a
*simple path*: a package key may appear at most once on a candidate walk
(Cormen et al., 2022, Appendix B.4). A shared
`(package_key, matched_count)` cache is not an equivalent optimization.
On a cycle such as `root → alpha@1 → beta → alpha@1 → charlie`, that cache
can reuse `alpha@1` to satisfy a second `alpha` position and falsely accept
the chain. Distinct keys that share a name (`alpha@1` then `alpha@2`) remain
valid. Do not reintroduce a global state cache to save `frozenset` copies.
Keep cycle and distinct-key regressions in
`services/analysis-engine/tests/test_supply_chain_dependency_path_cycles.py`.

## Vulnerability exception handling

Exceptions are allowed only when no patched version exists and the advisory is non-exploitable for this repository context.
Expand Down Expand Up @@ -138,3 +151,7 @@ Mark work as `BLOCKED` only when platform execution is impossible because GitHub
## Fast reference

`모든 보호 브랜치 변경은 dependency review, 보안 점검, SBOM 생성·검증을 통과해야 하며, release 산출물은 GitHub에서 추적 가능한 SBOM과 함께 배포되고, 이 공급망 통제는 에이전트가 임의로 해제하지 않는다.`

## References

Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2022). *Introduction to algorithms* (4th ed.). MIT Press.
8 changes: 7 additions & 1 deletion scripts/checks/verify_supply_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1988,7 +1988,13 @@ def cargo_lock_has_named_dependency_path(
root_package: str,
package_names: tuple[str, ...],
) -> bool:
"""Return whether a dependency path contains package names in order."""
"""Return whether a simple dependency path contains package names in order.

A package key may appear at most once on a candidate path. Shared
``(package_key, matched_count)`` caches are unsafe: a cycle can revisit
the same key with a later match count and falsely satisfy a repeated
name. Distinct keys that share a package name remain valid matches.
"""
pending: list[tuple[str, int, frozenset[str]]] = [(root_package, 0, frozenset())]
while pending:
current, matched_count, seen = pending.pop()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Regression tests for Cargo dependency-path cycle handling."""

from conftest import load_module


def test_dependency_path_does_not_reuse_a_package_key_through_a_cycle() -> None:
"""Ensure a cycle cannot make one package instance satisfy two path positions."""
supply_chain = load_module(
"scripts/checks/verify_supply_chain.py",
"verify_supply_chain_dependency_path_cycle_regression",
)
package_dependencies = {
"root 1.0.0": ["alpha 1.0.0"],
"alpha 1.0.0": ["beta 1.0.0", "charlie 1.0.0"],
"beta 1.0.0": ["alpha 1.0.0"],
"charlie 1.0.0": [],
}

assert not supply_chain.cargo_lock_has_named_dependency_path(
package_dependencies,
"root 1.0.0",
("alpha", "alpha", "charlie"),
)


def test_dependency_path_can_match_same_name_on_distinct_package_keys() -> None:
"""Ensure distinct package instances may legitimately satisfy repeated names."""
supply_chain = load_module(
"scripts/checks/verify_supply_chain.py",
"verify_supply_chain_dependency_path_distinct_instances",
)
package_dependencies = {
"root 1.0.0": ["alpha 1.0.0"],
"alpha 1.0.0": ["beta 1.0.0"],
"beta 1.0.0": ["alpha 2.0.0"],
"alpha 2.0.0": ["charlie 1.0.0"],
"charlie 1.0.0": [],
}

assert supply_chain.cargo_lock_has_named_dependency_path(
package_dependencies,
"root 1.0.0",
("alpha", "alpha", "charlie"),
)
Loading