Supply chain security scanner for Python projects
Project description
Seraph
Guardian of the supply chain.
Seraph is a Python supply chain security scanner. It detects attack vectors at the package level — before or after compromise — with no external dependencies and no network calls.
Python packages are a common supply chain attack surface. Known vectors include stolen publish tokens used to release malicious versions, payloads injected directly into package source files, persistence via .pth files executed automatically on interpreter startup, orphaned .pyc bytecode with no corresponding source, and backdoors installed post-execution with systemd persistence. Seraph detects these vectors at the package level.
What it detects
| Scanner | Detects |
|---|---|
pth |
Executable code in .pth files (the 1.82.8 vector) |
pyc |
Orphaned .pyc files and suspicious bytecode constants |
source |
Obfuscated payload execution in .py files via AST analysis |
integrity |
Post-install file tampering via dist-info RECORD hash verification |
persistence |
Known backdoor artifacts on the filesystem |
Installation
pip install schedy-seraph
Usage
# Run all scanners
seraph scan
# CI mode — exits with code 1 if findings are detected
seraph scan --ci
How it works
PTH scanner reads every .pth file in site-packages and flags lines containing executable patterns (import, exec(, base64, etc.). Legitimate .pth files contain only directory paths.
PYC scanner flags .pyc files with no corresponding .py source (injected bytecode) and walks the bytecode constant pool looking for Base64 blobs and exfiltration indicators.
Integrity scanner reads the RECORD file that pip writes at install time — which contains a SHA-256 hash of every installed file — and recomputes each hash. Any mismatch means the file was modified after installation.
Source scanner parses .py files in site-packages with Python's ast module and flags exec/eval calls wrapping decode or decompress operations — the pattern used to execute obfuscated payloads. AST analysis avoids false positives from comments and docstrings.
Persistence scanner checks for filesystem artifacts known to be dropped by the LiteLLM payload: the sysmon backdoor, systemd persistence service, and exfiltration remnants in /tmp.
Design
- Zero dependencies — stdlib only
- No network calls
- Extensible: implement the
Scannerprotocol and register incli.py
from seraph.base import Scanner, ScanResult
class MyScanner(Scanner):
name = "my-scanner"
description = "..."
def run(self) -> ScanResult: ...
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file schedy_seraph-0.1.5.tar.gz.
File metadata
- Download URL: schedy_seraph-0.1.5.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9121ab7b9cbfaa46c6e5b0cee6336c768a2c74ca6e32c06bc90899a641d8731
|
|
| MD5 |
b40364bdc5fa3d2cc951b090e5088f0e
|
|
| BLAKE2b-256 |
4aa1bda3a22017fa48f2769112688585b63b77c513e4c9acc2fc1446d433df4f
|
Provenance
The following attestation bundles were made for schedy_seraph-0.1.5.tar.gz:
Publisher:
publish.yml on schedylabs/seraph
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
schedy_seraph-0.1.5.tar.gz -
Subject digest:
c9121ab7b9cbfaa46c6e5b0cee6336c768a2c74ca6e32c06bc90899a641d8731 - Sigstore transparency entry: 1178166650
- Sigstore integration time:
-
Permalink:
schedylabs/seraph@84513b5e85ce6d1e632a85a42479fb282ba085a8 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/schedylabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@84513b5e85ce6d1e632a85a42479fb282ba085a8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file schedy_seraph-0.1.5-py3-none-any.whl.
File metadata
- Download URL: schedy_seraph-0.1.5-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96908addf0328c143a1202085024b4b36f45760ba0645cef2dac1529915fffa9
|
|
| MD5 |
88359fdd1d55e79ed7e9ccf9255cd1b1
|
|
| BLAKE2b-256 |
2113f6073a347c7beaeb576dc7635be06f1923e5a0ca9efc27703a653d80959e
|
Provenance
The following attestation bundles were made for schedy_seraph-0.1.5-py3-none-any.whl:
Publisher:
publish.yml on schedylabs/seraph
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
schedy_seraph-0.1.5-py3-none-any.whl -
Subject digest:
96908addf0328c143a1202085024b4b36f45760ba0645cef2dac1529915fffa9 - Sigstore transparency entry: 1178166753
- Sigstore integration time:
-
Permalink:
schedylabs/seraph@84513b5e85ce6d1e632a85a42479fb282ba085a8 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/schedylabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@84513b5e85ce6d1e632a85a42479fb282ba085a8 -
Trigger Event:
push
-
Statement type: