Skip to content

selvankj/gsi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

1 Commit
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

gsi โ€” GitHub Security Intelligence

A personal security gate. Scan before you use. Scan before you push.

CI Python License: MIT

gsi check .                              # ๐Ÿ”ต scan your repo before pushing
gsi check https://github.com/org/repo   # ๐ŸŸข evaluate an external repo
gsi install-hook                         # ๐Ÿ” auto-block commits containing secrets

Table of Contents


Why gsi?

Two moments where security matters most โ€” and where most developers have no tooling:

  1. Before you push โ€” Did you accidentally commit an .env file, a hardcoded API key, or a token?
  2. Before you use โ€” Does that open-source dependency have unpatched CVEs? Has it been abandoned?

gsi is a single CLI that catches both. Think of it as npm audit + git-secrets + a trust score, in one command.


How to Upload This to GitHub

Follow these steps โ€” this takes about 5 minutes.

Step 1 โ€” Create a new repository on GitHub

  1. Go to github.com/new
  2. Set the repository name to gsi
  3. Set visibility to Public (or Private โ€” your choice)
  4. โš ๏ธ Do NOT tick "Add a README", "Add .gitignore", or "Choose a license" โ€” the repo must be completely empty
  5. Click Create repository
  6. Copy the URL shown on the next page โ€” it will look like https://github.com/selvankj/gsi.git

Step 2 โ€” Update your username in two files

Replace selvankj with your actual GitHub username:

In pyproject.toml:

Homepage = "https://github.com/selvankj/gsi"
Issues   = "https://github.com/selvankj/gsi/issues"

In README.md (the badge line near the top):

[![CI](https://github.com/selvankj/gsi/actions/workflows/ci.yml/badge.svg)](https://github.com/selvankj/gsi/actions)

Step 3 โ€” Push the code

Open a terminal, cd into the unzipped gsi/ folder, and run these commands one by one:

# Initialise git
git init

# Stage all files
git add .

# First commit
git commit -m "feat: initial release of gsi security scanner"

# Point to your GitHub repo (replace selvankj)
git remote add origin https://github.com/selvankj/gsi.git

# Push
git branch -M main
git push -u origin main

Your repo is live at https://github.com/selvankj/gsi โœ…

Step 4 โ€” Set repo description and topics

  1. On your new repo page, click the โš™๏ธ gear icon next to About (top right)
  2. Set the description to:
    Personal security gate โ€” scan for secrets, CVEs, and risk signals before you push or use a repo
    
  3. Add topics: security cli secrets python devtools vulnerability-scanner github
  4. Click Save changes

Step 5 โ€” Verify CI is passing

After pushing, go to the Actions tab on your repo. You should see a workflow called CI running. It will:

  • Run all 46 tests across Python 3.9โ€“3.12
  • Run gsi check . on the repo itself (self-scan)

Once it goes green, the badge at the top of this README will light up โœ…


Install & Quickstart

Requires Python 3.9+

# Clone your repo (or cd into the unzipped folder)
git clone https://github.com/selvankj/gsi
cd gsi

# Install
pip install -e .

# Verify
gsi --help

No GitHub token needed for local scans. For scanning remote repos, a token removes rate limits:

export GITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Generate a token at github.com/settings/tokens โ€” only public_repo scope is needed.


Two Modes

๐Ÿ”ต Mode 1 โ€” Pre-publish (local)

Scan your own project before git push:

gsi check .
gsi check /path/to/myproject

Catches:

  • API keys, tokens, passwords, private keys in source files
  • .env files or credential configs accidentally staged
  • Dependencies with known CVEs (checks requirements.txt, package.json, go.mod, and more)
  • Insecure code patterns: SQL injection, eval(), weak crypto, command injection, SSRF, path traversalโ€ฆ

๐ŸŸข Mode 2 โ€” Pre-use (remote)

Evaluate an open-source repo before depending on it:

gsi check https://github.com/some/repo
gsi check owner/repo
gsi check owner/repo --token ghp_XXXX

Checks:

  • Known CVEs in all declared dependencies (via OSV.dev โ€” free, no API key needed)
  • Secrets accidentally committed to the repo
  • Risk signals: archived, stale, no security policy, no branch protection

Example Output

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ gsi security scan โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  ๐Ÿ“ /Users/me/myproject  (local ยท secrets ยท deps ยท risk)

๐Ÿ”‘ Secrets  (2 found)

  Sev         Type                            File             Line
  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€
  ๐Ÿ”ด CRIT     Database connection string      .env.local       3
  ๐ŸŸ  HIGH     AWS Access Key ID               config/aws.py    12

โš ๏ธ  Vulnerabilities  (1 found)

  Sev         Package    Version    CVE               Fix
  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  ๐ŸŸ  HIGH     requests   2.18.0     CVE-2018-18074    โ†’ 2.20.0

๐Ÿ“Š Risk Score  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘  42/100  [C] Elevated Risk

   +30pts  Secrets found in a public repo (2 critical/high secrets)
   +12pts  High-severity CVEs (4 high CVEs)

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  ๐Ÿšจ  UNSAFE                                              โ”‚
โ”‚  Fix the issues above before pushing โ€” your secrets      โ”‚
โ”‚  will be exposed.                                        โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Verdict levels:

Verdict Meaning
โœ… SAFE No critical or high findings
โš ๏ธ CAUTION High-severity findings or risk score โ‰ฅ 50
๐Ÿšจ UNSAFE Critical findings โ€” action required before pushing/using

Git Pre-commit Hook

Install once per project โ€” every git commit will automatically scan for secrets:

cd my-project
gsi install-hook

Now when you commit:

$ git commit -m "add payment integration"
๐Ÿ” gsi: scanning for secrets before commit...

โŒ  gsi: Commit BLOCKED โ€” secrets or high-risk findings detected.
    Fix the issues above, or run:  git commit --no-verify  to skip.

If the scan is clean:

$ git commit -m "fix: update config"
๐Ÿ” gsi: scanning for secrets before commit...
โœ…  gsi: No secrets found โ€” commit allowed.
[main 3a1b2c] fix: update config

Remove the hook at any time:

gsi remove-hook

Bypass once (use sparingly):

git commit --no-verify -m "your message"

All CLI Options

# โ”€โ”€ Targets โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi check .                              # current directory
gsi check /path/to/project               # specific local path
gsi check owner/repo                     # GitHub repo (short form)
gsi check https://github.com/owner/repo  # GitHub repo (full URL)

# โ”€โ”€ Modules โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi check . --modules secrets            # secrets only (fastest)
gsi check . --modules deps               # dependency CVEs only
gsi check . --modules secrets,deps       # combine modules
gsi check . --modules all                # everything โ€” default

# โ”€โ”€ Filtering โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi check . --min-severity medium        # hide low-severity findings
gsi check . --min-severity high          # only show high + critical

# โ”€โ”€ Output โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi check . --report report.html         # save a full HTML report
gsi check . --quiet                      # verdict + counts only (good for CI)

# โ”€โ”€ Remote-specific โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi check owner/repo --token ghp_XXXX    # provide token explicitly
gsi check owner/repo --no-clone          # use GitHub API only, skip cloning

# โ”€โ”€ Hook management โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
gsi install-hook                         # install in current repo
gsi install-hook /path/to/other/repo     # install in a specific repo
gsi remove-hook                          # remove from current repo

Exit codes โ€” useful for CI/CD:

Code Meaning
0 Clean โ€” safe to use or publish
1 High or critical findings detected
2 Scan error (bad path, auth failure, etc.)

Use in GitHub Actions:

# .github/workflows/security.yml
name: Security Gate
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install -e .
      - run: gsi check . --modules secrets --min-severity medium --quiet

Suppressing False Positives

Create a .gsiignore file in your project root. A template is included โ€” copy it to get started:

cp .gsiignore.example .gsiignore

Syntax:

# Ignore an entire file
tests/fixtures/fake_credentials.py

# Ignore a specific line
config/local.py:10

# Ignore a pattern type for paths matching a glob
[secrets] tests/**
[generic_api_key] docs/**
[high_entropy_string] **/*_test.py

Common suppressions to copy-paste:

# Test fixtures with fake/example credentials
[secrets] tests/fixtures/**
[secrets] tests/data/**

# Documentation examples
[secrets] docs/**
[generic_api_key] README.md

# Vendored third-party code
vendor/**

What Gets Detected

๐Ÿ”‘ Secrets

Category What's detected
AWS Access Key ID (AKIAโ€ฆ), Secret Access Key
GCP API Key (AIzaโ€ฆ), Service Account JSON
Azure Client secrets
GitHub Personal Access Tokens (ghp_, ghs_, fine-grained PATs)
Payments Stripe secret + publishable keys
Comms Slack tokens + webhooks, Twilio, SendGrid, Mailgun
Dev tools NPM tokens, Heroku API keys, Docker Hub credentials
Crypto RSA/EC/SSH private keys, JWTs
Generic Database URLs with credentials, high-entropy strings, hardcoded passwords

Detection uses two methods:

  • Regex patterns โ€” high-precision matching per credential type
  • Shannon entropy analysis โ€” catches high-entropy strings that don't match any known pattern

โš ๏ธ Dependencies

Powered by OSV.dev โ€” Google's open CVE database. No API key required.

Language Files scanned
Python requirements.txt, Pipfile, Pipfile.lock, pyproject.toml
Node.js package.json, package-lock.json, yarn.lock
Go go.mod, go.sum
Ruby Gemfile, Gemfile.lock
Rust Cargo.toml, Cargo.lock
Java pom.xml (basic)

๐Ÿ› Code Patterns

Check What it catches Severity
command_injection_risk shell=True + user input, os.system() Critical
sql_injection_risk String-concatenated SQL queries High
eval_usage eval() / exec() with dynamic input High
insecure_deserialization pickle.loads(), unsafe yaml.load() High
path_traversal_risk User input in file paths High
ssrf_risk User-controlled URLs in HTTP calls High
weak_crypto MD5, SHA1, DES, RC4 Medium
insecure_http Plain HTTP, disabled SSL verification Medium
debug_code_left pdb, console.log(password), DEBUG=True Medium
hardcoded_credentials Inline username/password assignments High
xxe_risk XML parsers without entity protection Medium
todo_fixme_security Security-related TODO/FIXME comments Low

Risk Scoring

Every scan produces a 0โ€“100 risk score built from weighted signals:

Signal Max points
Critical secrets in a public repo 30
Critical CVEs in dependencies 25
Repository is archived 15
High-severity CVEs 15
More than 3 secrets found 15
Critical code patterns 15
No branch protection on default branch 10
Stale repo (no commits in 180+ days) 10
Secrets found in a private repo 10
No SECURITY.md present 5

Grade scale:

Grade Score Label
A 0 โ€“ 14 Low Risk
B 15 โ€“ 29 Moderate Risk
C 30 โ€“ 49 Elevated Risk
D 50 โ€“ 74 High Risk
F 75 โ€“ 100 Critical Risk

Project Structure

gsi/
โ”œโ”€โ”€ gsi/                              # Main Python package
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ __main__.py                   # CLI entry point (Typer + Rich)
โ”‚   โ”œโ”€โ”€ gsiignore.py                  # .gsiignore file parser
โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ””โ”€โ”€ settings.py               # Configuration dataclasses
โ”‚   โ”œโ”€โ”€ modules/
โ”‚   โ”‚   โ”œโ”€โ”€ secret_scanner.py         # Regex + entropy secret detection
โ”‚   โ”‚   โ”œโ”€โ”€ dependency_scanner.py     # Manifest parsing + OSV.dev CVE lookup
โ”‚   โ”‚   โ”œโ”€โ”€ risk_scorer.py            # Signal-based risk scoring
โ”‚   โ”‚   โ””โ”€โ”€ pattern_scanner.py        # Code anti-pattern detection
โ”‚   โ”œโ”€โ”€ scanner/
โ”‚   โ”‚   โ””โ”€โ”€ github_client.py          # GitHub API + git clone helper
โ”‚   โ””โ”€โ”€ reports/
โ”‚       โ””โ”€โ”€ report_generator.py       # Console / JSON / HTML / Markdown output
โ”‚
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_secret_scanner.py        # 20 tests
โ”‚   โ”œโ”€โ”€ test_risk_scorer.py           # 14 tests
โ”‚   โ””โ”€โ”€ test_pattern_scanner.py       # 12 tests
โ”‚
โ”œโ”€โ”€ .github/
โ”‚   โ””โ”€โ”€ workflows/
โ”‚       โ””โ”€โ”€ ci.yml                    # CI: tests + self-scan on every push
โ”‚
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ .gsiignore.example                # Copy to .gsiignore to suppress false positives
โ”œโ”€โ”€ pyproject.toml                    # Package config โ€” update selvankj here
โ”œโ”€โ”€ CONTRIBUTING.md
โ””โ”€โ”€ LICENSE                           # MIT

Contributing

Contributions are welcome โ€” see CONTRIBUTING.md for full details.

The most impactful things to contribute:

  • New secret patterns โ€” add an entry to SECRET_PATTERNS in gsi/modules/secret_scanner.py
  • New code checks โ€” add an entry to PATTERN_CHECKS in gsi/modules/pattern_scanner.py
  • False positive fixes โ€” open an issue with the pattern name and a reproduction case
  • New dependency ecosystems โ€” add a parser to DependencyScanner._parse_content()

Dev setup:

git clone https://github.com/selvankj/gsi
cd gsi
pip install -e ".[dev]"
pytest                         # must show 46 passed
gsi check . --modules secrets  # must return SAFE

License

MIT โ€” see LICENSE.


Built to keep your secrets secret.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages