Skip to main content

StayAwakeBot

Supply-chain worm hunting for developer machines and CI.

PyPI Python versions License


A single compromised dependency is how one package becomes an organisation-wide incident. Self-propagating packages spread through installs, builds and merges — arriving with code you asked for, and running before you ever read it.

saw hunts them where they land: in your repositories, your lockfiles, your installed dependency tree, and your machine's start-up surface. It then remediates through a pull request and gates CI, so an infected change cannot merge.

Offline and accurate with zero flags. A default scan needs no network and no configuration. saw scan's exit code is the verdict, so a CI gate is one line.

Detect saw scan — repositories, lockfiles and installed dependency trees. Read-only, always.
Remediate saw fix — prepares a cleanup branch per infected repo, --pr to publish. Never rewrites history; saw discard undoes it.
Prevent saw guard — install and verify the CI gate on any repo. saw hook — scan on clone and pull, before you install or build.
Audit saw audit — host hygiene and branch-protection posture, stating plainly what it did not examine.
Advisories saw db — an offline corpus for dependency CVE and malicious-package matching.

Quick start

Prerequisites: Python 3.11+ — see docs/PREREQUISITES.md.

pip install stayawakebot

Or the latest from source:

pip install "stayawakebot @ git+https://github.com/Ndevu12/stayAwakeBot@main"

Then hunt. Each of these stands alone:

Scan the repository you are in:

saw scan

Or sweep every repository under a path:

saw scan ~/dev

Scan with your own allowlist, rather than the packaged defaults:

saw scan --config config/security.yml

Check the machine itself, not a repository — credential hygiene and start-up entries:

saw audit

New here? saw intro is a 60-second tour, and saw search "…" finds the command you want.

The distribution is published as stayawakebot; the security CLI is the terse saw command (see the CLI guide).

Don't hand-maintain that workflow

Gate any repository's CI with one command — no install, no clone.

Every repository you own should refuse an infected merge. saw guard writes that GitHub Actions workflow, keeps it pinned, and proves it is enforced — for one repository or a whole organisation. Each command below stands alone; reach for the one you need.

Set it up. Writes the gate here, for you to review and commit:

saw guard setup

Or raise it as a pull request instead, which never pushes to main:

saw guard setup --pr

Check that a repository is actually guarded — present, SHA-pinned, current, and required:

saw guard check

Check a whole organisation, failing if any repository lacks a required gate:

saw guard check --org your-org -f

saw guard setup surgically pin-bumps a gate that already exists rather than replacing it, and never clobbers a workflow installed by some other means. saw guard check goes further than "is the file there" — it verifies branch protection actually requires the check, because a gate that is not required is decoration.

Both sweep many repositories at once (--remote / --user / --org), like saw scan and saw fix. See the CLI guide.

The workflow it writes

Installed for you by saw guard setup, and equally valid to drop in by hand:

# .github/workflows/worm-scan.yml
name: Worm scan

on:
  push:
    branches: [main]
  pull_request:

# Auto-remediation needs write access:
#   contents: write       -> push the security/auto-clean fix branch
#   pull-requests: write  -> open/update the rolling cleanup PR
# The scan itself only needs read; these are for the remediate step. Drop them
# both to `read` if you want detection without remediation.
permissions:
  contents: write
  pull-requests: write

jobs:
  strix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1   # v7.0.1
        with:
          fetch-depth: 0        # full history is required

      - uses: Ndevu12/strix@93fe465d7b0266c6010778999b73b591ae082f3e      # v0.1.4
        with:
          version: '0.5.1'      # pin the scanner too; blank tracks latest
          # On an infected verdict, open ONE rolling `security/auto-clean` PR.
          # The gate still goes RED until that PR is merged — remediation opens
          # the fix, it does not make the check pass. Omit for detection only.
          remediate: pr

About the pins

Ndevu12/strix ("StayAwakeBot Strix") is the public Action — a thin wrapper that installs the published stayawakebot scanner from PyPI.

Pin every action by commit SHA, including this one: a tag can be moved to point at different code after you have reviewed it, a SHA cannot. The trailing comment records which release the SHA corresponds to, so the pin stays readable. In production pin version: as well — it selects the stayawakebot release from PyPI and otherwise tracks whatever is latest at run time.

Other inputs: config-file to supply your own allowlist, fail-on to choose the verdict that fails the build (default infected), and upload-sarif to send findings to code scanning. See Security baseline.

Run via Docker (no local Python needed)

Prefer not to install a Python toolchain at all? Pull the image and scan a mounted repo:

docker run --rm -v "$PWD:/repo:ro" ghcr.io/ndevu12/stayawakebot \
  saw scan /repo

The exit code is the verdict (0 clean, 1 findings). To keep the report file too, mount a writable dir and run as your own user so the bind-mount is writable:

docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/repo" \
  ghcr.io/ndevu12/stayawakebot \
  saw scan /repo --reports-dir /repo/reports

Tags: :latest, :X.Y.Z, :X.Y, and :sha-<commit>. The image runs as a non-root user, is built from the same wheel published to PyPI, and ships SLSA provenance + SBOM attestations.

Also in the package

stayawakebot additionally ships a health sentinel — a URL/uptime availability monitor (HTTP status, latency, TLS and keyword checks) run with stayawake-health-check. It is independent of saw and shares only the packaging. See Usage and Configuration.

stayawake-health-check --config config/urls.yml

Documentation

License

stayAwakeBot is dual-licensed:

  • AGPL-3.0-or-later — free and open source. You must preserve attribution, and if you modify it and convey it or offer it over a network (e.g. as a hosted service), you must release your corresponding source under the AGPL too.
  • Commercial license — a paid, proprietary-use option for closed-source or proprietary-SaaS use without the AGPL's source-disclosure obligations. For terms, contact saw@ndevuspace.com.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stayawakebot-0.6.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stayawakebot-0.6.0-py3-none-any.whl (1.2 MB view details)

Uploaded Python 3

File details

Details for the file stayawakebot-0.6.0.tar.gz.

File metadata

  • Download URL: stayawakebot-0.6.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stayawakebot-0.6.0.tar.gz
Algorithm Hash digest
SHA256 7fe9b1ca5cc57a1e700e1ed422a756a8acb7a5321cfa27c920a92dc7e6ed0539
MD5 1a13413d6805c71c814662deeeb791b6
BLAKE2b-256 fcd77453fdb29a63f2774450403d7707f1f99bea71169f0e02aee8648451afce

See more details on using hashes here.

Provenance

The following attestation bundles were made for stayawakebot-0.6.0.tar.gz:

Publisher: release.yml on Ndevu12/stayAwakeBot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stayawakebot-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: stayawakebot-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stayawakebot-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9cdfca7fd924a1545f1bcb76aa6cc66fb60b93602ef5473242d700d63e968326
MD5 a3651e49d8ad071847d9acd0533c8d43
BLAKE2b-256 43e86dca1c2804f3230e315e3ad5acf333b9007eb8d3f084a49f9caf97e510df

See more details on using hashes here.

Provenance

The following attestation bundles were made for stayawakebot-0.6.0-py3-none-any.whl:

Publisher: release.yml on Ndevu12/stayAwakeBot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

This release

0.6.0 This release

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.19

2 files

0.1.18

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.14

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page