keploy-e2e-test — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited keploy-e2e-test (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 6 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 6 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
End-to-end verification of a change in keploy/keploy by building the binary from source and driving it through real record → replay against a real sample app, exactly the way CI does.
Trigger this skill whenever the user asks to:
Before doing any work, decide whether e2e record/replay is even the right signal. Skip with a clear, short reason if:
tests + go build + golangci-lint run is enough.
keploy/integrations repo, not in this tree. You cannot fully exercise it from a fresh fork — CI skips those jobs on forks, and so should you. Say so and stop.
flag parsing, or log formatting, a unit test or a manual keploy --help check is sufficient.
path needs a dependency (eBPF kernel features, a managed DB, a paid service) that isn't available in the sandbox you're running in, say so and propose what would be needed instead of half-running.
If you skip, say why in one or two sentences and stop — do not silently fall back to "just run the unit tests."
Before touching anything, build a concrete picture of:
git diff main...HEAD, or thefiles the user points at). For a PR, read the PR description and the changed files — not just the titles.
pkg/matcher, pkg/service/replay)pkg/core/proxy, pkg/models/<protocol>, pkg/agent/hooks)pkg/platform/yaml)pkg/service/orchestrator)pkg/service/report, pkg/platform/coverage)cli/<cmd>.go, config/config.go)pkg/agent/memoryguard, main.go)sentence before you start looking for an app.
a status mismatch? a race in the record log? Knowing this up front tells you what to grep for after replay.
If the affected path is obvious from the diff, say so and move on. If it isn't, say so and ask — do not guess.
Search broadly across the keploy organization for a sample that already exercises the affected surface area. The sample repos CI pulls from are in AGENTS.md under "Sample repos CI pulls from"; the complete list of sample repos on the org is discoverable with gh repo list keploy. its usually samples- which can be go, java etc.
How to search, in rough order of cost:
what's already covered is .github/workflows/test_workflow_scripts/. Each subdirectory maps 1:1 to a sample app, and the shell script inside is what CI actually runs against that app. ls that tree — if one of the names obviously matches your changed path (e.g. you changed DNS parsing → check golang/dns_mock/, golang/dns_dedup/), read that script first.
grep -rn script_dir .github/workflows/*.ymlshows every app currently wired into CI with its path (directory in the samples repo) and script_dir (directory in test_workflow_scripts).
covered by an in-tree script:
gh api repos/keploy/samples-go/contents/ --jq '.[] | select(.type == "dir") | .name'
gh api repos/keploy/samples-python/contents/ --jq '.[] | select(.type == "dir") | .name'
gh api repos/keploy/samples-typescript/contents/ --jq '.[] | select(.type == "dir") | .name'
gh api repos/keploy/samples-java/contents/ --jq '.[] | select(.type == "dir") | .name'
gh api repos/keploy/samples-rust/contents/ --jq '.[] | select(.type == "dir") | .name'
gh api repos/keploy/samples-csharp/contents/ --jq '.[] | select(.type == "dir") | .name'Don't hard-code which repo to look in — the best match may be in a less-obvious place (e.g. a graphql-over-postgres change might be best exercised by samples-go/graphql-sql or by samples-java/spring-boot-postgres-graphql). Skim each candidate's README in the sample repo before committing.
path, you have two honest options:
samples are expensive to maintain.
If an existing test_workflow_scripts/<lang>/<script_dir>/<lang>-linux.sh already exercises the exact behavior your change touches — use it. Don't modify the script. Just build the binary and run it (Step 4).
If the app is right but the script doesn't cover the new behavior, make the minimal additive change:
send_request() (orwhatever the script calls its traffic driver).
expectation, add a new check after the existing check_test_report / report-walking loop — do not rewrite the loop.
existing assertion, state why explicitly in a comment on that line.
set -Eeuo pipefail vs. plain,section/endsec GitHub grouping helpers, trap handlers, 1 vs. 2 record iterations. Match what's already there.
When in doubt, look at how recent extensions were done by reading the git history of the script you're editing.
Please dont break existing code while doing it.
Only if no existing app exercises the path. This has two sides:
Sample-app side (in `keploy/samples-<lang>/`):
if required. Match the structure of the smallest existing samples in the same repo (e.g. samples-go/http-pokeapi, samples-python/flask-secret).
a PR there. If that's out of scope for this task, say so and propose the sample contents instead of silently trying to checkout a branch that doesn't exist. Do create a PR in the sample repository while using the skill keploy-pr-workflow to create the PR.
`keploy/keploy` side (this repo):
.github/workflows/test_workflow_scripts/<lang>/<script_dir>/<lang>-linux.sh.Name <script_dir> as lower_snake_case of the sample folder name (convention: see existing mappings — echo-mysql → echo_mysql, http-pokeapi → http_pokeapi, go-grpc → go-grpc (kept hyphenated here, so copy the convention of the closest existing neighbor rather than normalizing blindly)).
language. Canonical references:
.github/workflows/test_workflow_scripts/golang/http_pokeapi/golang-linux.sh.github/workflows/test_workflow_scripts/golang/echo_mysql/golang-linux.sh.github/workflows/test_workflow_scripts/node/express_mongoose/node-linux.sh.github/workflows/test_workflow_scripts/python/flask-secret/python-linux.sh.github/workflows/test_workflow_scripts/java/spring_petclinic/java-linux.sh.github/workflows/test_workflow_scripts/golang/go-grpc/grpc-linux.sh.github/workflows/golang_linux.yml.github/workflows/golang_docker.yml.github/workflows/grpc_linux.yml.github/workflows/python_linux.yml (native) / python_docker.yml.github/workflows/node_linux.yml / node_docker.yml.github/workflows/java_linux.yml.github/workflows/schema_match_linux.ymlThe entry must have name, path (dir inside the samples repo), script_dir (dir inside test_workflow_scripts/<lang>/), plus any extra axes the workflow uses (e.g. mode, enable_ssl).
for the language. The gate job in prepare_and_run.yml depends on the existing workflow names — new ones won't be required checks.
main,follow the existing pattern of git fetch origin && git checkout origin/<branch> at the top of the script (see echo_mysql, risk_profile, sse_preflight). Document that branch in the PR description on the samples-repo side.
Always build the binary the same way CI does before running:
# matches CI's "build-no-race" artifact
go build -tags=viper_bind_struct -o ./out/build-no-race/keploy .
# matches CI's "build" artifact (race-enabled; needs CGO)
CGO_ENABLED=1 go build -race -tags=viper_bind_struct -o ./out/build/keploy .Then run the script the way CI does (from inside the sample app directory), passing the binaries through the env:
# Checkout samples repo beside this one (once)
git clone https://github.com/keploy/samples-go ../samples-go
cd ../samples-go/<matrix.app.path>
RECORD_BIN=/abs/path/to/keploy/out/build/keploy \
REPLAY_BIN=/abs/path/to/keploy/out/build/keploy \
GITHUB_WORKSPACE=/abs/path/to/keploy \
bash -x $GITHUB_WORKSPACE/.github/workflows/test_workflow_scripts/<lang>/<script_dir>/<lang>-linux.shGITHUB_WORKSPACE must point at the keploy repo root because scripts source test-iid.sh and update-java.sh via that path.
On Linux, keploy needs root for eBPF — most scripts use sudo on specific commands. Don't add sudo to the whole script invocation if the script doesn't already do that; copy the pattern used by the existing scripts (selective sudo -E env PATH=$PATH "$RECORD_BIN" …, sometimes sudo "$RECORD_BIN" config --generate).
On macOS/Windows the same script pattern won't work unmodified — in those environments either fall back to the *_macos.yml / *_windows.yml / .ps1 counterparts, or say you can't reproduce locally and run it via CI. State that limitation explicitly rather than pretending to test.
If you can't run the script locally (no Docker, no eBPF support in a container, missing dependency), say so. Do not claim success without real evidence.
The script's own success criterion is: all ./keploy/reports/test-run-*/ test-set-*-report.yaml have status: PASSED, and no "ERROR" or "WARNING: DATA RACE" lines appeared in the record or test logs.
You must independently verify the same:
# the newest test-run dir
RUN_DIR=$(ls -1dt ./keploy/reports/test-run-* | head -n1)
# every report should say PASSED
for rpt in "$RUN_DIR"/test-set-*-report.yaml; do
awk '/^status:/{print FILENAME": "$2; exit}' "$rpt"
done
# coverage (when the sample enables it)
[ -f "$RUN_DIR/coverage.yaml" ] && cat "$RUN_DIR/coverage.yaml"Additionally:
1 or 2 times — check the for i in 1 2; do construct).
you added must be present in a generated test-set-<n>/tests/test-*.yaml or in the report's per-test breakdown.
mainbinary first** (use the latest artifact pattern from CI, or just build main into a separate path). Confirm the script fails before your change and passes after. That is the clean proof of a fix.
"ERROR|WARNING: DATA RACE"`. An "ERROR" line in keploy output fails the script in CI; reproduce that gate locally.
End with a short, factual summary:
samples-<lang>/<path>), and whether it wasused as-is, extended, or newly created.
test_workflow_scripts/<lang>/<script_dir>/<lang>-linux.sh).RECORD_BIN=… REPLAY_BIN=… bash … line).relevant diff in report output.
the top — don't invent a new reason.
set -Eeuo pipefail + ::group:: sections + a die trap, match that; if they use a simpler linear style (http_pokeapi), match that. Pick one of the existing templates as a starting point.
keploy/, keploy.yml, *_logs.txt, or other runartifacts from a sample app. Those are generated per run. It might be needed if the only thing you are checking is the test mode or other modes and you know you havent made any changes to the record mode. We can save CI times by not running the record mode.
pkg/agent/hooks/bpf_*_bpfel.go) as partof the e2e flow. If the eBPF programs need to change, that belongs in a separate, intentional step (edit the .c source and regenerate).
(record_latest_replay_build, record_build_replay_latest, record_build_replay_build) exist to catch mock-format incompatibility. If your change would be gated on "both sides are new," either add capability detection (see .github/workflows/test_workflow_scripts/golang/risk_profile/golang-linux.sh and connect_tunnel/golang-linux.sh for how the existing scripts distinguish */build/keploy from latest), or flag the incompatibility to the user so they can decide.
go build succeedingisn't a substitute for a real replay run. If you couldn't run, say so.
For anything in samples repo side changes, you must have created a branch. Use that branch has ref in keploy/keploy to test it.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.