ADR-005: Malicious Supply Chain Detection for Third-Party Skills and Plugins
Status: Proposed Date: 2026-02-18 Deciders: CODITECT Architecture Team Source Research: ClawGuard AI Agent Security Ecosystem Evaluation (2026-02-18)
Context
During the ClawGuard AI Agent Security Ecosystem evaluation on 2026-02-18, a trojanized fork of a legitimate repository was encountered and identified before any code was executed:
Finding:
lauty1505/clawguard— A trojanized fork ofJaydenBeard/clawguard. The fork contained an injected binary namedSoftware-tannin.zipembedded in the repository. The README was rewritten with social-engineering language to encourage users to download and execute the binary. This is a classic fork-and-trojanize supply chain attack pattern targeting developers who search for security tooling by name.Action taken: Repository removed from submodules. Never pushed, never executed.
This incident is not an outlier. Fork-and-trojanize is a documented, growing attack vector in the open-source ecosystem:
- The attacker identifies a legitimate, useful tool.
- They fork it to a new account.
- They inject malicious code (binary, script, or modified source).
- They optimize the forked repository to appear in search results for the tool's name.
- Developers who find the fork via search (not the canonical repository) clone and execute the malicious version.
The ClawGuard ecosystem is an especially attractive target because:
- Security tooling is trusted implicitly. A tool named "ClawGuard" is expected to run with security-related permissions and access to agent state.
- Developers evaluating security tools are specifically looking for new repositories, making search-based discovery the primary attack vector.
- The trojanized repository was found during a structured evaluation with explicit provenance checking. In a less rigorous workflow, it might have been cloned and tested.
CODITECT's platform involves:
- 97 submodules with a mix of CODITECT-owned and third-party repositories.
- A pattern of evaluating and integrating new third-party tools (
analyze-new-artifacts/workflow). - Tenant-installable skills (
skills/— 445 components) and a future plugin ecosystem. - Agent execution with tool calls that can read files, execute shell commands, and access credentials.
A single trojanized skill or plugin installed into the CODITECT runtime has immediate access to all of these. The attack surface is real and the stakes are high.
The question is: how should CODITECT systematically detect and prevent malicious supply chain components from being integrated, and how should this be enforced as an automated gate rather than a manual review process?
Decision
Implement automated supply chain verification as a mandatory gate for all third-party skill and plugin integrations, combining three complementary mechanisms:
- Binary artifact scanning — Detect injected executables, archives, and unexpected binary files in source repositories.
- Provenance verification — Validate that submodule URLs, npm packages, and PyPI packages point to expected canonical sources.
- Trust registry — Maintain a CODITECT-managed list of approved third-party repositories with pinned commit hashes and expected file checksums.
Mechanism 1: Binary Artifact Scanning
All repositories added to submodules/, all npm packages installed into skills, and all PyPI packages in skill venvs are scanned for:
- Unexpected binary file types:
.exe,.dll,.so,.dylib,.zip,.tar.gz,.gz,.pkg,.dmg,.msi,.deb,.rpm— any binary that is not explicitly declared in the repository's manifest. - Files not matching declared content: A file named
README.mdthat is binary, or a.pyfile with non-UTF-8 content. - Hidden files: Files with names beginning with
.that are not standard dotfiles (.gitignore,.env.example, etc.).
Detection is implemented in scripts/security/supply-chain-scanner.py, invoked automatically:
- When
git submodule addis executed (pre-commit hook). - When
npm installorpip installis run in a skill directory (post-install hook). - As a scheduled scan of all existing submodules (daily, via
scripts/security/scheduled-supply-chain-audit.py).
A binary artifact detection produces a SUPPLY_CHAIN_VIOLATION event and blocks the integration (always fail-closed for supply chain violations — no configurable fail-open).
Mechanism 2: Provenance Verification
Before a third-party repository is added as a submodule:
- The remote URL is checked against the CODITECT allow-list of trusted domains (
github.com/coditect-ai/, pre-approved third-party organizations). - The repository's commit history is checked: forks of known-good repositories that have fewer than a configurable minimum history depth (
min_commit_count: 10) are flagged as potentially suspicious (new forks often have shallow histories). - The adding developer must explicitly confirm that they have verified:
- The repository is the canonical upstream (not a fork).
- The repository owner is a recognized organization or individual.
- The commit being pinned has been reviewed.
This confirmation is recorded in config/security/submodule-attestations.yaml:
# config/security/submodule-attestations.yaml
attestations:
- submodule: submodules/core/coditect-core
url: https://github.com/coditect-ai/coditect-core.git
attested_by: hal@az1.ai
attested_at: "2026-02-18T00:00:00Z"
commit: abc123def456
notes: "Canonical CODITECT core framework."
- submodule: submodules/agent-labs/
url: https://github.com/brainqub3/agent-labs.git
attested_by: hal@az1.ai
attested_at: "2026-02-16T00:00:00Z"
commit: def789abc012
notes: "Third-party, read-only reference. NEVER push upstream."
never_push: true
Any submodule without an attestation entry blocks the repository from being included in CI and triggers an alert.
Mechanism 3: Trust Registry
The config/security/trust-registry.yaml file maintains a curated list of approved third-party components with pinned versions and expected checksums:
# config/security/trust-registry.yaml
version: "1.0.0"
updated: "2026-02-18"
trusted_npm_packages:
- name: "@yourclaw/clawguardian"
version: "0.2.2"
registry: "https://registry.npmjs.org"
sha512: "sha512-<expected-checksum>"
approved_by: hal@az1.ai
approved_at: "2026-02-18T00:00:00Z"
notes: "ClawGuardian hook plugin, reference implementation for security patterns."
trusted_pypi_packages:
- name: "fastapi"
version_range: ">=0.109.0,<1.0.0"
registry: "https://pypi.org"
approved_by: hal@az1.ai
approved_at: "2026-02-18T00:00:00Z"
untrusted_repositories:
- url: "https://github.com/lauty1505/clawguard"
reason: "Trojanized fork of JaydenBeard/clawguard. Contains injected binary Software-tannin.zip."
detected_at: "2026-02-18T00:00:00Z"
detected_by: research-agent
action: BLOCKED
The untrusted_repositories section serves as a threat intelligence list. Any attempt to add a URL from this list as a submodule is automatically blocked, regardless of context.
Post-Incident Retrospective Entry
The lauty1505/clawguard incident is immediately recorded in the trust registry (above) and in org.db as a permanent learning:
# Recorded in org.db as an error_solution
{
"category": "supply_chain_security",
"problem": "Trojanized fork encountered during security tool evaluation.",
"solution": "Binary artifact scanner + provenance verification + trust registry prevent recurrence.",
"evidence": "lauty1505/clawguard — Software-tannin.zip binary injected. Detected by provenance check before clone.",
"date": "2026-02-18"
}
Consequences
Positive
- Automated detection prevents human error: The
lauty1505/clawguardtrojan was caught in a structured evaluation. A developer under time pressure might have missed it. Automated scanning eliminates this dependency on human vigilance. - Defense-in-depth: Three independent mechanisms (binary scanning, provenance verification, trust registry) must all be bypassed simultaneously for a malicious component to be integrated. Any single mechanism catching an issue blocks the integration.
- Institutional memory: The
untrusted_repositoriestrust registry creates a permanent, searchable record of known-malicious repositories that persists across team members and sessions. - Audit trail: Submodule attestations in
submodule-attestations.yamlprovide a verifiable record of who reviewed and approved each third-party integration. - The ClawGuard ecosystem itself proves the value: The trojan was found while researching security tooling for AI agents. This recursive irony validates that supply chain attacks specifically target security-conscious workflows.
Negative
- Attestation overhead: Every new third-party submodule addition now requires an explicit attestation step. This adds friction to integration workflows. Mitigation: the attestation template is auto-generated by a helper script (
scripts/security/attest-submodule.py), reducing manual effort to filling in three fields. - Trust registry maintenance: The trusted packages list requires ongoing maintenance as package versions are updated. An outdated trust registry can false-positive on legitimate version upgrades. Mitigation: version range expressions (not pinned versions) are supported for packages with active upgrade cycles.
- Binary false positives: Legitimate repositories sometimes include pre-compiled assets (WebAssembly
.wasmfiles, compiled assets indist/). The scanner must maintain a configurable allow-list of expected binary types per repository. This adds calibration effort. - No protection against source-level injection: Binary scanning does not detect malicious code written in interpreted languages (Python, JavaScript) that does not use binary artifacts. Source-level analysis would require static analysis tooling (a future enhancement). The current ADR focuses on the most common attack pattern (injected binaries and archives).
Neutral
- CODITECT's existing git push safety rules (
NEVER PUSH TO NON-CODITECT REPOSITORIES) already prevent accidental upstream push of third-party submodules. ADR-005 adds complementary inbound protection (what we pull in) to the existing outbound protection (what we push out).
Alternatives Considered
Alternative A: Manual Review Only
Approach: Require human review of all third-party integrations. No automated scanning. Document a review checklist.
Rejected because:
- The
lauty1505/clawguardincident demonstrates that even structured, deliberate evaluations can encounter malicious repositories. Checklist-based manual review is subject to human error, time pressure, and fatigue. - As the CODITECT ecosystem grows (97 submodules today, more planned), manual review of every integration does not scale.
- Manual review produces no persistent audit record unless explicitly documented every time.
Alternative B: Automated Scanning Only (No Trust Registry)
Approach: Run binary artifact scanning on all integrations but maintain no trust registry or attestation records.
Rejected because:
- Binary scanning detects binary artifacts but not source-level malice or provenance fraud (a legitimate-looking repository with a malicious npm package dependency).
- Without a trust registry, there is no institutional memory. The
lauty1505/clawguardURL could be proposed as a submodule in a future session with no record of why it was previously rejected. - Attestations provide the human oversight layer that automated scanning cannot replace for novel attack patterns.
Alternative C: Vendor Lock-In via Approved Vendor List Only
Approach: Allow only pre-approved vendors. All third-party integrations must come from a fixed list of approved organizations (e.g., only github.com/coditect-ai/).
Rejected because:
- CODITECT legitimately integrates third-party open-source components (agent-browser, pdf tools, research tooling). A strict vendor whitelist would block all of these.
- The trust registry and attestation model provides equivalent assurance (each integration explicitly approved) without the operational inflexibility of an approved vendor list.
Alternative D: Sandboxed Execution Environment
Approach: Run all third-party skills and plugins in a sandboxed execution environment (containerized, network-isolated) so that even malicious code cannot affect the host system.
Not selected as primary (appropriate as a future enhancement):
- Sandboxing is complementary to supply chain verification, not a replacement. A sandbox prevents damage from executing malicious code, but does not prevent the malicious code from being present in the codebase or from operating within the sandbox's allowed capabilities.
- Container sandboxing adds significant operational complexity and latency to skill execution.
- Noted as a future enhancement, particularly for the planned third-party plugin ecosystem.
Implementation Notes
- Scanner:
scripts/security/supply-chain-scanner.py— invoked by pre-commit hook and scheduled audit. - Attestation tool:
scripts/security/attest-submodule.py— generates and validates attestation entries. - Trust registry SSOT:
config/security/trust-registry.yaml - Attestation SSOT:
config/security/submodule-attestations.yaml - Threat intelligence store:
untrusted_repositoriessection of trust registry +org.dberror_solutionstable. - CI gate: Supply chain scan runs in CI pipeline before any skill or submodule is merged to
main. - Expected binary allowlist: Per-repository configuration in
config/security/binary-allowlist.yaml(e.g.,submodules/core/json-viewermay contain pre-compiled.jsbundles). - Incident from this evaluation:
lauty1505/clawguardis immediately added tountrusted_repositoriesas the first entry.
References
- Malicious repository finding:
analyze-new-artifacts/clawguard-ai-agent-security/artifacts/research-context.json—security_findings.malicious_repo_detected - Git push safety:
CLAUDE.md— "NEVER PUSH TO NON-CODITECT REPOSITORIES" directives - Existing submodule safety:
.gitmodules+scripts/sync-all-submodules.sh - org.db schema:
docs/reference/database/DATABASE-SCHEMA.md—error_solutionstable - Related ADRs: ADR-001 (Security Layer Architecture), ADR-002 (Pattern Library Format), ADR-003 (Fail Behavior)
- Future: Sandboxed plugin execution (planned, not yet an ADR)