Every registry artifact runs through pipelines/scan-trust.mjs:
30 deterministic rules across 11 families, matched line-by-line against
vendored artifact files and curated copy. The scanner is evidence for human review, never an
automatic verdict — documentation context is shown but never counted, and secret values are
never echoed into findings.
Current mix: 8 critical · 13 high · 7 medium · 2 low.
Findings feed the verification and security posture shown on every
resource page. To propose a rule, edit data/curated/trust-rules.yaml —
one rule = one failure mode, with all four fields (definition, evidence, risk, remediation).
secrets
4 checks
secret-aws-key An AWS access key ID is embedded in a shipped file instead of injected at runtime.
Evidence: Literal AKIA-prefixed 20-character key id.
Redemption: Move credentials to environment variables or a secrets manager; add the file to .gitignore and rotate the exposed key.
Match patterns (1)
\bAKIA[0-9A-Z]{16}\b secret-github-token A GitHub personal access or OAuth token is embedded in a shipped file.
Evidence: ghp_/gho_/ghu_/ghs_/ghr_ token literal or a fine-grained github_pat_ token.
Redemption: Revoke the token, then read it from the environment at runtime.
Match patterns (2)
\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b
github_pat_[A-Za-z0-9_]{80,} secret-private-key A PEM private key block ships inside the artifact.
Evidence: -----BEGIN … PRIVATE KEY----- header.
Redemption: Remove the key from the artifact, rotate it, and mount it at runtime from a secret store.
Match patterns (1)
-----BEGIN [A-Z ]*PRIVATE KEY----- secret-token-assign A password, API key or token is assigned a string literal that looks real.
Evidence: password/secret/api_key assignment with a long literal value that lacks example markers.
Redemption: Replace with a placeholder plus runtime injection; document the required env var.
Match patterns (2)
\b(password|passwd|pwd|secret)\s*[:=]\s*['"][^'"]{4,}['"]
\b(api[_-]?key|apikey|token)\s*[:=]\s*['"][^'"]{8,}['"] remote execution
3 checks
exec-curl-pipe-shell A remote payload is fetched and executed without inspection — the classic supply-chain injection.
Evidence: curl or wget output piped into sh, bash, zsh or python.
Redemption: Pin a versioned download, verify its checksum, then run an inspected file — never pipe remote content to an interpreter.
Match patterns (2)
\b(curl|wget)\b[^|;\n]*\|\s*(sudo\s+)?(ba|z|da)?sh\b
\b(curl|wget)\b[^|;\n]*\|\s*python3?\b exec-remote-script-download The artifact fetches code from the network and immediately runs it, even without a pipe.
Evidence: curl/wget to a .sh/.py target followed by an execution call on the downloaded path.
Redemption: Vendor the script, pin its hash, and review it like any other source file.
Match patterns (2)
\b(curl|wget)\b[^\n]*\.(sh|py)\b[^\n]*\n\s*(ba|z|da)?sh\b
\bchmod\s+\+x[^\n]*\.sh\b exec-installer-oneliner Bootstraps via an install-script endpoint piped into a shell (get.docker.com patterns).
Evidence: A well-known installer endpoint invoked through a shell pipe.
Redemption: Prefer a pinned package manager install; if the one-liner is required, document manual verification steps.
Match patterns (3)
get\.(docker|docker-compose|composer)\.com
raw\.githubusercontent\.com[^\n]*\|\s*(ba|z)?sh
install\.[a-z]+/[^\n]*\|\s*(ba|z)?sh hidden instruction
2 checks
hidden-ignore-instructions Documentation or skill text tries to override the agent's instructions at runtime.
Evidence: Phrases like ignore previous instructions, disregard your rules, you are now, do not tell the user.
Redemption: Remove directive language from prose; skills describe capabilities, they do not command the agent behind the user's back.
Match patterns (6)
ignore (all |any |the )?(previous|prior|above) (instructions?|prompts?|rules?)
disregard (all |the )?(previous|prior|your) (instructions?|rules?|guidelines)
do not tell the user
you are now (a|an|the)
act as (if )?you have no
exfiltrate|send (the )?(api[_ -]?key|credentials|tokens) to hidden-obfuscated-commands Encoded payloads hidden in documentation that decode into shell commands.
Evidence: base64/atob/eval chains inside markdown prose or comments.
Redemption: Decode and inline the actual command in plain text so reviewers can see it.
Match patterns (2)
\beval\s*\(\s*\(?\s*(atob|base64|decode)
\becho\s+\S+\s*\|\s*base64\s+(-d|--decode) sql destructive
2 checks
sql-drop-table-unscoped DROP TABLE/SCHEMA/DATABASE appears without a guard, scratch schema, or explicit confirmation flow.
Evidence: DROP keywords in run paths (not in a migration file or quoted documentation).
Redemption: Scope destructive DDL to a scratch/dev schema, require an explicit confirmation flag, or move it behind a review gate.
Match patterns (1)
\bDROP\s+(TABLE|SCHEMA|DATABASE|CLUSTER)\b sql-truncate-delete-unbounded TRUNCATE, or DELETE without a WHERE clause, wipes a table in one statement.
Evidence: TRUNCATE keyword, or DELETE FROM with no WHERE on the same logical line.
Redemption: Bound destructive DML with WHERE, run inside a transaction with a LIMIT pre-check, and print affected row counts.
Match patterns (2)
\bTRUNCATE\s+(TABLE\s+)?[A-Za-z_]
\bDELETE\s+FROM\s+\S+\s*;?\s*$ data egress
3 checks
egress-hardcoded-endpoint The artifact sends data to a fixed external domain or IP outside the user's infrastructure.
Evidence: https endpoints that are not localhost or a loopback address.
Redemption: Move endpoints into user-supplied configuration; document every outbound destination and payload.
Match patterns (1)
https?://(?!localhost|127\.0\.0\.1|0\.0\.0\.0)[a-z0-9.-]+ egress-raw-ip Network calls aimed at a bare IP address — common in exfiltration and C2 patterns.
Evidence: Dotted-quad literals in connection strings (loopback exempted).
Redemption: Use named, documented hosts configured by the user; raw IPs deserve an explicit justification comment.
Match patterns (1)
\b(?!127\.0\.0\.1|0\.0\.0\.0)(\d{1,3}\.){3}\d{1,3}\b egress-cloud-storage-write Writes data to an external blob store (S3/GCS/Azure) which may leave the tenant boundary.
Evidence: aws s3 cp/sync, gsutil cp, az storage blob upload patterns.
Redemption: Default writes to user-configured buckets only; print the destination before upload.
Match patterns (3)
\baws s3 (cp|sync|mv)\b
\bgsutil\s+(cp|rsync)\b
\baz storage blob (upload|copy)\b unix destructive
4 checks
unix-rm-rf-root Recursive force-delete aimed at /, ~, $HOME, or a glob — the classic data-loss bug.
Evidence: rm with -r and -f flags targeting root/home/glob paths.
Redemption: Constrain deletes to a workdir-relative path; require an explicit confirmation flag; never expand globs in delete paths.
Match patterns (2)
\brm\s+(-[a-zA-Z]*[rf][a-zA-Z]*\s+)+(/|~|\$HOME|\*)
\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+/\s*($|\*) unix-mkfs-dd mkfs, dd to a device, or a volume-erase — destroys volumes.
Evidence: mkfs invocations, dd of=/dev/, eraseVolume.
Redemption: Never touch raw devices; if disk work is unavoidable, gate it behind explicit operator confirmation outside the artifact.
Match patterns (3)
\bmkfs(\.\w+)?\b
\bdd\b[^\n]*\bof=/dev/
\beraseVolume\b unix-chmod-777 chmod 777 (or 666) opens files or directories to every user — privilege-escalation surface.
Evidence: chmod with 777/666 modes.
Redemption: Grant the narrowest mode that works (typically 755/644) and to a specific owner.
Match patterns (1)
\bchmod\s+(-R\s+)?[76]{3}\b unix-crontab-persistence The artifact installs scheduled jobs or services — a persistence mechanism unrelated to its stated task.
Evidence: crontab writes, systemctl enable, launchctl load.
Redemption: Ship the schedule as documentation or an optional install step the operator runs knowingly.
Match patterns (3)
\bcrontab\s+
\bsystemctl\s+(enable|start)\b
\blaunchctl\s+load\b platform destructive
3 checks
platform-powershell-destructive Remove-Item -Recurse -Force, volume formatting, or execution-policy bypass shipped in run paths.
Evidence: Windows destructive cmdlets with force/recurse flags.
Redemption: Scope Remove-Item to an explicit relative path; never ship execution-policy changes in artifacts.
Match patterns (3)
Remove-Item\b[^\n]*(-Recurse[^\n]*-Force|-Force[^\n]*-Recurse)
\bFormat-Volume\b
Set-ExecutionPolicy\b.*(Bypass|Unrestricted) platform-kubectl-destructive kubectl delete namespace/pvc, or drain nodes without guards.
Evidence: kubectl delete targeting namespaces, PVCs or nodes.
Redemption: Target a dedicated dev namespace; require a confirmation flag; never delete shared PVCs.
Match patterns (2)
\bkubectl\s+delete\s+(ns|namespace|pvc|node)\b
\bkubectl\s+drain\b[^\n]*--force platform-cloud-destroy terraform destroy, EC2 terminate, project/group delete — irreversible cloud ops.
Evidence: destroy/terminate/delete verbs against cloud providers.
Redemption: Never ship destroy verbs in default paths; require a target guard (workspace/env pin) and typed confirmation.
Match patterns (4)
\bterraform\s+destroy\b
\baws\s+ec2\s+terminate-instances\b
\bgcloud\s+(projects|compute instances)\s+delete\b
\baz\s+group\s+delete\b git destructive
2 checks
git-force-push git push --force (or -f) rewrites shared history.
Evidence: push with force flags — plain --force is the risk, --force-with-lease is the accepted mitigation.
Redemption: Use --force-with-lease at most, and only on personal branches; prefer revert commits on shared branches.
Match patterns (1)
\bgit\s+push\b[^\n]*(--force(?!-with-lease)|\s-f\b) git-history-rewrite reset --hard, clean -fd, or checkout -- . discard uncommitted work without confirmation.
Evidence: reset --hard / clean -fd / checkout -- . patterns.
Redemption: Snapshot (stash/branch) before any destructive git op; print what will be discarded first.
Match patterns (3)
\bgit\s+reset\s+--hard\b
\bgit\s+clean\s+-[a-zA-Z]*fd
\bgit\s+checkout\s+--\s+\.?\s*$ overbroad permission
2 checks
perm-sudo-in-artifact Commands escalate to root without need — an artifact should never require root for its core task.
Evidence: sudo/su prefixes in run commands.
Redemption: Document the one setup step that needs privileges and run everything else unprivileged.
Match patterns (2)
\bsudo\b
\bsu\s+-?\w*\b perm-credential-scope-wide Asks for tokens/roles with wildcard scope (e.g. AWS *:* , full org tokens) when a narrow role would do.
Evidence: wildcard IAM actions, scope=admin, write-all OAuth scopes.
Redemption: Request least-privilege scopes and document each permission's purpose next to the request.
Match patterns (3)
['"]Action['"]\s*:\s*['"]\*
\bscope[=:]\s*['"]?(admin|\*)
\*:\* skill hygiene
2 checks
hygiene-unpinned-image docker run/pull references :latest or an untagged image — builds are not reproducible and updates are unaudited.
Evidence: docker run/pull with :latest or missing tags.
Redemption: Pin exact versions (name:tag) and re-verify on upgrade.
Match patterns (1)
\bdocker\s+(run|pull)\b[^\n]*:latest\b hygiene-unpinned-dependency npm/pip installs without a version pin — supply-chain drift lands silently.
Evidence: pip install pkg with no == constraint; npm install at end of line without a version.
Redemption: Pin package==1.2.3 (or a lockfile) and re-run the trust scan on upgrades.
Match patterns (2)
\bpip\s+install\s+[A-Za-z0-9_-]+(\s|$)
\bnpm\s+i(nstall)?\s+[^-][^\s]*\s*$ rerun safety
3 checks
rerun-mv-onto-output Moving onto a fixed destination unconditionally overwrites prior outputs, so re-runs destroy earlier results.
Evidence: mv with a fixed destination path and no existence check or versioned name.
Redemption: Write to versioned or temp paths and atomically swap; check existence before overwrite.
Match patterns (1)
\bmv\s+[^\n]+\s+(out|output|result|final)\.(csv|json|parquet|txt)\s*$ rerun-cp-onto-system cp/mv onto /etc or other system paths destroys host configuration without backup.
Evidence: cp/mv targeting /etc/... destinations.
Redemption: Write to a temp path, diff, and swap only after showing the operator what changes.
Match patterns (1)
\b(cp|mv)\b[^\n]*\s+/etc/(passwd|hosts|sudoers|shadow)\b rerun-append-config Appends output into shell/rc or daemon config on each run — re-running duplicates entries and corrupts the host config.
Evidence: append redirects into .bashrc/.zshrc/profile or daemon configs.
Redemption: Guard appends with a grep check so re-runs are no-ops.
Match patterns (1)
>>\s*[^\n]*(\.bashrc|\.zshrc|\.profile|\.bash_profile|sshd_config|daemon\.json)