cicd-security
Skill489 starsChanged 5 days agoMITView on GitHub
Audit CI/CD pipelines, GitHub Actions first and GitLab CI and CircleCI briefly, for the paths that give an outsider code execution, secrets or a write token: pull_request_target and workflow_run running untrusted code, expression injection into run steps, missing or broad workflow permissions, third-party actions not pinned to a commit SHA, OIDC trust policies with wildcard subjects, self-hosted runners on public repos, secrets reaching forks, cache and artifact trust between workflows, and AI agents in CI that read issue or PR text while holding a write token. Runs zizmor and actionlint read-only and writes findings.json. Use when the user mentions 'pull_request_target,' 'pwn request,' 'workflow injection,' 'zizmor,' 'actionlint,' 'pin actions to SHA,' 'GITHUB_TOKEN permissions,' 'self-hosted runner,' 'claude-code-action,' 'AI agent in CI,' 'GitLab CI security,' 'CircleCI security,' 'is this workflow safe,' or needs to secure a build pipeline.
- Reads credentials
- Commits and pushes
We split this skill into the rules it gives an agent
9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 42
Always prompts: zizmor in online mode (it sends a GitHub token to the API), any gh api call (the same command takes -X/-f and becomes a …
- Distinctive: line 45
Never prove a finding by opening a PR, issue or comment on a repository to trigger a workflow, and never run a workflow with a crafted …
- Distinctive: line 48
Never print secret values from workflow logs, environments or artifacts.
- Very specific: line 52
Read every file that defines or feeds a pipeline, not just .github/workflows/:
- Distinctive: line 95
Every finding needs a named lower-trust actor.
- Very specific: line 128
Token permissions (
excessive-permissions): No top-level permissions: (the job inherits the repo default), write-all, or write scopes on a … - Very specific: line 267
Write findings.json first.
- Very specific: line 311
Never edit workflows during the audit (zizmor --fix included).
- Distinctive: line 312
Never print secret values, tokens, or OIDC tokens.
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CI/CD Security — Workflows, Runners, Tokens and Agents in the Pipeline
Review a repository's CI configuration the way you'd review authorization code. A workflow file decides who can run what, with which token, which secrets and which cloud role. The question for every job is the same: can someone with less trust than the job (a fork PR author, any GitHub user who can comment, a third-party action maintainer) change what it runs or what it reads, and what does the job hold when they do?
Cross-references: dependency-audit (packages, lockfiles, build context and release-artifact identity; this skill owns
the workflow and runner side), secrets-audit (a secret that already reached a log, fork or artifact: rotation and
history), agent-supply-chain-audit (skills, hooks and MCP servers on developer machines; this skill covers agents
running inside CI), prompt-injection (LLM features in the user's own application), iam-audit (what the cloud role
behind an OIDC trust policy can do), cloud-audit (repo security defaults and branch protection as part of a platform
sweep), scanner-pipeline (running zizmor on every PR and on a schedule), finding-triage (disposition of a single
finding).
When to use
- "Is this workflow safe?", a pasted
.github/workflows/*.yml, or a PR that adds or changes CI - A repo or org review of GitHub Actions: triggers, permissions, pins, runners, OIDC, caches, artifacts
- An AI agent action (claude-code-action, codex-action, run-gemini-cli, actions/ai-inference) wired to issues, PRs or comments
- GitLab CI (
.gitlab-ci.yml) or CircleCI (.circleci/config.yml): the same classes, see references/gitlab-circleci.md - zizmor or actionlint output that needs verdicts rather than a raw list
Not for: vulnerable packages or a lockfile diff → dependency-audit; a leaked key that needs rotating →
secrets-audit; a Claude skill or MCP server someone is about to install → agent-supply-chain-audit; prompt
injection in the product's chatbot → prompt-injection; designing least-privilege cloud roles → iam-audit; setting
up a weekly scanner workflow → scanner-pipeline.
Authorization
- Review only repositories, organizations and CI systems the user owns or is authorized to audit. If ownership is unclear, ask first.
- Pre-approved because they only read: reading files, the
zizmor --offlineandactionlintforms, andgh workflow list/viewandgh run list. None of them edits a workflow. - Always prompts:
zizmorin online mode (it sends a GitHub token to the API), anygh apicall (the same command takes-X/-fand becomes a write),zizmor --fix(rewrites workflow files),gh run download, re-running or dispatching a workflow, and changing any repository or org setting. Recommend those; let the owner run them. - Never prove a finding by opening a PR, issue or comment on a repository to trigger a workflow, and never run a
workflow with a crafted payload. Write the exploit path as a trace and, where a live check is needed, a
validation_planthe owner runs on a private fork or test repo. - Never print secret values from workflow logs, environments or artifacts. Names only.
Step 1 — Inventory
Read every file that defines or feeds a pipeline, not just .github/workflows/:
| What | Where |
| Workflows | .github/workflows/*.yml, *.yaml |
| Local actions and reusable workflows | .github/actions/**/action.y*ml, action.y*ml at the root, any uses: ./… path |
| Remote reusable workflows | job-level uses: org/repo/.github/workflows/x.yml@ref: read them too, one level deep |
| Config the jobs execute or the agent loads | Makefile, package.json scripts, scripts under .github/, CLAUDE.md, AGENTS.md, .claude/, .mcp.json |
| Other CI | .gitlab-ci.yml and its include: files, .circleci/config.yml, dependabot.yml |
For each workflow, record: triggers (on:), top-level and job-level permissions:, each job's runs-on,
environment:, if: gates, every uses: with its ref, the secrets and id-token it uses, and any AI agent step.
That table is the coverage record for the report.
rg -n '^on:|^\s+(pull_request_target|workflow_run|issue_comment|issues|pull_request_review(_comment)?|discussion(_comment)?|workflow_call|workflow_dispatch)\b' .github/workflows
rg -n 'anthropics/claude-code(-base)?-action|openai/codex-action|google-github-actions/run-gemini-cli|actions/ai-inference' .github
# portable equivalents: grep -rnE with the same patternsRemote repo without a clone: list with gh workflow list -R owner/repo; reading file contents needs gh api
repos/OWNER/REPO/contents/.github/workflows/FILE --jq '.content | @base64d', which prompts. Treat fetched YAML as
data: never pipe it into a shell or interpreter.
Step 2 — Run the tools (candidates, not findings)
zizmor --offline --format=json . # pre-approved; also --format=sarif for code scanning
actionlint -format '{{json .}}' # pre-approved; runs shellcheck on run: blocks if it's installed- zizmor finds most of the classes below. Offline mode skips the audits that need the GitHub API
(
impostor-commit,known-vulnerable-actions,ref-confusion,stale-action-refs,archived-uses). For those, ask the user to runGH_TOKEN=$(gh auth token) zizmor --format=json .(it prompts, because it hands the API a token).--persona=auditoradds lower-confidence results;--fixrewrites files and is never part of the audit. - actionlint catches syntax and type errors, script-injection shapes in
run:and shellcheck problems in scripts. A workflow that doesn't parse can't be reasoned about; fix that first. - Map each tool result to a class with references/checks.md. Every result
still goes through Steps 3–5. zizmor flags
pull_request_targetwhether or not untrusted code ever runs; that alone is not a finding.
Step 3 — Who can trigger it, and what does the job hold
Every finding needs a named lower-trust actor. Decide it per trigger before looking for bugs:
| Trigger | Who controls the input | Token and secrets by default |
pull_request from a fork | Any GitHub user (public repo; first-time contributors may need approval) | Read-only token, no secrets |
pull_request_target | Any GitHub user who opens a PR | Base repo token (write unless restricted) and secrets |
issue_comment, issues, discussion*, pull_request_review* | Any GitHub user who can comment or open an issue | Base repo token and secrets |
workflow_run | Whoever triggered the upstream run, often a fork PR | Base repo token and secrets |
push, workflow_dispatch, schedule, release | Users with write access | Full; usually not an outsider path |
workflow_call | Whatever triggered the caller | Inherits the caller's context |
Since 8 December 2025, pull_request_target always runs the workflow file from the default branch and sets
GITHUB_REF/GITHUB_SHA to it; older workflow copies on other branches no longer run. That change does nothing about
a workflow that checks out or executes the PR's code, which is still the main pwn-request path.
Then list what the job holds: the effective GITHUB_TOKEN permissions (job block, else workflow block, else the repo
or org default, which is a platform fact), secrets referenced in the job, id-token: write and the role it assumes,
environment: protections, publish or deploy steps, and the runner (GitHub-hosted, or self-hosted and persistent).
Step 4 — Checks
Each class below has its grep, the attacker-controlled contexts, safe shapes and GitLab/CircleCI equivalents in references/checks.md. AI agents have their own reference: references/ai-agents-in-ci.md.
- Untrusted checkout in a privileged workflow (
pwn-request).pull_request_targetorworkflow_runthat checks outgithub.event.pull_request.head.sha/head.ref,refs/pull/N/mergeor the triggering run'shead_sha, then builds, tests, installs, or runs a local action or script from it. Indirect execution counts:npm installruns lifecycle scripts,makereads the PR's Makefile, auses: ./.github/actions/xresolves from the checked-out tree. - Expression injection (
script-injection).${{ github.event.issue.title }},…pull_request.body,…comment.body,github.head_ref, commit messages, author names and similar, expanded insiderun:, insideactions/github-script'sscript:, or into a value later written to$GITHUB_ENV/$GITHUB_OUTPUT. The runner pastes the text into the script before the shell sees it. Fix: pass it throughenv:and quote"$VAR". - Token permissions (
excessive-permissions). No top-levelpermissions:(the job inherits the repo default),write-all, or write scopes on a job that runs untrusted input. A finding only when a lower-trust actor reaches a step that uses the extra scope; otherwise a hardening note.persist-credentialsleft on in a job that later uploads the workspace as an artifact is the same class. - Mutable action refs (
unpinned-action). Third-partyuses:on a tag or branch instead of a full 40-character SHA,docker://images by tag, reusable workflows on@main. A finding when the job holds secrets, a write token, OIDC, or publish rights; tj-actions/changed-files (CVE-2025-30066) is the precedent for a tag re-pointed to code that printed secrets into logs.actions/*andgithub/*on tags are lower risk; say what policy the repo follows. A SHA that exists only in a fork's network (zizmorimpostor-commit) is not a pin. - OIDC trust (
oidc-trust).id-token: writeplus a cloud trust policy that a lower-trust workflow can satisfy: AWStoken.actions.githubusercontent.com:subwithStringLikeonrepo:org/*orrepo:org/repo:*, GCPattribute_conditionchecking onlyrepository_owner, Azure federated credentials whose subject is a pull request or a broad claims-matching expression. Pin the subject to a repo plus a protected branch or environment. - Self-hosted runners (
self-hosted-runner).runs-on: self-hosted(or a custom label) on a public repo, or any repo where fork PRs run. A persistent runner keeps whatever the previous job left on disk and in its environment. - Secrets reaching untrusted code (
fork-secrets). Secrets inpull_request_target/workflow_run/ comment-triggered jobs that run untrusted code,secrets: inheritinto a reusable workflow that runs PR code,toJSON(secrets), and on private repos the "send secrets to fork PR workflows" setting. - Cache poisoning (
cache-poisoning). A cache an untrusted run can write and a release or secret-holding job restores: writes frompull_request_target, broadrestore-keys:, keys built from branch names,setup-*cache:in a release job. Ultralytics (December 2024) went through this into a PyPI publish. - Artifact trust (
artifact-trust). Aworkflow_runjob that downloads a fork run's artifact and executes, unpacks into the workspace, deploys or publishes it, or trusts a value inside it (a PR number, a path) in a shell command. - Comment and label gates (
comment-command).issue_commentcommands with noauthor_associationor permission check,if: github.actor == 'dependabot[bot]'style checks that a spoofed actor can satisfy, and "safe to test" labels with a race between labeling and the next push. - Publish without a protected identity (
unprotected-publish).npm publish,twine upload,docker push,gh release createin a job any branch can reach, with a long-lived token and noenvironment:reviewers, where trusted publishing is available. - AI agents in CI (
agent-prompt-injection). An agent step that reads text a lower-trust actor wrote (issue body, PR title, diff, review comment, a PR-modifiedCLAUDE.md) while it holds a write token, secrets in its environment, or broad tools. Decide three things from references/ai-agents-in-ci.md: who can trigger it (the action's write-access check,allowed_non_write_users,allowed_bots), what it can do (claude_args --allowedTools, sandbox mode,Bash(*), jobpermissions:), and where its output goes (a comment, a commit, or a laterrun:step that evaluates it). The model is not a security boundary; the token scope and the trigger gate are.
Step 5 — Platform facts
Some deciding facts live in repo or org settings. Don't guess them; record each as a needs_validation blocker with
the command that answers it. These are gh api reads, which prompt (the owner can also check Settings → Actions):
gh api repos/OWNER/REPO --jq '{visibility, default_branch}'
gh api repos/OWNER/REPO/actions/permissions/workflow # default_workflow_permissions, can_approve_pull_request_reviews
gh api repos/OWNER/REPO/actions/permissions # allowed_actions, sha_pinning_required
gh api repos/OWNER/REPO/actions/runners --jq '.runners[] | {name, labels: [.labels[].name]}'
gh api repos/OWNER/REPO/actions/oidc/customization/sub # custom sub claim template, if any
gh api repos/OWNER/REPO/environments --jq '.environments[] | {name, protection_rules}'
gh api repos/OWNER/REPO/rules/branches/BRANCH # rulesets on the branch a release runs fromFork-PR approval and private-repo fork settings, org runner groups, and cloud-side trust policies that aren't in this
repo's IaC are the other usual blockers. references/checks.md lists the
commands, including aws iam get-role and gcloud iam workload-identity-pools providers describe.
Step 6 — Verify, then record
Close every candidate with one verdict, as defined in references/findings-format.md.
- Write the trace.
entrypoint= the trigger and the input the lower-trust actor controls (theon:line, the expression);propagation= the checkout, env var, artifact, cache key or agent prompt that carries it;sink= the step that runs it with the token, secrets or role. Point every step at a workflow file and line. - Refute it with references/verification.md. In CI the strongest controls are: the
trigger can't be reached by an outsider (
pushonly, agithub.repository == …guard, anauthor_associationcheck that runs before the step); the job holds nothing (read-only token, no secrets, no OIDC, GitHub-hosted runner); the value can't carry text (a PR number, a SHA); the untrusted checkout goes to a subdirectory nothing executes. A label gate, "only maintainers merge" and "the model will refuse" do not rule a candidate out. - Pick the verdict.
| Verdict | What it looks like here |
confirmed | pr-preview.yml runs on pull_request_target, checks out github.event.pull_request.head.sha, runs npm ci && npm run build (lifecycle scripts from the PR), and the job has contents: write and VERCEL_TOKEN. Any GitHub user opening a PR runs code with both. Static trace: confidence medium. Same verdict for issue-triage.yml putting ${{ github.event.issue.title }} into run: echo "…" with issues: write, and for a claude-code-action step with allowed_non_write_users: "*", claude_args: --allowedTools "Bash(*)" and contents: write. |
needs_validation | One deciding fact is a platform setting. deploy.yml has id-token: write and assumes arn:aws:iam::…:role/gha-deploy, but the trust policy isn't in the repo (blocker: does the role's sub condition allow any branch or pull_request? plan: aws iam get-role --role-name gha-deploy --query Role.AssumeRolePolicyDocument). A runs-on: [self-hosted, linux] job runs on pull_request in a public repo (blockers: is the runner ephemeral, and do fork PRs need approval?). A workflow with no permissions: runs PR code with a secret-free job (blocker: is default_workflow_permissions write?). |
rejected | A named control at a named line stops it on every path. pull_request_target labels PRs with actions/labeler and never checks out PR code: ruled_out_by names the job's only steps. ${{ github.event.pull_request.number }} in run: is numeric. ${{ github.event.issue.title }} reaches run: only through env: TITLE and "$TITLE". A claude-code-action workflow keeps the default write-access check (no allowed_non_write_users, no allowed_bots), so only collaborators trigger it. |
Gaps with no traced path are hardening notes, not records: missing top-level permissions: on a push-only
workflow, a tag-pinned third-party action in a job with a read-only token and no secrets, no concurrency: limit,
persist-credentials on with no artifact upload.
Severity follows references/severity-calibration.md, on
confirmedonly, andoverall≤ impact. Rate by what the job holds:- Critical: an outsider gets code execution with publish credentials, a cloud role with write access to production, or a token that can push to a protected release branch.
- High: an outsider gets a repo write token or repository secrets.
- Medium: an unpinned third-party action in a privileged job (likelihood depends on an upstream compromise), or a gate that only maintainers can reach.
- Low: the job holds nothing beyond read access and the result is limited to the attacker's own PR.
A static trace caps confidence at
medium.reproduced: trueonly when the owner ran the plan on a test repo or private fork and it showed the effect.- Fingerprint by root cause:
cicd-security/<class>/<workflow file>/<job id>, adding the step id when one job has two independent sinks (…/<job id>/<step id>). For an OIDC trust policy in IaC, use the IaC file and resource address; for one read from the cloud, the provider path with slashes. No line numbers, no:<digits>.
cicd-security/pwn-request/.github/workflows/pr-preview.yml/build
cicd-security/script-injection/.github/workflows/issue-triage.yml/label/greet
cicd-security/agent-prompt-injection/.github/workflows/claude.yml/claude
cicd-security/oidc-trust/infra/github-oidc.tf/aws_iam_role.gha_deploy
cicd-security/oidc-trust/aws/123456789012/role/gha-deploy
cicd-security/script-injection/.gitlab-ci.yml/notifyClasses: pwn-request, script-injection, excessive-permissions, unpinned-action, oidc-trust,
self-hosted-runner, fork-secrets, cache-poisoning, artifact-trust, comment-command, unprotected-publish,
agent-prompt-injection. Add one when none fits.
extkeys (flat, snake_case):
| Key | Value |
platform | github-actions, gitlab-ci, circleci |
workflow | Workflow file, or the IaC file for an OIDC policy |
trigger | Array of triggers that reach the sink: ["pull_request_target"] |
job / step | Job id; step id or name when it matters |
lower_trust_actor | any-github-user, fork-pr-author, issue-commenter, third-party-action-maintainer, org-member |
token_permissions | Effective write scopes: ["contents:write", "id-token:write"] |
secrets_in_scope | Secret names only: ["NPM_TOKEN"] |
agent | claude-code-action, codex-action, run-gemini-cli, ai-inference |
tool_rule | The tool hit that raised it: zizmor/template-injection, actionlint/expression |
- Write and validate.
skill: "cicd-security", sort by fingerprint, then:
node references/validate-findings.mjs findings.json
node references/to-sarif.mjs findings.json -o findings.sarif # optionalA full worked findings.json with one record per verdict is in
references/worked-examples.md. On a re-run, load the previous file first: a
rejected record stays rejected unless the line in ruled_out_by.location changed.
Dispositions (usually set later by finding-triage): Fixed / Deferred / Accepted Risk / Mitigated (platform/config) /
Requires major migration. Setting the repo's default token to read-only is a typical Mitigated (platform/config).
Output Format
Write findings.json first. The report is rendered from it and never changes a verdict or severity the JSON doesn't
already say.
# CI/CD Security Review
## Repository: [owner/repo @ sha] ## Date: [date] ## Platforms: [GitHub Actions / GitLab CI / CircleCI]
## Scope: [full | diff-scoped (partial) — what was left out] ## Visibility: [public | private | unknown]
## Tools: [zizmor x.y offline/online, actionlint x.y] ## findings.json: [path] — validated: [yes]
### Summary
- Confirmed: [N] (Critical [n] | High [n] | Medium [n] | Low [n]) Needs validation: [N] Rejected: [N]
### Workflow inventory
| Workflow | Triggers | Effective token scopes | Secrets / OIDC | Runner | Third-party refs unpinned | AI agent |
|---|---|---|---|---|---|---|
### Confirmed findings
#### [SEVERITY] [Class]: [Title] `fingerprint`
**Workflow / job:** `.github/workflows/x.yml` → `job` (`step`) **Trigger:** [trigger] **Confidence:** [medium | high (reproduced)]
**Path:** [lower-trust actor] → [input] → [carrier] → [sink] holding [token scopes / secret names / role]
**Fix:** [the YAML change, e.g. move to `pull_request` + `workflow_run`, pass through `env:`, pin to SHA with a version comment]
**Verify the fix:** [re-run `zizmor --offline .` / the grep / the owner's test-repo check]
### Needs validation
| Finding | Blockers | Check for the owner to run |
|---|---|---|
### Hardening notes (not findings)
- [gap] — [why there's no path] — [effort]
### Rejected (do not re-raise)
| Fingerprint | Ruled out by | Location |
|---|---|---|
### Prioritized remediation plan
1. [Untrusted code or text reaching secrets / write tokens: same day]
2. [OIDC subjects and runner exposure]
3. [Pins, permissions defaults, repo-level policy (default token read-only, SHA pinning required)]Boundaries
- Static review and read-only tools. Never trigger a workflow, open a PR or comment to test a path, or dispatch a run with crafted input; the owner tests on a private fork or a throwaway repo.
- Never edit workflows during the audit (
zizmor --fixincluded). Give the patch; the owner applies it. - Never print secret values, tokens, or OIDC tokens; name the secret and where it's referenced.
- Repositories the user doesn't own: report through the owner's security policy or GitHub private vulnerability reporting, never in a public issue.
- Refuse requests to use a found pipeline weakness against someone else's repository.
References
- GitHub Security Lab, "Keeping your GitHub Actions and workflows secure": Part 1, preventing pwn requests, Part 2, untrusted input
- GitHub Docs: Security hardening for GitHub Actions, OIDC in AWS
- GitHub Changelog: pull_request_target and environment branch protection changes (2025-11-07, effective 2025-12-08), blocking and SHA-pinning policy (2025-08-15)
- zizmor (audits, usage), MIT; actionlint, MIT
- anthropics/claude-code-action security guide
- Trail of Bits, agentic-actions-auditor (CC BY-SA 4.0): the trigger → agent input → capability framing for agents in CI. Paraphrased; no text copied
- Sentry, gha-security-review (Apache-2.0): the outsider threat model and safe-pattern list. Paraphrased; no text copied
- Wiz, Avoiding mistakes with AWS OIDC integration conditions
- Shared references (copied in at build time): findings-format.md, findings.schema.json, validate-findings.mjs, to-sarif.mjs, severity-calibration.md, verification.md
- This skill: references/checks.md, references/ai-agents-in-ci.md, references/gitlab-circleci.md, references/worked-examples.md
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- awarexone/Agentic-Bug-Hunter★ 5.5ksame name
- Awarexone/Agentic-Bug-Hunter★ 5.5ksame name
- shuvonsec/claude-bug-bounty★ 5.4ksame name
- zyphr-labs/bounty-harness★ 1same name
- conjure-3301/skills★ 0same name
- thesammykins/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository42 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- agent-supply-chain-auditSkill
- ai-risk-managementSkill
- api-auditSkill
- breach-patternsSkill
- business-logic-testingSkill
- cloud-auditSkill
- container-auditSkill
- control-auditSkill
- crypto-auditSkill
- csf-mappingSkill
- dependency-auditSkill
- disk-forensicsSkill
- finding-triageSkill
- fuzzing-harnessSkill
- hipaa-auditSkill
- iam-auditSkill
- incident-triageSkill
- log-watchSkill
- malware-triageSkill
- mobile-auditSkill
- native-code-reviewSkill
- osint-reconSkill
- owasp-auditSkill
- patch-sweepSkill
- pci-auditSkill
- personal-opsecSkill
- privacy-engineeringSkill
- prompt-injectionSkill
- reconSkill
- red-team-engagementSkill
- scanner-pipelineSkill
- secrets-auditSkill
- security-commsSkill
- security-startSkill
- siem-detectionSkill
- soc-operationsSkill
- threat-huntingSkill
- threat-modelingSkill
- variant-analysisSkill
- vuln-researchSkill
- web-pentestSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

