@clear-capabilities/agentic-security-scanner 0.195.28 → 0.195.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/bin/agentic-security.js +13 -4
- package/dist/1340.index.js +11 -6
- package/dist/3500.index.js +943 -0
- package/dist/5616.index.js +146 -19
- package/dist/{3eabd90d6d9c8c8dbbd9.json → 7e58a58b8e6ccdde1659.json} +7 -6
- package/dist/9560.index.js +29 -5
- package/dist/agentic-security.mjs +2 -2
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +7 -6
- package/src/egress/policy.js +79 -1
- package/src/engine.js +1 -1
- package/src/language/CLAUDE.md +1 -1
- package/src/language/haskell-guards.js +26 -5
- package/src/lineage/CLAUDE.md +3 -1
- package/src/lineage/deployment/adapter-cloud.js +5 -2
- package/src/lineage/deployment/attack-paths.js +107 -30
- package/src/lineage/deployment/boundaries-run.js +2 -2
- package/src/lineage/deployment/iam-eval.js +105 -0
- package/src/lineage/deployment/projection.js +10 -4
- package/src/lineage/deployment/proof-binding.js +79 -0
- package/src/llm-validator/bounded-context.js +115 -8
- package/src/llm-validator/index.js +1 -1
- package/src/mcp/CLAUDE.md +6 -0
- package/src/mcp/tools.js +27 -3
- package/src/pipeline/evidence-record.js +1 -1
- package/src/posture/CLAUDE.md +2 -0
- package/src/posture/assurance/candidate-qualification.js +155 -0
- package/src/posture/assurance/release-package-cli.js +44 -2
- package/src/posture/auditor-walkthrough.js +2 -1
- package/src/posture/dnr/detection-ir.js +2 -2
- package/src/posture/dnr/hunt.js +22 -6
- package/src/posture/dnr/log-reader.js +47 -3
- package/src/posture/dnr/matchers.js +43 -3
- package/src/posture/dnr/outputs.js +16 -2
- package/src/posture/dnr/payload-classes.js +12 -2
- package/src/posture/dnr/validate.js +17 -4
- package/src/posture/evaluation/report.js +2 -1
- package/src/posture/evaluation/score.js +24 -7
- package/src/posture/logic-claims.js +15 -14
- package/src/posture/sibling-queue.js +69 -0
- package/src/posture/triage-memory.js +106 -26
- package/src/posture/verification-separation.js +55 -7
- package/src/report/index.js +4 -0
- package/src/runScan.js +5 -0
- package/src/scope/flags.js +1 -0
- package/src/scope/inventory.js +17 -1
- package/src/scope/release-scope.js +80 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
49efaca1a4d9c735d54511f9e3b65837265fbc5341177c79a5fb6e9a4d3bea90 agentic-security.mjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clear-capabilities/agentic-security-scanner",
|
|
3
|
-
"version": "0.195.
|
|
3
|
+
"version": "0.195.30",
|
|
4
4
|
"description": "Scanner engine for the agentic-security Claude Code plugin: SAST, SCA with reachability and CISA KEV, secrets, IaC, Haskell and Nix/NixOS, prompt-injection, MCP/agent-tool audit, authZ analysis, SBOM, compliance attestation, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -87,14 +87,14 @@
|
|
|
87
87
|
"test:ollama-e2e": "AGENTIC_SECURITY_OLLAMA_E2E=1 node --test test/ollama-e2e.test.js",
|
|
88
88
|
"test:glob": "node --test test/glob-compat.test.js",
|
|
89
89
|
"test:sast": "node --test test/dag-precision.test.js test/cpp-hardcoded-secret.test.js test/sibling-guard.test.js test/comment-blindness.test.js test/todo-marker-words.test.js test/crypto-specialist.test.js test/llm.test.js test/llm-cost-advisor.test.js test/llm-owasp.test.js test/logic.test.js test/authz.test.js test/model-load.test.js test/prompt-template.test.js test/business-logic.test.js test/python-sinks.test.js test/phase1-detectors.test.js test/phase2-detectors.test.js test/phase3-v3.test.js test/phase7-extensions.test.js test/phase8-extensions.test.js test/new-cwe-detectors.test.js test/file-upload.test.js test/llmsecops-detectors.test.js test/db-taint.test.js test/dart-swift.test.js test/zip-slip-containment-guard.test.js test/zip-slip-go.test.js test/redos-anchoring.test.js test/path-guard-validator-call.test.js test/redos-nfa.test.js test/weak-randomness.test.js test/csharp-pipeline.test.js test/csharp-cross-file.test.js test/post-quantum-crypto.test.js test/web3-advanced.test.js test/cloud-iam-k8s.test.js test/crypto-protocol.test.js test/ml-supply-chain.test.js test/mcp-audit-scan.test.js test/wrong-context-sanitizer.test.js test/sanitizer-context.test.js test/frontend-hygiene.test.js test/csv-injection.test.js test/stored-taint.test.js test/tree-sitter-sinks.test.js test/kotlin-structural.test.js test/ruby-php-structural.test.js test/java-csharp-structural.test.js test/java-structural-cross-file.test.js test/guard-recognition.test.js test/guard-window-identifier-correlation.test.js test/js-python-framework-structural.test.js test/go-structural.test.js test/secret-concat.test.js test/secret-redaction.test.js test/xss-reflected-multilang.test.js test/code-injection-multilang.test.js test/xxe-multilang.test.js test/xpath-injection-multilang.test.js test/gapfill-batch13.test.js test/agent-untrusted-flow.test.js test/api-authz.test.js test/event-entrypoint.test.js test/iac-terraform.test.js test/cross-service.test.js test/rbac-consistency.test.js test/adversarial-robustness.test.js test/secret-entropy.test.js test/comment-strip.test.js test/juliet-path-filter-gate.test.js test/java-bench-shape-opt-in.test.js test/vendor-java-parser-current.test.js test/java-ast-folding.test.js test/java-bench-extras.test.js test/reachability-missing-callgraph-data.test.js test/rate-limit.test.js test/auth-signals.test.js test/convention-deviation.test.js test/resource-exhaustion.test.js test/resource-exhaustion-realworld.test.js test/redirect-toctou.test.js test/redirect-toctou-realworld.test.js test/codegen-sink.test.js test/ownership-authz.test.js test/ownership-authz-realworld.test.js test/t21-precision-audit.test.js test/secrets-coverage.test.js test/prompt-injection-payloads.test.js test/iac-cloud-templates.test.js test/ruby-path-join.test.js test/sast/manifest-line-tracking.test.js test/rust-sast.test.js test/java-deserialization-precision.test.js test/pipeline-env-secret.test.js test/mark-used-vuln-functions.test.js",
|
|
90
|
-
"test:posture": "node --test test/contracts/finding-provenance.contract.test.js test/contracts/root-cause-sweep.contract.test.js test/contracts/model-validation.contract.test.js test/contracts/agentic-discovery.contract.test.js test/contracts/local-models.contract.test.js test/contracts/dependency-finding.contract.test.js test/contracts/taint-flow.contract.test.js test/contracts/runtime-corroboration.contract.test.js test/compliance-coverage.test.js test/contracts/blast-radius.contract.test.js test/contracts/federation.contract.test.js test/contracts/eval-lab-report.contract.test.js test/contracts/fleet.contract.test.js test/contracts/rule-compiler.contract.test.js test/contracts/release-assurance.contract.test.js test/contracts/dnr.contract.test.js test/contracts/strategic-metrics.contract.test.js test/contracts/exploit-proof.contract.test.js test/contracts/artifact-provenance.contract.test.js test/dnr/artifact-join.test.js test/rule-pack-signing.test.js test/threat-model.test.js test/git-hardening.test.js test/privacy-framework.test.js test/material-change.test.js test/drift.test.js test/scorecard.test.js test/accuracy-scorecard.test.js test/scorecard-gate.test.js test/predeploy-gate.test.js test/release-check.test.js test/pre-push-gate.test.js test/dependency-currency.test.js test/package-contents-check.test.js test/gate-verdict-cache.test.js test/run-unit-tests.test.js test/temp-leak-guard.test.js test/release-workflow.test.js test/release-workflow-structure.test.js test/independent-population.test.js test/why-missed.test.js test/independent-scoring.test.js test/evidence-bundle.test.js test/obligation-evidence-pack.test.js test/policy-bundle.test.js test/discovery-memory.test.js test/mttr.test.js test/license-policy.test.js test/aibom.test.js test/sbom.test.js test/api-inventory.test.js test/iam-policy.test.js test/container.test.js test/container-runtime.test.js test/image-packages.test.js test/kev.test.js test/dep-confusion.test.js test/sca-deprecated.test.js test/sca-batch.test.js test/composite-risk.test.js test/epss-enrich.test.js test/sca-coverage.test.js test/gradle-deps.test.js test/sca-route-reachable.test.js test/sca-policy.test.js test/sca-verdict.test.js test/install-script.test.js test/sca-linked-findings.test.js test/packs.test.js test/flow-narration.test.js test/regression-test-gen.test.js test/deterministic-fix.test.js test/falsification.test.js test/verification-separation.test.js test/logic-claims.test.js test/attestation.test.js test/verify-attestation-cli.test.js test/comparison.test.js test/determinism-cross-machine.test.js test/fix-honesty-gate.test.js test/model-routing.test.js test/root-cause-sweep.test.js test/entrypoint-inventory.test.js test/relevance.test.js test/untrusted.test.js test/agent-hardening.test.js test/rule-synthesis.test.js test/policy-gate.test.js test/agents-memory.test.js test/cve-lookup.test.js test/cve-alert-daemon.test.js test/fix-verify-loop.test.js test/fix-verify-tests.test.js test/fix-acceptance.test.js test/exploitability-probability.test.js test/history-scan.test.js test/viral-features.test.js test/viral-v074.test.js test/state-dir.test.js test/ignore-pragma.test.js test/license-graph.test.js test/secret-live-check.test.js test/attack-taxonomy.test.js test/triage-memory.test.js test/pr-augment.test.js test/chat-batch2.test.js test/chat-batch3.test.js test/chat-batch4.test.js test/chat-batch5.test.js test/chat-batch6.test.js test/risk-scenario-disclosure.test.js test/egress-policy.test.js test/egress-transport.test.js test/local-preset-callers.test.js test/egress-policy-completeness.test.js test/egress-policy-integration.test.js test/router.test.js test/legacy-alias-redirect.test.js test/cache-economics.test.js test/coverage-report.test.js test/corpus-status.test.js test/provenance.test.js test/secret-history.test.js test/execution-proof.test.js test/fix-metrics.test.js test/corpus-enroll.test.js test/prove-findings.test.js test/corpus-match.test.js test/corpus-provenance.test.js test/learning-quorum.test.js test/llm-cache-integrity.test.js test/scope/inventory.test.js test/scope/readtree-scope.test.js test/scope/cli-scope.test.js test/scope/watch-scope.test.js test/workflow-flow.test.js test/oidc-trust.test.js test/haskell-coverage/coverage.test.js test/validation-disposition.test.js test/claim-groups.test.js test/validation-bounded-context.test.js test/evidence-record.test.js test/report-disposition-view.test.js test/sca-basis.test.js test/proof-artifact.test.js test/providers.test.js test/fleet.test.js test/autopilot.test.js test/autopilot-cli.test.js test/verifier-independence.test.js test/integrity-legacy-key.test.js test/suppression-visibility.test.js test/cost-ceiling.test.js test/local-endpoint.test.js test/ollama-provider.test.js test/ollama-capabilities.test.js test/ollama-offline-egress.test.js test/ollama-fix-proposal.test.js test/ollama-explain-proposal.test.js test/ollama-poc-proposal.test.js test/ollama-model-probe.test.js test/ollama-agent-tools.test.js test/ollama-agent-loop.test.js test/ollama-e2e.test.js test/ollama-oom-feedback.test.js test/ollama-doc-drift.test.js test/model-trust.test.js test/vuln-archaeology.test.js test/scan-checkpoint.test.js test/llm-redact.test.js test/world-class-batch2.test.js test/api-contract-scope.test.js test/world-class-modules.test.js test/privacy-ir-adapter.test.js test/privacy-taxonomy.test.js test/privacy-sink-policy.test.js test/privacy-governance.test.js test/privacy-inventory.test.js test/integration-end-to-end.test.js test/streak-cli-wiring.test.js test/stack-playbook.test.js test/machine-output-flag.test.js test/stdout-flush.test.js test/format-determinism.test.js test/only-flag-channels.test.js test/confidence.test.js test/security-trend.test.js test/calibration-drift.test.js test/validator-metrics.test.js test/clustering-ir-taint-line.test.js test/concurrency-cwe.test.js test/compliance-mapping-liveness.test.js test/module-artifact-liveness.test.js test/supply-chain-provenance-completeness.test.js test/compliance-severity-threshold.test.js test/compliance-severity-policy.test.js test/compliance-evidence-binding.test.js test/compliance-evidence-signing.test.js test/compliance-file-contains.test.js test/label-isolation.test.js test/evidence-grade-wording.test.js test/llm-model-status.test.js test/egress-policy-constraints.test.js test/egress-redact.test.js test/egress-audit.test.js test/egress-approved-providers.test.js test/family-registry.test.js test/coverage-strength.test.js test/framework-provenance.test.js test/framework-provenance-controlrefs.test.js test/third-party-verification.test.js test/proof-coverage.test.js test/calibration-holdout.test.js test/independent-population-gate.test.js test/catalog-freshness.test.js test/incremental-parity.test.js test/surface-smoke.test.js test/fix-coverage.test.js test/raw-source-carveout.test.js test/mlbom-conformance.test.js test/deploy-gate-replay.test.js test/sbom-conformance.test.js test/unscored-claims.test.js test/mcp-rug-pull.test.js test/agent-boundary-taint.test.js test/confinement-adversarial.test.js test/comment-strip-cost.test.js test/reachability-claim.test.js test/entrypoint-breadth.test.js test/dep-file-admission.test.js test/custom-rules-freshness.test.js test/posture/provenance-schema.test.js test/posture/provenance-cache.test.js test/helpers/build-git-fixture.test.js test/posture/provenance-git-evidence.test.js test/posture/provenance-dag-walk.test.js test/posture/provenance-confidence.test.js test/posture/provenance-predicate-replay.test.js test/posture/provenance-origin-resolver.test.js test/posture/provenance-ai-authorship.test.js test/posture/provenance-branch-entry.test.js test/posture/provenance-evidence-attribution.test.js test/posture/provenance-lifecycle.test.js test/posture/provenance-missing-control-resolver.test.js test/posture/provenance-missing-control-wiring.test.js test/posture/provenance-coordinator.test.js test/posture/provenance-sca-origin.test.js test/posture/provenance-transitive-sca.test.js test/posture/provenance-coordinator-sca.test.js test/posture/provenance-providers.test.js test/posture/provenance-evidence-bundle.test.js test/posture/provenance-repo-lineage.test.js test/posture/provenance-secrets-logic.test.js test/cli/provenance-flags.test.js test/cli/attest-provenance.test.js test/cli/attest-obligations.test.js test/cli/models.test.js test/cli/setup-llm.test.js test/cli/fix-retry.test.js test/cli/compliance-walkthrough-lineage.test.js test/cli/dataflow-export-privacy.test.js test/cli/dataflow-export-briefing.test.js test/cli/lineage-snapshot-persist.test.js test/cli/dataflow-diff.test.js test/cli/dataflow-watch.test.js test/cli/dataflow-recipients.test.js test/cli/dataflow-coverage.test.js test/security/provenance-safety.test.js test/security/provenance-injection.test.js test/posture/remediation-ledger.test.js test/posture/assurance-baseline.test.js test/posture/assurance-contracts.test.js test/posture/assurance-config.test.js test/evidence-issuer.test.js test/load-factor.test.js test/fleet/job-store.test.js test/fleet/enterprise-graph.test.js test/fleet/discover-edges.test.js test/fleet/code-boundaries.test.js test/fleet/job-runner.test.js test/fleet/accounting.test.js test/fleet/fleet-org-cli.test.js test/eval-lab/dataset-neutralize.test.js test/eval-lab/arms-score-stats.test.js test/eval-lab/run-report.test.js test/eval-lab/router.test.js test/eval-lab/arm-ollama.test.js test/eval-lab/import-independent.test.js test/cli/eval-lab-cli.test.js test/dnr/ir-and-outputs.test.js test/dnr/logs-and-hunt.test.js test/dnr/window-store-view.test.js test/dnr/exploit-correlation.test.js test/cli/dnr-cli.test.js test/proof-fabric/core.test.js test/proof-fabric/container.test.js test/proof-fabric/generate.test.js test/proof-fabric/siblings.test.js test/proof-fabric/generate-python.test.js test/proof-fabric/generate-haskell.test.js test/proof-fabric/generate-haskell-widened.test.js test/cli/proof-lifecycle-demo.test.js test/mcp-proof.test.js test/proof-fabric/fix-store-runner.test.js test/proof-fabric/fixtures.test.js test/cli/proof-fabric-cli.test.js test/rule-compiler/core.test.js test/rule-compiler/gates.test.js test/rule-compiler/ci-regression.test.js test/rule-compiler/synthesis.test.js test/rule-compiler/structure.test.js test/cli/rule-compiler-cli.test.js test/fleet/fleet-graph.test.js test/fleet/fleet-manifest.test.js test/fleet/fleet-cli.test.js test/artifact/safe-tar.test.js test/artifact/image-archive.test.js test/artifact/filesystem.test.js test/artifact/layer-secrets.test.js test/artifact/inventory.test.js test/artifact/vuln-correlate.test.js test/artifact/signature.test.js test/artifact/provenance-graph.test.js test/artifact/mismatch.test.js test/artifact/vex.test.js test/artifact/registry.test.js test/artifact/sources-cosign-evidence.test.js test/cli/artifact-sources-cli.test.js test/cli/artifact-provenance-cli.test.js test/witness-bundle.test.js",
|
|
90
|
+
"test:posture": "node --test test/contracts/finding-provenance.contract.test.js test/contracts/root-cause-sweep.contract.test.js test/contracts/model-validation.contract.test.js test/contracts/agentic-discovery.contract.test.js test/contracts/local-models.contract.test.js test/contracts/dependency-finding.contract.test.js test/contracts/taint-flow.contract.test.js test/contracts/runtime-corroboration.contract.test.js test/compliance-coverage.test.js test/contracts/blast-radius.contract.test.js test/contracts/federation.contract.test.js test/contracts/eval-lab-report.contract.test.js test/contracts/fleet.contract.test.js test/contracts/rule-compiler.contract.test.js test/contracts/release-assurance.contract.test.js test/contracts/dnr.contract.test.js test/contracts/strategic-metrics.contract.test.js test/contracts/exploit-proof.contract.test.js test/contracts/artifact-provenance.contract.test.js test/dnr/artifact-join.test.js test/rule-pack-signing.test.js test/threat-model.test.js test/git-hardening.test.js test/privacy-framework.test.js test/material-change.test.js test/drift.test.js test/scorecard.test.js test/accuracy-scorecard.test.js test/scorecard-gate.test.js test/predeploy-gate.test.js test/release-check.test.js test/pre-push-gate.test.js test/dependency-currency.test.js test/package-contents-check.test.js test/gate-verdict-cache.test.js test/run-unit-tests.test.js test/temp-leak-guard.test.js test/release-workflow.test.js test/release-workflow-structure.test.js test/independent-population.test.js test/why-missed.test.js test/independent-scoring.test.js test/evidence-bundle.test.js test/obligation-evidence-pack.test.js test/policy-bundle.test.js test/discovery-memory.test.js test/mttr.test.js test/license-policy.test.js test/aibom.test.js test/sbom.test.js test/api-inventory.test.js test/iam-policy.test.js test/container.test.js test/container-runtime.test.js test/image-packages.test.js test/kev.test.js test/dep-confusion.test.js test/sca-deprecated.test.js test/sca-batch.test.js test/composite-risk.test.js test/epss-enrich.test.js test/sca-coverage.test.js test/gradle-deps.test.js test/sca-route-reachable.test.js test/sca-policy.test.js test/sca-verdict.test.js test/install-script.test.js test/sca-linked-findings.test.js test/packs.test.js test/flow-narration.test.js test/regression-test-gen.test.js test/deterministic-fix.test.js test/falsification.test.js test/verification-separation.test.js test/verification-independence.test.js test/candidate-qualification.test.js test/logic-claims.test.js test/attestation.test.js test/verify-attestation-cli.test.js test/comparison.test.js test/determinism-cross-machine.test.js test/fix-honesty-gate.test.js test/model-routing.test.js test/root-cause-sweep.test.js test/entrypoint-inventory.test.js test/relevance.test.js test/untrusted.test.js test/agent-hardening.test.js test/rule-synthesis.test.js test/policy-gate.test.js test/agents-memory.test.js test/cve-lookup.test.js test/cve-alert-daemon.test.js test/fix-verify-loop.test.js test/fix-verify-tests.test.js test/fix-acceptance.test.js test/exploitability-probability.test.js test/history-scan.test.js test/viral-features.test.js test/viral-v074.test.js test/state-dir.test.js test/ignore-pragma.test.js test/license-graph.test.js test/secret-live-check.test.js test/attack-taxonomy.test.js test/triage-memory.test.js test/triage-memory-scoped.test.js test/sibling-queue.test.js test/pr-augment.test.js test/chat-batch2.test.js test/chat-batch3.test.js test/chat-batch4.test.js test/chat-batch5.test.js test/chat-batch6.test.js test/risk-scenario-disclosure.test.js test/egress-policy.test.js test/egress-profile.test.js test/mcp-approval-binding.test.js test/egress-transport.test.js test/local-preset-callers.test.js test/egress-policy-completeness.test.js test/egress-policy-integration.test.js test/router.test.js test/legacy-alias-redirect.test.js test/cache-economics.test.js test/coverage-report.test.js test/corpus-status.test.js test/provenance.test.js test/secret-history.test.js test/execution-proof.test.js test/fix-metrics.test.js test/corpus-enroll.test.js test/prove-findings.test.js test/corpus-match.test.js test/corpus-provenance.test.js test/learning-quorum.test.js test/llm-cache-integrity.test.js test/scope/inventory.test.js test/scope/readtree-scope.test.js test/scope/cli-scope.test.js test/scope/scope-evidence.test.js test/scope/watch-scope.test.js test/workflow-flow.test.js test/oidc-trust.test.js test/haskell-coverage/coverage.test.js test/validation-disposition.test.js test/claim-groups.test.js test/validation-bounded-context.test.js test/evidence-record.test.js test/report-disposition-view.test.js test/sca-basis.test.js test/proof-artifact.test.js test/providers.test.js test/fleet.test.js test/autopilot.test.js test/autopilot-cli.test.js test/verifier-independence.test.js test/integrity-legacy-key.test.js test/suppression-visibility.test.js test/cost-ceiling.test.js test/local-endpoint.test.js test/ollama-provider.test.js test/ollama-capabilities.test.js test/ollama-offline-egress.test.js test/ollama-fix-proposal.test.js test/ollama-explain-proposal.test.js test/ollama-poc-proposal.test.js test/ollama-model-probe.test.js test/ollama-agent-tools.test.js test/ollama-agent-loop.test.js test/ollama-e2e.test.js test/ollama-oom-feedback.test.js test/ollama-doc-drift.test.js test/model-trust.test.js test/vuln-archaeology.test.js test/scan-checkpoint.test.js test/llm-redact.test.js test/world-class-batch2.test.js test/api-contract-scope.test.js test/world-class-modules.test.js test/privacy-ir-adapter.test.js test/privacy-taxonomy.test.js test/privacy-sink-policy.test.js test/privacy-governance.test.js test/privacy-inventory.test.js test/integration-end-to-end.test.js test/streak-cli-wiring.test.js test/stack-playbook.test.js test/machine-output-flag.test.js test/stdout-flush.test.js test/format-determinism.test.js test/only-flag-channels.test.js test/confidence.test.js test/security-trend.test.js test/calibration-drift.test.js test/validator-metrics.test.js test/clustering-ir-taint-line.test.js test/concurrency-cwe.test.js test/compliance-mapping-liveness.test.js test/module-artifact-liveness.test.js test/supply-chain-provenance-completeness.test.js test/compliance-severity-threshold.test.js test/compliance-severity-policy.test.js test/compliance-evidence-binding.test.js test/compliance-evidence-signing.test.js test/compliance-file-contains.test.js test/label-isolation.test.js test/evidence-grade-wording.test.js test/llm-model-status.test.js test/egress-policy-constraints.test.js test/egress-redact.test.js test/egress-audit.test.js test/egress-approved-providers.test.js test/family-registry.test.js test/coverage-strength.test.js test/framework-provenance.test.js test/framework-provenance-controlrefs.test.js test/third-party-verification.test.js test/proof-coverage.test.js test/calibration-holdout.test.js test/independent-population-gate.test.js test/catalog-freshness.test.js test/incremental-parity.test.js test/surface-smoke.test.js test/fix-coverage.test.js test/raw-source-carveout.test.js test/mlbom-conformance.test.js test/deploy-gate-replay.test.js test/sbom-conformance.test.js test/unscored-claims.test.js test/mcp-rug-pull.test.js test/agent-boundary-taint.test.js test/confinement-adversarial.test.js test/comment-strip-cost.test.js test/reachability-claim.test.js test/entrypoint-breadth.test.js test/dep-file-admission.test.js test/custom-rules-freshness.test.js test/posture/provenance-schema.test.js test/posture/provenance-cache.test.js test/helpers/build-git-fixture.test.js test/posture/provenance-git-evidence.test.js test/posture/provenance-dag-walk.test.js test/posture/provenance-confidence.test.js test/posture/provenance-predicate-replay.test.js test/posture/provenance-origin-resolver.test.js test/posture/provenance-ai-authorship.test.js test/posture/provenance-branch-entry.test.js test/posture/provenance-evidence-attribution.test.js test/posture/provenance-lifecycle.test.js test/posture/provenance-missing-control-resolver.test.js test/posture/provenance-missing-control-wiring.test.js test/posture/provenance-coordinator.test.js test/posture/provenance-sca-origin.test.js test/posture/provenance-transitive-sca.test.js test/posture/provenance-coordinator-sca.test.js test/posture/provenance-providers.test.js test/posture/provenance-evidence-bundle.test.js test/posture/provenance-repo-lineage.test.js test/posture/provenance-secrets-logic.test.js test/cli/provenance-flags.test.js test/cli/attest-provenance.test.js test/cli/attest-obligations.test.js test/cli/models.test.js test/cli/setup-llm.test.js test/cli/fix-retry.test.js test/cli/compliance-walkthrough-lineage.test.js test/cli/dataflow-export-privacy.test.js test/cli/dataflow-export-briefing.test.js test/cli/lineage-snapshot-persist.test.js test/cli/dataflow-diff.test.js test/cli/dataflow-watch.test.js test/cli/dataflow-recipients.test.js test/cli/dataflow-coverage.test.js test/security/provenance-safety.test.js test/security/provenance-injection.test.js test/posture/remediation-ledger.test.js test/posture/assurance-baseline.test.js test/posture/assurance-contracts.test.js test/posture/assurance-config.test.js test/evidence-issuer.test.js test/load-factor.test.js test/fleet/job-store.test.js test/fleet/enterprise-graph.test.js test/fleet/discover-edges.test.js test/fleet/code-boundaries.test.js test/fleet/job-runner.test.js test/fleet/accounting.test.js test/fleet/fleet-org-cli.test.js test/eval-lab/dataset-neutralize.test.js test/eval-lab/arms-score-stats.test.js test/eval-lab/run-report.test.js test/eval-lab/router.test.js test/eval-lab/arm-ollama.test.js test/eval-lab/import-independent.test.js test/cli/eval-lab-cli.test.js test/dnr/ir-and-outputs.test.js test/dnr/logs-and-hunt.test.js test/dnr/auth-truth-object-authz.test.js test/pilot/two-tenant-records.test.js test/pilot/app-to-cloud-and-db.test.js test/pilot/candidate-packet.test.js test/dnr/window-store-view.test.js test/dnr/exploit-correlation.test.js test/cli/dnr-cli.test.js test/proof-fabric/core.test.js test/proof-fabric/container.test.js test/proof-fabric/generate.test.js test/proof-fabric/siblings.test.js test/proof-fabric/generate-python.test.js test/proof-fabric/generate-haskell.test.js test/proof-fabric/generate-haskell-widened.test.js test/cli/proof-lifecycle-demo.test.js test/mcp-proof.test.js test/proof-fabric/fix-store-runner.test.js test/proof-fabric/fixtures.test.js test/cli/proof-fabric-cli.test.js test/rule-compiler/core.test.js test/rule-compiler/gates.test.js test/rule-compiler/ci-regression.test.js test/rule-compiler/synthesis.test.js test/rule-compiler/structure.test.js test/cli/rule-compiler-cli.test.js test/fleet/fleet-graph.test.js test/fleet/fleet-manifest.test.js test/fleet/fleet-cli.test.js test/artifact/safe-tar.test.js test/artifact/image-archive.test.js test/artifact/filesystem.test.js test/artifact/layer-secrets.test.js test/artifact/inventory.test.js test/artifact/vuln-correlate.test.js test/artifact/signature.test.js test/artifact/provenance-graph.test.js test/artifact/mismatch.test.js test/artifact/vex.test.js test/artifact/registry.test.js test/artifact/sources-cosign-evidence.test.js test/cli/artifact-sources-cli.test.js test/cli/artifact-provenance-cli.test.js test/witness-bundle.test.js test/scope/watch-cli.test.js",
|
|
91
91
|
"test:dataflow": "node --test test/privacy-catalog.test.js test/privacy-deep-walker.test.js test/privacy-deep-e2e.test.js test/container-taint.test.js test/stored-taint-families.test.js test/py-annotation-sources.test.js test/fn-reach.test.js test/deep-taint.test.js test/calibration.test.js test/holdout-eval.test.js test/cross-lang-meta.test.js test/cross-lang-queues.test.js test/phase5-xlang.test.js test/phase5-coverage.test.js test/phase6-taint.test.js test/llm-validator-consistency.test.js test/llm-validator-default-on.test.js test/llm-validator-preset.test.js test/parser-py-cst.test.js test/chrome-probe.test.js test/parser-cs-kt.test.js test/parser-cs-annotations.test.js test/parser-cs-control-flow.test.js test/parser-kt-control-flow.test.js test/parser-js-annotations.test.js test/parser-java-annotations.test.js test/parser-java-control-flow.test.js test/parser-java-calls.test.js test/parser-go.test.js test/parser-rust.test.js test/rust-taint-flow.test.js test/parser-php-rb.test.js test/parser-php-control-flow.test.js test/interproc-k2.test.js test/proven-clean.test.js test/backward-default.test.js test/incremental-cache.test.js test/string-regex-lattice.test.js test/closure-capture.test.js test/points-to.test.js test/type-stubs.test.js test/soft-taint.test.js test/ifds.test.js test/symbolic-exec-proof.test.js test/ifds-summary-edges.test.js test/stub-aware-filter.test.js test/cross-repo.test.js test/proof-gate.test.js test/layer-recall.test.js test/java-taint-flow.test.js test/kt-taint-flow.test.js test/sanitizer-typed-flow.test.js test/sanitizer-gate-unit.test.js test/proof-safe.test.js test/collection-taint.test.js test/kcfa-context.test.js test/kcfa-callstring.test.js test/flow-parity.test.js test/callgraph-resolve.test.js test/import-reachability.test.js test/ir-stats.test.js test/parser-cpp.test.js test/parser-js-decorators.test.js test/parser-js-if-else-cfg.test.js test/cpp-integration.test.js test/engine-reconnect.test.js test/phase2-scoping.test.js test/engine-recall.test.js test/catalog-annotation-source.test.js test/catalog-cs-p1.test.js test/catalog-expanded.test.js test/builtin-summaries.test.js test/interproc-mutation-crash.test.js test/mutated-param-taint.test.js test/return-sink-check.test.js test/higher-order-inline-callback.test.js test/interproc-findings-discard.test.js test/runscan-deep-option.test.js test/summary-cache-convergence.test.js test/parser-rb-calls.test.js test/parser-rb-module-level.test.js test/balanced-call.test.js test/destructuring-taint.test.js test/computed-member-taint.test.js test/string-interpolation-taint.test.js test/dataflow-deadcode-severity.test.js test/catalog-dotted-callee-lookup.test.js test/builtin-summary-family-blind-kill.test.js test/deep-mode-annotator-pipeline.test.js test/receiver-type-and-nested-calls.test.js test/member-write-and-loop-taint.test.js test/parser-py-module-level.test.js test/parser-php-module-level.test.js test/r14b-module-level-e2e.test.js test/annotation-taint-engine.test.js test/interproc-nested-call-taint.test.js test/catalog-xpath-injection.test.js test/catalog-ldap-injection.test.js test/catalog-xxe.test.js test/catalog-response-splitting.test.js test/catalog-code-injection.test.js test/parser-rb-control-flow.test.js test/catalog-ruby-p1.test.js test/callee-receiver-taint.test.js test/catalog-command-injection-p4.test.js test/catalog-xss-p4.test.js test/catalog-path-ssrf-p3.test.js test/catalog-ai-model-provider-precision.test.js test/catalog-orm-write.test.js test/dataflow/provenance-pipeline-integration.test.js test/dataflow-progress.test.js test/scan-progress.test.js test/sard-leakage-pipeline.test.js test/sard-split-scoring.test.js test/sard-llm-isolation.test.js test/sard-mutation-adversarial.test.js test/sard-baseline-adaptive-tolerance.test.js test/sard-independent-holdout.test.js test/sard-flow-aware-scoring.test.js test/sard-macro-score-support-floor.test.js test/sard-php-split.test.js test/parser-java-nary-concat.test.js test/sard-naive-baseline.test.js test/field-taint-cross-method.test.js test/field-taint-engine-unit.test.js test/coercion-sanitizer-kill.test.js test/constant-propagation-path-sensitivity.test.js test/parser-java-assignments.test.js test/catalog-java-sard.test.js test/parser-cs-juliet-shapes.test.js test/catalog-cs-sard-p2.test.js test/sard-cwe-key-merge.test.js test/parser-php-backtick.test.js test/parser-php-include.test.js test/php-include-merge.test.js test/parser-php-array-field-taint.test.js test/parser-php-cond-assign.test.js test/parser-rust-redos.test.js test/multi-sink-taint-chain.test.js test/static-field-cross-class-call-string.test.js test/regex-guard-narrowing.test.js test/object-instance-field-taint.test.js test/param-type-inference.test.js test/smt-path-feasibility.test.js test/cross-service-taint.test.js test/dataflow-expr-taint-scaling.test.js test/evaluation/guard-dominance.test.js test/evaluation/engine-mechanisms.test.js test/rx-exec-receiver.test.js test/incremental-dependency.test.js test/incremental-integrity.test.js test/demand-query.test.js test/ir-cache.test.js test/canonicalize-parity.test.js test/dataflow-source-attribution.test.js",
|
|
92
92
|
"test:mcp": "node --test test/mcp.test.js test/mcp-apply-fix-multifile.test.js test/mcp-protocol-smoke.test.js test/mcp-audit.test.js test/audit-cli.test.js test/mcp-scratchpad.test.js test/mcp-offload.test.js test/sca-upgrade.test.js test/lsp-server.test.js test/mcp-dataflow-tools.test.js test/cli/governance-propose-edit.test.js test/cli/remediation-open-update.test.js test/cli/remediation-verify-reopen.test.js test/cli/dataflow-observations.test.js test/cli/federate-declare-list.test.js test/capabilities/tools.test.js",
|
|
93
93
|
"test:report": "node --test test/report-scan-invariants.test.js test/junit.test.js test/ci.test.js test/poc-generator.test.js test/verifier.test.js test/verifier-target.test.js test/annotator-errors.test.js test/git-history-batch.test.js test/default-scan-drift.test.js test/bundle-optional-deps.test.js test/scan-health.test.js test/finding-schema.test.js test/pipeline/finding-schema-provenance.test.js test/evidence-provenance.test.js test/report/provenance-output.test.js test/report/provenance-format-parity.test.js test/legacy-compat.test.js test/annotator-runner.test.js test/detector-runner.test.js test/detector-errors.test.js test/analyzer-supervisor.test.js test/cascade-worker-pool.test.js test/cascade-pool-wiring.test.js test/coverage-ledger.test.js test/coverage-ledger-completeness.test.js test/assurance-mode.test.js test/artifact-registry.test.js test/artifact-registry-completeness.test.js test/retention-policy.test.js test/state-lifecycle-report.test.js test/legal-hold.test.js test/production-feedback.test.js test/calibration-feedback.test.js test/encryption-provider.test.js test/grader-calibration.test.js test/pr-delta-gate.test.js test/vex.test.js test/report-render.test.js test/oscal-conformance.test.js test/cli-fix-apply.test.js test/apply-fix-service.test.js test/high-impact-approval-gate.test.js test/approver-registry.test.js test/suppression-exceptions.test.js test/fix-history.test.js test/producer-registry.test.js test/producer-collector.test.js test/enrichment-completion.test.js",
|
|
94
94
|
"test:lineage": "node --test test/lineage/analysis-completion.test.js test/lineage/schema.test.js test/lineage/ids.test.js test/lineage/protection.test.js test/lineage/classification.test.js test/lineage/validate.test.js test/lineage/json-schema-parity.test.js test/lineage/flagship-fixture.test.js test/lineage/flagship-fixture-semantics.test.js test/lineage/field-identity.test.js test/lineage/engine-expr-resolver.test.js test/lineage/engine-walker.test.js test/lineage/engine-integration.test.js test/lineage/engine-receiver-identity.test.js test/lineage/summaries.test.js test/lineage/driver.test.js test/lineage/engine-provenance.test.js test/lineage/engine-provenance-interprocedural.test.js test/lineage/path-store.test.js test/lineage/path-query.test.js test/lineage/flow-grade.test.js test/lineage/source-registry.test.js test/lineage/sink-registry.test.js test/lineage/transform-catalog.test.js test/lineage/handling-analyzer.test.js test/lineage/registry-real-code.test.js test/lineage/source-seeding.test.js test/lineage/seeding-across-calls.test.js test/lineage/boundary-join.test.js test/contracts/code-boundaries.contract.test.js test/lineage/graph-builder.test.js test/lineage/coverage.test.js test/lineage/resolve-destination.test.js test/lineage/queue-detail.test.js test/lineage/index.test.js test/lineage/obligation-mapping.test.js test/lineage/obligation-predicates.test.js test/lineage/obligation-predicates-walkthrough.test.js test/lineage/transit-protection.test.js test/lineage/at-rest-protection.test.js test/lineage/protection-summary.test.js test/lineage/ac01-multi-sink.test.js test/lineage/policy-verdict.test.js test/lineage/governance-refs.test.js test/lineage/export-privacy.test.js test/lineage/export-json.test.js test/lineage/export-csv.test.js test/lineage/decision-story.test.js test/lineage/export-briefing.test.js test/lineage/graph-snapshot.test.js test/lineage/graph-diff.test.js test/lineage/drift-policy.test.js test/lineage/recipient-profile.test.js test/lineage/recipient-registry.test.js test/lineage/recipient-wiring.test.js test/lineage/redact-graph.test.js test/lineage-scan-wiring.test.js test/lineage-artifact-write.test.js test/bench-data-lineage-runner.test.js test/bundle-frontend.test.js test/bundle-frontend-golden.test.js test/generate-html-report.test.js test/export-image.test.js test/lineage/scenario.test.js test/lineage/scenario-engine.test.js test/lineage/scenario-diff.test.js test/lineage/scenario-no-obligation-wiring.test.js test/lineage/impact-assessment.test.js test/lineage/impact-engine.test.js test/lineage/impact-no-obligation-wiring.test.js test/lineage/governance-edit.test.js test/lineage/remediation.test.js test/lineage/runtime-observation.test.js test/lineage/observation-correlation.test.js test/lineage/observation-adapters.test.js test/lineage/observation-store.test.js test/lineage/runtime-corroboration-wiring.test.js test/lineage/cross-repo-link.test.js test/lineage/federation-loader.test.js test/lineage/cross-repo-link-wiring.test.js test/lineage/runtime-assurance.test.js test/lineage/runtime-edge-states.test.js test/lineage/runtime-explorer-view.test.js test/cli/runtime-explorer-cli.test.js test/cli/runtime-identity-cli.test.js test/cli/runtime-twin-cli.test.js test/lineage/cut-planner.test.js test/lineage/scc.test.js test/lineage/scc-solver.test.js test/graph/graph-views.test.js test/lineage/dag07-completion.test.js test/lineage/owned-build.test.js test/dataflow/boundary-propagation.test.js test/lineage/boundary-contract.test.js test/lineage/correlation-v2.test.js test/lineage/path-control-evidence.test.js test/lineage/smt-z3-backend.test.js test/cli/dag-commands.test.js",
|
|
95
95
|
"test:bench-modules": "node --test test/phase4-harness.test.js test/pipeline.test.js test/proof-corpus-lib.test.js test/proof-corpus-runner.test.js",
|
|
96
96
|
"test:server": "node --test test/server/graph-loader.test.js test/server/security.test.js test/server/routes.test.js test/server/http-server.test.js test/server/cmd-explore.test.js test/server/cmd-dataflow-export.test.js test/server/static-assets.test.js test/server/dataflow-scenario-cli.test.js test/server/dataflow-impact-cli.test.js",
|
|
97
|
-
"test:haskell": "node --test test/haskell/haskell-core-families-runner.test.js test/haskell/haskell-project-models.test.js test/haskell/haskell-reachability.test.js test/haskell/haskell-real-code-shapes.test.js test/haskell/haskell-unseen-v5-shapes.test.js test/haskell/haskell-unseen-v4-shapes.test.js test/haskell/haskell-alias-taint.test.js test/haskell/haskell-weak-hash-names.test.js test/haskell/haskell-models-extended.test.js test/haskell/haskell-rules-extended.test.js test/haskell/haskell-injection.test.js test/haskell/haskell-ir.test.js test/haskell/haskell-manifests.test.js test/haskell/haskell-parser.test.js test/haskell/haskell-remediation.test.js test/haskell/haskell-remediation-0190.test.js test/haskell/haskell-remediation-kdf.test.js test/haskell/haskell-remediation-html-text.test.js test/haskell/haskell-remediation-scotty-body.test.js test/haskell/haskell-remediation-entropy.test.js test/haskell/haskell-remediation-text-command.test.js test/haskell/haskell-remediation-path-contain.test.js test/haskell/haskell-remediation-0195-16.test.js test/haskell/haskell-taint-shapes.test.js test/haskell/haskell-real-advisory-shapes.test.js test/haskell/haskell-discovery-shapes.test.js test/haskell/haskell-quasiquote-interp.test.js test/haskell/haskell-record-dot.test.js test/haskell/haskell-global-cell.test.js test/haskell/haskell-syntax-extensions.test.js test/haskell/haskell-rule-precision.test.js test/haskell/haskell-resolved-graph.test.js test/haskell/haskell-sca.test.js test/haskell/haskell-sca-severity.test.js test/haskell/haskell-web-guards.test.js test/haskell/haskell-advisory-feed.test.js test/haskell/haskell-security-rules.test.js test/haskell/haskell-taint.test.js test/haskell/haskell-boundaries.test.js test/haskell/haskell-live-feed-scan.test.js test/haskell/haskell-supply-bounds.test.js test/haskell/haskell-ir-scaling.test.js test/haskell/haskell-boundary-propagation.test.js test/haskell/haskell-generalization.test.js test/haskell/haskell-trust-boundary.test.js test/haskell/haskell-trust-fixed-file.test.js test/haskell/haskell-predictable-random-flow.test.js test/haskell/haskell-comment-invariance.test.js test/haskell/haskell-remediation-classes.test.js test/haskell/haskell-trust-boundary-frameworks.test.js test/haskell/haskell-generic-detectors.test.js",
|
|
97
|
+
"test:haskell": "node --test test/haskell/haskell-core-families-runner.test.js test/haskell/haskell-pilot.test.js test/haskell/haskell-project-models.test.js test/haskell/haskell-reachability.test.js test/haskell/haskell-real-code-shapes.test.js test/haskell/haskell-unseen-v5-shapes.test.js test/haskell/haskell-unseen-v4-shapes.test.js test/haskell/haskell-alias-taint.test.js test/haskell/haskell-weak-hash-names.test.js test/haskell/haskell-models-extended.test.js test/haskell/haskell-rules-extended.test.js test/haskell/haskell-injection.test.js test/haskell/haskell-ir.test.js test/haskell/haskell-manifests.test.js test/haskell/haskell-parser.test.js test/haskell/haskell-remediation.test.js test/haskell/haskell-remediation-0190.test.js test/haskell/haskell-remediation-kdf.test.js test/haskell/haskell-remediation-html-text.test.js test/haskell/haskell-remediation-scotty-body.test.js test/haskell/haskell-remediation-entropy.test.js test/haskell/haskell-remediation-text-command.test.js test/haskell/haskell-remediation-path-contain.test.js test/haskell/haskell-remediation-0195-16.test.js test/haskell/haskell-taint-shapes.test.js test/haskell/haskell-real-advisory-shapes.test.js test/haskell/haskell-discovery-shapes.test.js test/haskell/haskell-quasiquote-interp.test.js test/haskell/haskell-record-dot.test.js test/haskell/haskell-global-cell.test.js test/haskell/haskell-syntax-extensions.test.js test/haskell/haskell-rule-precision.test.js test/haskell/haskell-resolved-graph.test.js test/haskell/haskell-sca.test.js test/haskell/haskell-sca-severity.test.js test/haskell/haskell-web-guards.test.js test/haskell/haskell-advisory-feed.test.js test/haskell/haskell-security-rules.test.js test/haskell/haskell-taint.test.js test/haskell/haskell-boundaries.test.js test/haskell/haskell-live-feed-scan.test.js test/haskell/haskell-supply-bounds.test.js test/haskell/haskell-ir-scaling.test.js test/haskell/haskell-boundary-propagation.test.js test/haskell/haskell-generalization.test.js test/haskell/haskell-trust-boundary.test.js test/haskell/haskell-trust-fixed-file.test.js test/haskell/haskell-predictable-random-flow.test.js test/haskell/haskell-comment-invariance.test.js test/haskell/haskell-remediation-classes.test.js test/haskell/haskell-trust-boundary-frameworks.test.js test/haskell/haskell-generic-detectors.test.js",
|
|
98
98
|
"test:nix": "node --test test/nix/nix-option-types.test.js test/nix/nix-development-shapes.test.js test/nix/nixos-hardening-daemon.test.js test/nix/nixos-hardening-extended.test.js test/nix/nix-build-trust.test.js test/nix/nix-eval-isolation.test.js test/nix/nix-input-inventory.test.js test/nix/nix-parser-ir.test.js test/nix/nix-remediation.test.js test/nix/nix-resolved-closure.test.js test/nix/nix-sca-patches.test.js test/nix/nix-sca-severity.test.js test/nix/nix-haskell-closure-names.test.js test/nix/nix-script-taint.test.js test/nix/nix-secrets-store.test.js test/nix/nixos-hardening.test.js test/nix/nixos-module-resolution.test.js test/nix/nix-fix-multifile.test.js test/nix/nixos-evaluator-forms.test.js test/nix/nix-advisory-feed.test.js test/nix/nix-fix-prewrite.test.js test/nix/nix-boundary-scope.test.js",
|
|
99
99
|
"test:language": "node --test test/bench-haskell-precision.test.js test/bench-independent-haskell-panel.test.js test/language/capability-ledger.test.js test/language/language-accuracy-regression.test.js test/language/language-aibom.test.js test/language/language-assurance.test.js test/language/language-bom.test.js test/language/language-compliance.test.js test/language/language-contracts.test.js test/language/language-corpora-integrity.test.js test/language/language-discovery.test.js test/language/language-doc-coverage.test.js test/language/language-evidence-posture.test.js test/language/language-explorer.test.js test/language/frozen-splits.test.js test/language/language-gap-fixes.test.js test/language/language-gap-fixes-2.test.js test/language/language-governance.test.js test/language/language-integrations.test.js test/language/language-llm-agent.test.js test/language/language-local-ai.test.js test/language/language-parity-haskell.test.js test/language/language-polyglot-bridges.test.js test/language/language-privacy-lineage.test.js test/language/language-proof-remediation.test.js test/language/language-report-formats.test.js test/language/language-secrets.test.js test/language/language-trust-boundary.test.js",
|
|
100
100
|
"test:language-stress": "node --test --test-concurrency=1 test/language/language-stress-offline.test.js",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"bench:language-support:check": "node ../bench/language-support/check.mjs",
|
|
103
103
|
"bench:live-feed": "node ../bench/live-feed/run.mjs",
|
|
104
104
|
"bench:language-support:perf": "node ../bench/language-support/perf.mjs",
|
|
105
|
-
"test:evaluation": "node --test test/evaluation/protocol.test.js test/evaluation/grouping.test.js test/evaluation/labels.test.js test/evaluation/custody.test.js test/evaluation/runner.test.js test/evaluation/gates-scorecard.test.js test/evaluation/reporting.test.js test/evaluation/why-missed.test.js test/evaluation/guard-dominance.test.js test/evaluation/engine-mechanisms.test.js test/evaluation/release-gate.test.js test/evaluation/publication.test.js",
|
|
105
|
+
"test:evaluation": "node --test test/evaluation/protocol.test.js test/evaluation/grouping.test.js test/evaluation/labels.test.js test/evaluation/custody.test.js test/evaluation/runner.test.js test/evaluation/gates-scorecard.test.js test/evaluation/reporting.test.js test/evaluation/why-missed.test.js test/evaluation/scorer-reconciliation.test.js test/evaluation/guard-dominance.test.js test/evaluation/engine-mechanisms.test.js test/evaluation/release-gate.test.js test/evaluation/publication.test.js",
|
|
106
106
|
"reproduce:mini": "node ../scripts/public-reproduction.mjs",
|
|
107
107
|
"reproduce:routing": "node ../scripts/routing-replay.mjs",
|
|
108
108
|
"verification:patch-example": "node ../scripts/patch-replay-example.mjs",
|
|
@@ -122,12 +122,13 @@
|
|
|
122
122
|
"test:release-closure": "node --test test/release-closure/closure-plan.test.js test/release-closure/closure-record.test.js test/release-closure/compatibility.test.js test/release-closure/rollout-stages.test.js test/release-closure/migration-readers.test.js test/release-closure/rollback.test.js test/release-closure/wrappers.test.js test/release-closure/final-closure.test.js test/release-closure/final-closure-controller.test.js test/release-closure/runner-hardening.test.js test/release-closure/remote-attestation.test.js test/release-closure/closure-parallel.test.js",
|
|
123
123
|
"release:closure:check": "node ../scripts/release-closure.mjs --run",
|
|
124
124
|
"release:closure:static": "node ../scripts/release-closure.mjs --static",
|
|
125
|
+
"pilot:qualify": "node ../bench/threat-model-pilot/qualify.mjs",
|
|
125
126
|
"test:documentation": "node --test test/documentation/drift-check.test.js test/documentation/generated-pages.test.js test/documentation/scope-and-examples.test.js test/documentation/policy-cards.test.js test/documentation/operations-and-review.test.js",
|
|
126
127
|
"test:capabilities": "node --test test/capabilities/manifest.test.js test/capabilities/filesystem.test.js test/capabilities/exec.test.js test/capabilities/network.test.js test/capabilities/canary.test.js test/capabilities/tools.test.js test/capabilities/recovery.test.js test/capabilities/receipts.test.js test/capabilities/adversarial.test.js test/capabilities/linux-enforcement.test.js test/supervise-async-sweep.test.js",
|
|
127
128
|
"test:verification": "node --test test/verification/verification-record.test.js test/verification/oracle-adapters.test.js test/verification/replay-manifest.test.js test/verification/patch-negative.test.js test/verification/non-taint-classes.test.js test/verification/interface-equivalence.test.js test/verification/advisory-gating.test.js test/verification/oracle-conformance.test.js",
|
|
128
|
-
"test:deployment": "node --test test/deployment/boundary-graph.test.js test/deployment/config-adapters.test.js test/deployment/trace-correlation.test.js test/deployment/cross-repo.test.js test/deployment/attack-paths.test.js test/deployment/drift.test.js test/deployment/boundary-presentation.test.js test/deployment/differentiation-ablation.test.js test/deployment/boundaries-cli.test.js",
|
|
129
|
+
"test:deployment": "node --test test/deployment/boundary-graph.test.js test/deployment/config-adapters.test.js test/deployment/trace-correlation.test.js test/deployment/cross-repo.test.js test/deployment/attack-paths.test.js test/deployment/iam-actions-and-limits.test.js test/deployment/proof-binding.test.js test/deployment/drift.test.js test/deployment/boundary-presentation.test.js test/deployment/differentiation-ablation.test.js test/deployment/boundaries-cli.test.js",
|
|
129
130
|
"test:portfolio": "node --test test/portfolio/manifest.test.js test/portfolio/bundle.test.js test/portfolio/signing.test.js test/portfolio/work-units.test.js test/portfolio/resume.test.js test/portfolio/scheduler.test.js test/portfolio/progress.test.js test/portfolio/retention.test.js test/portfolio/backend.test.js",
|
|
130
|
-
"test:invariants": "node --test test/invariants/invariant-schema.test.js test/invariants/invariant-lifecycle.test.js test/invariants/invariant-scenarios.test.js test/invariants/business-state-oracle.test.js test/invariants/scenario-shrinking.test.js test/invariants/invariant-repair.test.js test/invariants/business-coverage.test.js test/invariants/invariant-ablation.test.js",
|
|
131
|
+
"test:invariants": "node --test test/invariants/invariant-schema.test.js test/invariants/invariant-lifecycle.test.js test/invariants/invariant-scenarios.test.js test/invariants/business-state-oracle.test.js test/invariants/scenario-shrinking.test.js test/invariants/invariant-repair.test.js test/invariants/approval-workflow.test.js test/invariants/business-coverage.test.js test/invariants/invariant-ablation.test.js",
|
|
131
132
|
"bench:invariant-ablation": "node ../scripts/invariant-ablation.mjs",
|
|
132
133
|
"verification:conformance:check": "node ../scripts/verification-conformance-check.mjs",
|
|
133
134
|
"verification:conformance:static": "node ../scripts/verification-conformance-check.mjs --static",
|
package/src/egress/policy.js
CHANGED
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
// functionality nobody configured it to disable.
|
|
66
66
|
|
|
67
67
|
import * as fs from 'node:fs';
|
|
68
|
+
import * as crypto from 'node:crypto';
|
|
68
69
|
import { load as loadYaml } from '../util/yaml.js';
|
|
69
70
|
import { statePath } from '../posture/state-dir.js';
|
|
70
71
|
import { isLoopbackUrl } from '../llm-validator/local-endpoint.js';
|
|
@@ -211,10 +212,87 @@ export function evaluateEgress(ctx = {}) {
|
|
|
211
212
|
return { allowed: false, decision: 'deny', reason: "AGENTIC_SECURITY_EGRESS_DENY=1 is set", provider, policySource: 'env', purpose };
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
return _withProfile(ctx, provider);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ── execution profiles (threat-model PRD FR-06.1, TM-08) ────────────────────────────────────────────────────────────────────────────
|
|
219
|
+
// `AGENTIC_SECURITY_EGRESS_PROFILE=restricted` makes the operator's policy authoritative: the file named by
|
|
220
|
+
// AGENTIC_SECURITY_EGRESS_POLICY must exist and be valid, or every model request is denied before transport. The repository's own
|
|
221
|
+
// `.agentic-security/egress-policy.yml` can only narrow it (a deny in either denies; a repository `mode: allow` cannot widen an
|
|
222
|
+
// operator `local-only`), and an invalid repository file also denies. An unknown profile or an unknown operator mode always fails
|
|
223
|
+
// closed. Outside the restricted profile the documented legacy default holds (no valid policy means allow), and an invalid policy
|
|
224
|
+
// file that is present is reported on the decision instead of being silently ignored. AGENTIC_SECURITY_EGRESS_DENY=1 always wins.
|
|
225
|
+
export const EGRESS_PROFILES = Object.freeze(['standard', 'restricted']);
|
|
226
|
+
export const EGRESS_MODES = Object.freeze(['allow', 'deny', 'local-only']);
|
|
227
|
+
const MAX_POLICY_BYTES = 256 * 1024;
|
|
228
|
+
|
|
229
|
+
/** Read a policy file and classify it: absent | valid | malformed | unreadable | unsupported. Never throws. */
|
|
230
|
+
export function loadPolicyState(fp) {
|
|
231
|
+
if (!fp) return { status: 'absent', doc: null, digest: null };
|
|
232
|
+
let raw;
|
|
233
|
+
// one open, then the size and type checks and the read on that same descriptor: the file cannot be swapped between check and use
|
|
234
|
+
let fd = null;
|
|
235
|
+
try {
|
|
236
|
+
fd = fs.openSync(fp, 'r');
|
|
237
|
+
const st = fs.fstatSync(fd);
|
|
238
|
+
if (!st.isFile() || st.size > MAX_POLICY_BYTES) return { status: 'unreadable', doc: null, digest: null };
|
|
239
|
+
const buf = Buffer.alloc(st.size);
|
|
240
|
+
fs.readSync(fd, buf, 0, st.size, 0);
|
|
241
|
+
raw = buf.toString('utf8');
|
|
242
|
+
} catch (e) { return { status: e && e.code === 'ENOENT' ? 'absent' : 'unreadable', doc: null, digest: null }; }
|
|
243
|
+
finally { if (fd !== null) try { fs.closeSync(fd); } catch { /* already closed */ } }
|
|
244
|
+
const digest = `sha256:${crypto.createHash('sha256').update(raw).digest('hex').slice(0, 16)}`;
|
|
245
|
+
let doc;
|
|
246
|
+
try { doc = loadYaml(raw); } catch { return { status: 'malformed', doc: null, digest }; }
|
|
247
|
+
if (!doc || typeof doc !== 'object' || Array.isArray(doc)) return { status: 'malformed', doc: null, digest };
|
|
248
|
+
if (doc.mode !== undefined && !EGRESS_MODES.includes(doc.mode)) return { status: 'unsupported', doc, digest };
|
|
249
|
+
return { status: 'valid', doc, digest };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function _withProfile(ctx, provider) {
|
|
253
|
+
const purpose = ctx.purpose ?? 'unknown';
|
|
254
|
+
const profile = process.env.AGENTIC_SECURITY_EGRESS_PROFILE || 'standard';
|
|
214
255
|
const envMode = process.env.AGENTIC_SECURITY_EGRESS_MODE;
|
|
215
|
-
const
|
|
256
|
+
const deny = (reasonCode, reason, extra = {}) => ({ allowed: false, decision: 'deny', reason, reasonCode, provider, policySource: 'operator', purpose, profile, enforcement: 'enforced', ...extra });
|
|
257
|
+
if (!EGRESS_PROFILES.includes(profile)) return deny('profile-unknown', 'the egress profile set by the operator is not recognised, so every request is denied');
|
|
258
|
+
if (envMode !== undefined && envMode !== '' && !EGRESS_MODES.includes(envMode)) return deny('operator-mode-unknown', 'the egress mode set by the operator is not recognised, so every request is denied');
|
|
259
|
+
let repoPath = null;
|
|
260
|
+
try { repoPath = statePath(ctx.scanRoot, POLICY_FILE); } catch { repoPath = null; }
|
|
261
|
+
const repo = loadPolicyState(repoPath);
|
|
262
|
+
|
|
263
|
+
if (profile === 'restricted') {
|
|
264
|
+
const op = loadPolicyState(process.env.AGENTIC_SECURITY_EGRESS_POLICY || null);
|
|
265
|
+
const policyState = { operator: op.status, repository: repo.status };
|
|
266
|
+
if (op.status !== 'valid') return deny(`operator-policy-${op.status}`, `the restricted profile requires a valid operator egress policy, and it is ${op.status}`, { policyState, policyIdentity: op.digest });
|
|
267
|
+
if (repo.status !== 'valid' && repo.status !== 'absent') return deny(`repository-policy-${repo.status}`, `the repository egress policy is ${repo.status}; under the restricted profile that denies`, { policyState, policyIdentity: op.digest });
|
|
268
|
+
const first = _decideOne(ctx, provider, op.doc, envMode || op.doc.mode || 'allow', envMode ? 'env' : 'operator');
|
|
269
|
+
const stamp = (d) => ({ ...d, reasonCode: d.allowed ? 'allowed' : (d.reasonCode || 'policy-deny'), profile, enforcement: 'enforced', policyState, policyIdentity: op.digest });
|
|
270
|
+
if (!first.allowed) return stamp(first);
|
|
271
|
+
if (repo.status === 'valid') {
|
|
272
|
+
const second = _decideOne(ctx, provider, repo.doc, repo.doc.mode || 'allow', 'config');
|
|
273
|
+
if (!second.allowed) return stamp(second);
|
|
274
|
+
}
|
|
275
|
+
return stamp(first);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const cfg = repo.status === 'valid' ? repo.doc : null;
|
|
216
279
|
const mode = envMode || (cfg && cfg.mode) || 'allow';
|
|
217
280
|
const policySource = envMode ? 'env' : ((cfg && cfg.mode) ? 'config' : 'default');
|
|
281
|
+
const d = _decideOne(ctx, provider, cfg, mode, policySource);
|
|
282
|
+
const invalid = repo.status !== 'valid' && repo.status !== 'absent';
|
|
283
|
+
return {
|
|
284
|
+
...d, reasonCode: d.allowed ? (invalid ? 'allowed-legacy-default' : 'allowed') : (d.reasonCode || 'policy-deny'), profile, enforcement: 'legacy-default', policyState: { repository: repo.status },
|
|
285
|
+
...(invalid ? { configurationWarning: `the repository egress policy is ${repo.status} and was ignored; under the standard profile the legacy default applies (select AGENTIC_SECURITY_EGRESS_PROFILE=restricted to fail closed)` } : {}),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The checks of one policy document, unchanged from before profiles existed. */
|
|
290
|
+
function _decideOne(ctx, provider, cfg, mode, policySource) {
|
|
291
|
+
const {
|
|
292
|
+
purpose = 'unknown', endpoint,
|
|
293
|
+
model = null, role = null, region = null, repository = null,
|
|
294
|
+
path: filePath = null, dataClass = null, contextTokens = null,
|
|
295
|
+
} = ctx;
|
|
218
296
|
|
|
219
297
|
if (mode === 'deny') {
|
|
220
298
|
return { allowed: false, decision: 'deny', reason: "egress mode is 'deny'", provider, policySource, purpose };
|
package/src/engine.js
CHANGED
|
@@ -9691,7 +9691,7 @@ function _deterministicFileTimings(timings) {
|
|
|
9691
9691
|
f.unvalidated = true;
|
|
9692
9692
|
f.validator_verdict = 'unvalidated';
|
|
9693
9693
|
}
|
|
9694
|
-
try { applyHaskellGuards(irFindings, perFile); applyTrustBoundary(irFindings, perFile); try { applyHaskellReachability(irFindings, perFile); } catch (_) { /* the verdict is metadata; the finding stands without it */ } consolidateFlowSinks(irFindings, perFile); annotateUnresolvedTargets(irFindings, perFile); attachEvidenceChains(irFindings, perFile); annotateHaskellFindings(irFindings, fc); annotateHaskellLlm(irFindings, fc); } catch (_) { /* metadata only; the finding stands without it */ }
|
|
9694
|
+
try { applyHaskellGuards(irFindings, perFile, fc); applyTrustBoundary(irFindings, perFile); try { applyHaskellReachability(irFindings, perFile); } catch (_) { /* the verdict is metadata; the finding stands without it */ } consolidateFlowSinks(irFindings, perFile); annotateUnresolvedTargets(irFindings, perFile); attachEvidenceChains(irFindings, perFile); annotateHaskellFindings(irFindings, fc); annotateHaskellLlm(irFindings, fc); } catch (_) { /* metadata only; the finding stands without it */ }
|
|
9695
9695
|
aF.push(...irFindings);
|
|
9696
9696
|
} catch (e) {
|
|
9697
9697
|
// Deep mode is best-effort. A parser blowup in one file shouldn't kill
|
package/src/language/CLAUDE.md
CHANGED
|
@@ -160,7 +160,7 @@ The `unseen` split (unseen-v3) is a **DEVELOPMENT set since 2026-10-26**: its fa
|
|
|
160
160
|
|
|
161
161
|
**The detection suite scores `actionable` findings (since 0.195.9):** a finding at `info`, or one the engine PROVED clean or infeasible (`proof.verdict` `proven-*`: a catalog sanitizer of the sink's family on the path, a dominating guard), is not a detection, the same rule `bench/language-support/lib.mjs` `actionable` already applied elsewhere. Before, `renderHtml (toHtml name)` into a Scotty `html` sink was scored a false positive although the proof gate had labelled it proven-clean. **Disclosure:** while the real-code precision work of 0.195.9 was being investigated, two frozen-holdout path-traversal sources (shapes s0 and s1, both a parameter joined under a fixed directory) were printed and read; no rule was changed to them (both are still findings), but the holdout has been seen by the person who changed the path-wrapper policy, and a reader weighing the holdout's independence should know that.
|
|
162
162
|
|
|
163
|
-
Rules added for the unseen-v5 shapes, pinned both ways in `test/haskell/haskell-unseen-v5-shapes.test.js`: a Servant handler pairs the API's reads with its LAST parameters (`orderServer conn ref`; `haskell-ir.js` `servantEndpointParams` paired from the front and annotated the closure parameter); a `Set-Cookie` header handed to `setHeader`/`addHeader` is judged like a hand-written tuple; a project helper the IR inlined at its call site (`hs.inlinedFrom`) reports a fast password hash or a credential log once, in the helper (`markInlined`, `inlineCtx`, the filter before the return); mwc-random and splitmix are predictable generators (`System.Random.MWC` in `HS_RULE_APIS` so the IR qualifies the names); a function that MAKES a key (`newKey`, `generateApiKey`) is security-shaped, and `code`/`pin`/`otp` is a security value in a function that talks about a reset or a verification (`CONTEXT_CODE_VAR`, `CODE_CONTEXT`); an authentication endpoint (`AUTH_ENDPOINT_PATH`/`_NAME`) is never missing authentication; `X-Session`, `X-Token` and similar project header names are credentials (`CREDENTIAL_HEADER`); a yes/no answer about a credential (`accepted <- checkCredentials attempt`, a comparison, a `logical`, a helper whose returns are such: `returnsYesNo`) carries no credential text, a record built from one logged through another field (`attemptUser attempt`, a `member` of it) is that field, the record logged whole is the credential, and `lastFour`/`takeEnd`/`fingerprint` are masking helpers by name; `pushLogStr(Ln)` is a log sink. In `haskell-guards.js`: a CWE-918 flow whose URL starts from a literal (or a constant bound to one) naming the scheme, the host and a `/`, or whose request is built by http-conduit's modifiers over such a base, is lowered to `info` with `guardNote.kind: fixed-host-request` (`fixedHostRequest`; a record update that sets a host field, or a literal that stops inside the host, is not); `judgeFinding` locates the sink in the CALLEE when the finding was found from a caller (the canonicalise-and-prefix guard in `persistDraft` refutes the flow found from `saveDraft`), and the XSS escaper judgement knows the catalog's HTML escapers and a project helper that uses the parameter receiving the tainted value only under an escaper. Nix (`test/nix/nix-development-shapes.test.js`): `AmbientCapabilities` as one string, `Defaults !authenticate`, a `*File` option handed a `writeText` of a literal (`nix-secret-plaintext`, exposure `store`), a TLS key path on any enabled service (`sslKey`, `sslServerKey`, `keyFile`, ...), and one script-taint finding per rule, line and origin class.
|
|
163
|
+
Rules added for the unseen-v5 shapes, pinned both ways in `test/haskell/haskell-unseen-v5-shapes.test.js`: a Servant handler pairs the API's reads with its LAST parameters (`orderServer conn ref`; `haskell-ir.js` `servantEndpointParams` paired from the front and annotated the closure parameter); a `Set-Cookie` header handed to `setHeader`/`addHeader` is judged like a hand-written tuple; a project helper the IR inlined at its call site (`hs.inlinedFrom`) reports a fast password hash or a credential log once, in the helper (`markInlined`, `inlineCtx`, the filter before the return); mwc-random and splitmix are predictable generators (`System.Random.MWC` in `HS_RULE_APIS` so the IR qualifies the names); a function that MAKES a key (`newKey`, `generateApiKey`) is security-shaped, and `code`/`pin`/`otp` is a security value in a function that talks about a reset or a verification (`CONTEXT_CODE_VAR`, `CODE_CONTEXT`); an authentication endpoint (`AUTH_ENDPOINT_PATH`/`_NAME`) is never missing authentication; `X-Session`, `X-Token` and similar project header names are credentials (`CREDENTIAL_HEADER`); a yes/no answer about a credential (`accepted <- checkCredentials attempt`, a comparison, a `logical`, a helper whose returns are such: `returnsYesNo`) carries no credential text, a record built from one logged through another field (`attemptUser attempt`, a `member` of it) is that field, the record logged whole is the credential, and `lastFour`/`takeEnd`/`fingerprint` are masking helpers by name; `pushLogStr(Ln)` is a log sink. In `haskell-guards.js`: a CWE-918 flow whose URL starts from a literal (or a constant bound to one) naming the scheme, the host and a `/`, or whose request is built by http-conduit's modifiers over such a base, is lowered to `info` with `guardNote.kind: fixed-host-request` (`fixedHostRequest`; a record update that sets a host field, or a literal that stops inside the host, is not); when the WHOLE destination (scheme, host and path) is the literal and the client reaches only the query, headers, body, method or auth (`destinationFixed`), the guard also records a `constant-input` refutation tied to the file's hash, so the disposition is `refuted` (a concatenation, a path setter, a manager or an unknown record field leaves it open: lowered only); `judgeFinding` locates the sink in the CALLEE when the finding was found from a caller (the canonicalise-and-prefix guard in `persistDraft` refutes the flow found from `saveDraft`), and the XSS escaper judgement knows the catalog's HTML escapers and a project helper that uses the parameter receiving the tainted value only under an escaper. Nix (`test/nix/nix-development-shapes.test.js`): `AmbientCapabilities` as one string, `Defaults !authenticate`, a `*File` option handed a `writeText` of a literal (`nix-secret-plaintext`, exposure `store`), a TLS key path on any enabled service (`sslKey`, `sslServerKey`, `keyFile`, ...), and one script-taint finding per rule, line and origin class.
|
|
164
164
|
|
|
165
165
|
Rules added for the unseen-v4 shapes, each pinned both ways in `test/haskell/haskell-unseen-v4-shapes.test.js`: a value READ from the request inside a function (`param`, `strictRequestBody`, `requestHeaders`, any `REQUEST_PROVENANCE` source) is caller text for the partial-function, allocation and bounding rules whatever the function's parameters are; a presence test does not cover a partial call on a value SPLIT or parsed from the tested one (`SPLITTER`), while the same split of the same value does; a relational test on a count bounds the allocation it sizes; a `System.Random` value that reaches the result of a security-shaped function is predictable randomness; a project record parameter with a credential or card field logged whole (`show card`) is sensitive logging, through a masking helper by name it is not; wai-extra `requestSizeCheck` bounds the body read. In `haskell-web.js`: Servant closure arguments before the endpoint's values are paired from the end; a container lookup by the request id (`M.lookup`) is the object selection for BOLA only; BOLA without an authenticated principal needs either a WRITE to the selected object or OWNER EVIDENCE (`OWNER_COL`: a statement names an owner column its WHERE clause does not use; `OWNER_FIELD`: the record the handler works with has an owner field it never reads, where "works with" means another field of that record is read); a Scotty handler typed `ActionM` but registered elsewhere is a route with method `UNKNOWN` (ownership only, never a missing-auth finding); a Yesod `isAuthorized` clause that can answer `AuthenticationRequired` guards; a privileged path whose handler calls into unseen code is a lower-severity missing-auth finding, but a plain write with no visible operation is NOT (23 echo, upload-demo and health-check routes on four real projects). Taint: `Network.Wai.Parse.fileName` is an `upload` source; `Network.Wai.responseLBS`/`responseBuilder` are CWE-79 sinks judged by the header argument (`waiHtmlContext`: `text/html` keeps, another content type lowers to `info`, opaque headers keep with a stated uncertainty); the HTML-escaper judgement follows local bindings, and a definition with no value in it (a read) is the raw origin; a Shakespeare quasi-quote with interpolations is rewritten in place to an application of its interpolated expressions (`hamletInterpolations`, boundary kind `quasiquote-hamlet`, never opaque) so `#{preEscapedToHtml body}` is a sink site and `#{body}` is not. Two shapes stay as they were on purpose: `getArgs` reaching a shell is `operator-controlled` (info), and `fetch url = parseRequest url >>= httpNoBody` stays a finding (a URL wrapper is not an `api-contract`); unseen-v4 labels both the other way, and that is recorded, not decided.
|
|
166
166
|
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// has the prefix. A weak guard is reported as a note on the finding and does not refute it.
|
|
18
18
|
|
|
19
19
|
const CANON_CALLS = new Set(['System.Directory.canonicalizePath', 'System.Directory.makeAbsolute', 'System.FilePath.normalise']);
|
|
20
|
+
import { createHash } from 'node:crypto';
|
|
20
21
|
import { HS_SANITIZERS } from './haskell-models.js';
|
|
21
22
|
// the catalog's HTML escapers (blaze, lucid): the same list the taint catalog is generated from
|
|
22
23
|
const CATALOG_HTML_ESCAPERS = new Set(HS_SANITIZERS.filter((s) => (s.appliesTo || []).includes('xss')).map((s) => `${s.module}.${s.name}`));
|
|
@@ -570,6 +571,11 @@ const REQUEST_BUILDERS = /(?:^|\.)(?:parseRequest|parseRequest_|parseUrlThrow|pa
|
|
|
570
571
|
const REQUEST_MODIFIERS = /(?:^|\.)(?:setRequestQueryString|setRequestQuery|setQueryString|setRequestPath|setRequestBody|setRequestBodyLBS|setRequestBodyJSON|setRequestBodyURLEncoded|setRequestBodyFile|setRequestBodySource|setRequestHeader|setRequestHeaders|addRequestHeader|setRequestMethod|setRequestBasicAuth|setRequestBearerAuth|setRequestIgnoreStatus|setRequestResponseTimeout|setRequestCheckStatus|setRequestManager|urlEncodedBody|applyBasicAuth|applyBearerAuth)$/;
|
|
571
572
|
const PEEL_WRAPPERS = /(?:^|\.)(?:liftIO|pure|return|unpack|pack|fromString|toStrict|fromStrict|encodeUtf8|decodeUtf8|toText|fromText)$/;
|
|
572
573
|
const HOST_FIELD = /^(?:host|port|secure|url|uri|requestHost)$/i;
|
|
574
|
+
// Record fields and modifiers that leave the destination exactly as the literal names it. Anything else on the way (a concatenation, a
|
|
575
|
+
// path setter, a custom manager, which can carry a proxy, an unknown field) leaves the PATH or the route open, and then the finding is
|
|
576
|
+
// only lowered, never refuted.
|
|
577
|
+
const DESTINATION_NEUTRAL_FIELD = /^(?:method|requestHeaders|requestBody|queryString|responseTimeout|checkResponse|redirectCount|decompress|requestVersion|cookieJar)$/;
|
|
578
|
+
const PATH_OPENING_MODIFIER = /(?:^|\.)(?:setRequestPath|setRequestManager)$/;
|
|
573
579
|
|
|
574
580
|
function fixedHostRequest(f, perFile) {
|
|
575
581
|
if (!f || f.cwe !== 'CWE-918') return null;
|
|
@@ -593,6 +599,7 @@ function fixedHostRequest(f, perFile) {
|
|
|
593
599
|
return rets.length === 1 ? rets[0].value : null;
|
|
594
600
|
};
|
|
595
601
|
let evidence = null;
|
|
602
|
+
let open = false;
|
|
596
603
|
const fixed = (e, seen, depth) => {
|
|
597
604
|
if (!e || typeof e !== 'object' || depth > 24) return false;
|
|
598
605
|
if (e.kind === 'literal') { const ok = typeof e.value === 'string' && HOST_ANCHORED.test(e.value); if (ok) evidence = e.value.replace(/^([a-z][a-z0-9+.-]*:\/\/[^/@?#\s]+\/).*$/i, '$1'); return ok; }
|
|
@@ -606,15 +613,16 @@ function fixedHostRequest(f, perFile) {
|
|
|
606
613
|
if (e.kind === 'object' && Array.isArray(e.props)) {
|
|
607
614
|
// a record update: `{ method = "POST" }` joined (as a union) with its base; a field that names the host makes it unknown
|
|
608
615
|
if (e.props.some((p) => HOST_FIELD.test(String(p.key || p.name || '')))) return false;
|
|
616
|
+
if (e.props.some((p) => !DESTINATION_NEUTRAL_FIELD.test(String(p.key || p.name || '')))) open = true;
|
|
609
617
|
return e.object ? fixed(e.object, seen, depth + 1) : true;
|
|
610
618
|
}
|
|
611
|
-
if (e.kind === 'binary' && (e.op === '<>' || e.op === '++' || (e.hs && e.hs.concat))) return fixed(e.left, seen, depth + 1);
|
|
619
|
+
if (e.kind === 'binary' && (e.op === '<>' || e.op === '++' || (e.hs && e.hs.concat))) { open = true; return fixed(e.left, seen, depth + 1); }
|
|
612
620
|
if (e.kind === 'call' && typeof e.callee === 'string') {
|
|
613
621
|
const args = e.args || [];
|
|
614
622
|
if (PEEL_WRAPPERS.test(e.callee) && args.length === 1) return fixed(args[0], seen, depth + 1);
|
|
615
623
|
if (REQUEST_BUILDERS.test(e.callee) && args.length >= 1) return fixed(args[args.length - 1], seen, depth + 1);
|
|
616
|
-
if (REQUEST_MODIFIERS.test(e.callee) && args.length >= 1) return fixed(args[args.length - 1], seen, depth + 1);
|
|
617
|
-
if (/(?:^|\.)(?:<\/>|combine|joinPath)$/.test(e.callee) && args.length === 2) return fixed(args[0], seen, depth + 1);
|
|
624
|
+
if (REQUEST_MODIFIERS.test(e.callee) && args.length >= 1) { if (PATH_OPENING_MODIFIER.test(e.callee)) open = true; return fixed(args[args.length - 1], seen, depth + 1); }
|
|
625
|
+
if (/(?:^|\.)(?:<\/>|combine|joinPath)$/.test(e.callee) && args.length === 2) { open = true; return fixed(args[0], seen, depth + 1); }
|
|
618
626
|
}
|
|
619
627
|
return false;
|
|
620
628
|
};
|
|
@@ -625,10 +633,10 @@ function fixedHostRequest(f, perFile) {
|
|
|
625
633
|
// update alone, which is fixed when it names no host field, so the base branch decides
|
|
626
634
|
if (!fixed(arg, new Set(), 0)) return null;
|
|
627
635
|
}
|
|
628
|
-
return { kind: 'fixed-host-request', base: evidence };
|
|
636
|
+
return { kind: 'fixed-host-request', base: evidence, destinationFixed: !open };
|
|
629
637
|
}
|
|
630
638
|
|
|
631
|
-
export function applyHaskellGuards(findings, perFile) {
|
|
639
|
+
export function applyHaskellGuards(findings, perFile, fileContents = null) {
|
|
632
640
|
const stats = { refuted: 0, weak: 0 };
|
|
633
641
|
for (const f of findings || []) {
|
|
634
642
|
if (!f || f.parser !== 'IR-TAINT') continue;
|
|
@@ -656,6 +664,19 @@ export function applyHaskellGuards(findings, perFile) {
|
|
|
656
664
|
f._fixedHost = true; f.severity = 'info';
|
|
657
665
|
f.controls = [...(f.controls || []), { kind: 'fixed-host-request', evidenceKind: 'source' }];
|
|
658
666
|
f.guardNote = { kind: 'fixed-host-request', reason: `the request's host is fixed by the literal${fh.base ? ` "${fh.base}"` : ''} the URL or base request starts from; the client's text can only choose the path, query or fragment, which is not a server-side request forgery (a path it chooses on that host is still worth a look)` };
|
|
667
|
+
// When the whole destination (scheme, host and path) is the literal and the client's text reaches only the query, headers, body,
|
|
668
|
+
// method or authentication, the claim that the client chooses where the request goes is disproved by the code itself: an
|
|
669
|
+
// evidence-backed refutation, tied to this file's content. A path the client can still choose is lowered only (above).
|
|
670
|
+
const text = fileContents && typeof fileContents[f.file] === 'string' ? fileContents[f.file] : null;
|
|
671
|
+
if (fh.destinationFixed && text !== null) {
|
|
672
|
+
f.refutation = {
|
|
673
|
+
kind: 'constant-input', verifier: 'haskell-guards/fixed-host-request', version: 1,
|
|
674
|
+
// the host goes in the evidence, not the reason: a host name such as `internal.example.com` is not a context excuse
|
|
675
|
+
evidenceRefs: [`${f.file}:${f.line}`, ...(fh.base ? [`destination:${fh.base}`] : [])],
|
|
676
|
+
reason: 'the request\'s destination is a literal in full (scheme, host and path); the client\'s text reaches only the query, headers, body, method or authentication',
|
|
677
|
+
sourceHash: createHash('sha256').update(text).digest('hex'),
|
|
678
|
+
};
|
|
679
|
+
}
|
|
659
680
|
stats.weak++;
|
|
660
681
|
continue;
|
|
661
682
|
}
|
package/src/lineage/CLAUDE.md
CHANGED
|
@@ -1254,7 +1254,9 @@ pure function of text. Suite: `npm run test:deployment`, with fixtures under `te
|
|
|
1254
1254
|
| `deployment/ingest.js` | `ingestDeploymentConfig` (pure: text in, graph out; an adapter that throws is contained to that file), `ingestDeploymentFiles` (reads named files under one root, refusing traversal, absolute paths, symlinks and oversize files; feature gated), `detectFormat` (HCL, proxy configuration and TOML/XML are typed unsupported syntax) and `invalidateChangedSources` (drops the relations a changed or removed file supported, using the recorded digests; a node only that file declared stops being resolved or is dropped). |
|
|
1255
1255
|
| `deployment/trace-correlation.js` | X-303. `importTraceLines` keeps an allowlist of topology metadata and removes every other field WITHOUT storing it, even its name (only counts, split credential-shaped, payload-shaped and other); strips query strings; turns opaque path segments into `:id`; rejects a record whose kept value is not identifier-shaped; refuses other-environment records instead of relabelling them; merges duplicates; and is bounded (bytes, line length, lines, distinct observations with oldest-first eviction reported). `correlateObservations` matches with numbered rules R1 to R4 (exact service pair, route chain, identity, naming convention); R4 yields an `inferred` edge, R1 to R3 a `runtime-observation` edge, and static edges are never edited. `coverage.trafficCoverage` is always `not-established`; observed, sampled, stale and missing are separate lists; a static edge with no observation stays `possible`. `applyCorrelation` folds the result into a new validated graph. It does NOT persist anything: callers store `exportObservationSet` output and read it back with `parseObservationSet` (closed world, bounded, digest-checked). This sits beside, not on top of, the existing data-flow `runtime-observation.js` records, whose graph-id oriented contract is unchanged; only `EVENT_COUNT_BANDS` is shared. |
|
|
1256
1256
|
| `deployment/cross-repo.js` | X-304. `resolveCrossRepoBoundaries` takes graph exports the operator supplies, declared dependencies (each binding an exact 40/64 hex revision for both ends) and an access scope; it has no network or file access (a test pins its import list). A link resolves only when both repositories are in scope and supplied, each graph validates and names the repository it was supplied as, the graph revision equals the bound revision, the declared service exists resolved in its repository and in no other supplied repository, and a declared entry route reaches it. Every failure is a typed gap (`access-denied`, `repository-unavailable`, `version-mismatch`, `revision-unknown`, `identity-collision`, `unresolved-identity`, `graph-integrity`, `malformed-input`) and the dependency is kept as an unresolved edge to an unresolved callee. A resolved link carries evidence (declaration file and digest, both graph digests, the declaring files on each side, the route chain) and transitions (entry route, caller identities, callee identity and its grants, boundary crossings). It extends the idea of `cross-repo-link.js` to this graph; that module and `federation-loader.js` are unchanged. |
|
|
1257
|
-
| `deployment/attack-paths.js` | X-305. `computeAttackPaths` walks bounded, cycle-safe simple paths from entry points (resolved public routes and services) to targets (resources an identity is granted, or in the privileged zone) over `routes-to`, `calls`, `depends-on`, `network-allows`, `assumes` and `grants`. A hop is `blocked` only when an explicit deny edge sits between its endpoints; a path is `blocked` if any hop is, `unresolved` if a hop or endpoint is unresolved or a tenant transition makes it CONDITIONAL (a hop whose endpoints carry different tenants, listed as a `tenant-binding` condition), `runtime-supported` only if every network hop was observed (identity hops stay configuration), else `possible`. Each path lists supporting edges (with source file, digest, revision), assumptions, blockers, environments, boundary crossings and a coverage block (observed, sampled, stale, unobserved hops; `trafficCoverage` is always `not-established`; staleness is judged only when the caller passes `now`). Path ids hash the edge ids along the path, not the state, so they survive reordering and state changes. `bindFindingToService` ties a finding to a service ONLY through an explicit path-prefix binding (longest prefix wins; a tie, an absent service or no binding is a typed non-bound status and nothing is guessed). `analyzeFindingBoundaries` builds the per-finding `boundary-context` (exposure paths to the bound service, impact paths onward, verification assessments, uncovered boundaries, warnings). **Exploitability is never derived from reachability**: `assessVerification` accepts a record only if it validates, its outcome is `confirmed`, its confirmation level RECOMPUTED from evidence is `runtime-confirmed`, and its oracle is the one the finding's non-taint class names (an unsupported class has none); the label is `exploitable-confirmed` only then
|
|
1257
|
+
| `deployment/attack-paths.js` | X-305. `computeAttackPaths` walks bounded, cycle-safe simple paths from entry points (resolved public routes and services) to targets (resources an identity is granted, or in the privileged zone) over `routes-to`, `calls`, `depends-on`, `network-allows`, `assumes` and `grants`. A hop is `blocked` only when an explicit deny edge sits between its endpoints; a path is `blocked` if any hop is, `unresolved` if a hop or endpoint is unresolved or a tenant transition makes it CONDITIONAL (a hop whose endpoints carry different tenants, listed as a `tenant-binding` condition), `runtime-supported` only if every network hop was observed (identity hops stay configuration), else `possible`. Each path lists supporting edges (with source file, digest, revision), assumptions, blockers, environments, boundary crossings and a coverage block (observed, sampled, stale, unobserved hops; `trafficCoverage` is always `not-established`; staleness is judged only when the caller passes `now`). Path ids hash the edge ids along the path, not the state, so they survive reordering and state changes. `bindFindingToService` ties a finding to a service ONLY through an explicit path-prefix binding (longest prefix wins; a tie, an absent service or no binding is a typed non-bound status and nothing is guessed). `analyzeFindingBoundaries` builds the per-finding `boundary-context` (exposure paths to the bound service, impact paths onward, verification assessments, uncovered boundaries, warnings). **Exploitability is never derived from reachability**: `assessVerification` accepts a record only if it validates, its outcome is `confirmed`, its confirmation level RECOMPUTED from evidence is `runtime-confirmed`, and its oracle is the one the finding's non-taint class names (an unsupported class has none); the label is `exploitable-confirmed` only then AND (threat-model FR-04) when the record is at the graph's revision and a signed `proof-binding.js` envelope ties it to that exact path and claim; without one the proof is reported as `exploitability.componentProof`. A blocked or unresolved path keeps that fact in an `oracle-confirmed-path-*` label. IAM hops are decided per action by `iam-eval.js` (threat-model FR-03): a deny blocks only a matching action, resource and holding condition; `truncation.reasons` records depth, result-count and expansion cutoffs; boundary context 1.1.0. `exposureReach` is the path-free reachability the drift diff compares. |
|
|
1258
|
+
| `deployment/iam-eval.js` | Threat-model FR-03.1. Action and resource globs, the decided condition subset (`StringEquals`, `StringNotEquals`, `Bool`, `ArnEquals` against a caller context), `statementAttrs` (what the IAM adapter stores on a grants edge, inside the attribute grammar) and `decideAction` (possible, blocked, unresolved, not-granted with the blocking rule and the unresolved reasons). An opaque deny (no action list) is unresolved, never blocking. |
|
|
1259
|
+
| `deployment/proof-binding.js` | Threat-model FR-04.1. The `agentic-security/proof-binding` v1 envelope: Ed25519-signed by an issuer in the operator's trust root, binding a verification record to one path, claim, artifact, policy digest, environment, tenant, actor, route, action and oracle version. `verifyProofBinding` and `judgePathPromotion` return distinct codes (malformed, unsupported-version, missing-binding, untrusted-issuer, tampered, expired, context-mismatch). |
|
|
1258
1260
|
| `deployment/drift.js` | X-306. `diffBoundaryGraphs` compares two validated graphs of one repository at stable ids: new exposure (newly reachable from an entry, by reachability not by edge), changed privilege (new or changed grant, new identity assumption), tenant weakening (a dropped tenant binding, found by (kind, name, environment) because the tenant is part of the node id, or a new cross-tenant edge) and removed controls (a removed deny) are `material`; other relation changes are reported but not material. It also diffs the SOURCES and names the edges each moved file supported. `planRescan` maps changes to hypotheses through the bound service: a hypothesis is affected when its service is a seed of a change or can reach or be reached from one (union of both revisions, bounded closure); everything else is `skipped` with a reason and NOT rescanned. A hypothesis that cannot be tied to a service cannot be proven independent, so it makes the plan `incomplete` (only when something changed), as does a graph gap that stands for a missing dependency (`DEPENDENCY_GAP_CODES`). `incrementalAnnotate` recomputes only the planned hypotheses; `compareScoped` checks the result against a complete recomputation on `scopedSignature` (which leaves out graph-wide metadata) and never reports an incomplete result as equivalent. `invalidatePathsForSources` reuses `invalidateChangedSources` and drops exactly the paths whose supporting edges or node declarations cite a changed file. |
|
|
1259
1261
|
| `deployment/projection.js` | X-307. The ONE projection of a boundary context, modelled on `posture/verification/projection.js`: `projectBoundaryContext` (closed-world validation first: an unknown field, a credential-shaped or payload-shaped string, a control character or an over-long string refuses the whole context), `filterBoundaryView` (service, repository, environment, tenant; keeps scope, uncovered boundaries and every earlier warning and adds a warning saying how many paths it hid), `boundaryFields` (the additive report fields; the context itself is echoed only when it validated), `boundaryCoverage` (run accounting) and `attachBoundaryContext`, the ONLY producer, gated by the `deployment-boundaries` feature (off returns the same findings array untouched). The text states what was and was not established, never says safe, protected or unreachable (a lint-style test sweeps every state), and a context with no path says "not shown to exist". Consumed by `report/index.js` (`normalizeFindings` adds `boundaryContext` and `boundaryView` only when a finding carries a context, a top-level `boundaryCoverage`, a Markdown and a terminal block) and by MCP `explain_finding`. Previous output schemas are pinned in `test/fixtures/boundary-compat/` (captured before the wiring). |
|
|
1260
1262
|
| `deployment/boundaries-run.js` | X-308 wiring. The one operator entry point: `agentic-security boundaries --from <dir> [--findings <last-scan.json>] [--environment] [--repository] [--revision] [--root] [--out] [--json] [--now]`. `runBoundaries` (gated by `deployment-boundaries`, off by default; off returns a typed `disabled` BEFORE any file is opened) lists configuration files under the directory (bounded walk, symlinks never followed or listed), reads the reserved inputs `service-bindings.json`, `identities.json` and `traces.jsonl`/`traces.ndjson` (never ingested as configuration), ingests through `ingestDeploymentFiles`, correlates sanitized traces, reads findings from a scan result (a sibling `.sig` that exists must verify, else exit 1; an absent one is read and labelled unsigned) or from memory, and attaches contexts with `attachBoundaryContext`. Local files only, no scan, no execution; the only write is `--out`, refused when the target is a symbolic link. Exit codes: 0 report, 1 failed, 2 usage, 3 feature off, blocked or unsupported. `renderBoundariesText` reuses each context's own projected text. Suite: `test/deployment/boundaries-cli.test.js`. |
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// and conditions it cannot interpret are reported, not approximated.
|
|
10
10
|
|
|
11
11
|
import { adapterContext, isObject, asArray, str } from './adapter-kit.js';
|
|
12
|
+
import { statementAttrs } from './iam-eval.js';
|
|
12
13
|
|
|
13
14
|
export const TERRAFORM_PARSER = 'terraform-plan-json';
|
|
14
15
|
export const TERRAFORM_PARSER_VERSION = '1';
|
|
@@ -39,10 +40,12 @@ function applyPolicy(kit, identity, policy, subject) {
|
|
|
39
40
|
const conditioned = isObject(st.Condition) && Object.keys(st.Condition).length > 0;
|
|
40
41
|
read += 1;
|
|
41
42
|
if (resources.length > MAX_RESOURCES_PER_STATEMENT) kit.gap('limit-exceeded', subject, `a statement lists ${resources.length} resources; only the first ${MAX_RESOURCES_PER_STATEMENT} are read`);
|
|
43
|
+
if (actions.join(',').length > 250) kit.gap('limit-exceeded', subject, 'a statement\'s action list is longer than the graph records; the clipped list leaves decisions about the missing actions unresolved');
|
|
44
|
+
if (conditioned && statementAttrs(actions, st.Condition).conditionSupported !== true) kit.gap('unsupported-syntax', subject, 'a statement condition uses an operator or value outside the supported subset (StringEquals, StringNotEquals, Bool, ArnEquals); decisions it can affect stay unresolved');
|
|
42
45
|
for (const r of resources.slice(0, MAX_RESOURCES_PER_STATEMENT)) {
|
|
43
46
|
const target = kit.node('resource', `aws/${r}`, { trustZone: 'internal', attrs: r === '*' ? { wildcard: true } : {} });
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
// threat-model FR-03.1: the action list (and whether it was clipped) and the condition, in a form the path search can decide
|
|
48
|
+
const attrs = statementAttrs(actions, conditioned ? st.Condition : null);
|
|
46
49
|
kit.edge('grants', identity, target, {
|
|
47
50
|
effect, confidence: conditioned ? 'low' : 'high', discriminator: `${actions.join(',')}${conditioned ? ';cond' : ''}`.slice(0, 250), attrs,
|
|
48
51
|
});
|