How to Sign Your Python .exe With Sigstore (No Certificate Required)

Published: (February 15, 2026 at 02:48 PM EST)
5 min read
Source: Dev.to

Source: Dev.to

The problem

You built an open‑source app. Users download your .exe. How do they know it’s really from you and hasn’t been tampered with?

  • Traditional solution: buy a code‑signing certificate ($200‑$400 / year).
  • Better solution: Sigstore – free, open‑source, cryptographically secure.

This is how I sign every PC_Workman release.

  • Setup time: ~8 minutes
  • Per‑release time: ~30 seconds
  • Cost: $0

Why Sigstore?

What Sigstore Gives You
Proof the file came from your GitHub account
Proof the file hasn’t been modified since signing
Cryptographic proof anyone can verify
Completely free – no credit card, no certificate purchase, no annual fees

What You Need

RequirementDetails
Python project compiled to .exePyInstaller, Nuitka, etc.
GitHub accountTo authenticate and claim ownership
8 minutesTo set everything up

Install Sigstore

pip install sigstore

Verify the installation:

sigstore --version
# Expected output: sigstore, version X.X.X

Create a GitHub Personal Access Token (PAT)

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic).

  2. Click “Generate new token (classic)”.

  3. Select the following scopes:

    • read:user
    • user:email
  4. Set Expiration to “No expiration” (for ongoing releases).

  5. Copy the token (you’ll only see it once).

Store it securely, e.g.:

# Bash / macOS / Linux
export GITHUB_TOKEN="your_token_here"

# PowerShell
$env:GITHUB_TOKEN="your_token_here"

You can also keep it in a password manager and paste when needed.

Sign Your Executable

cd /path/to/your/releases   # navigate to the folder containing the .exe

sigstore sign \
    --bundle sigstore-bundle.json \
    PC_Workman_HCK.exe

What Happens

  1. Sigstore opens a browser for GitHub OAuth – authorize the app.

  2. A cryptographic signature is generated.

  3. Two files appear:

    • PC_Workman_HCK.exe (unchanged)
    • sigstore-bundle.json (the signature bundle)

Time: ~30 seconds.

Create a GitHub Release

Include the following assets:

FilePurpose
PC_Workman_HCK.exeYour executable
sigstore-bundle.jsonSignature proof
VERIFICATION.mdInstructions for users (see below)
(optional) security-report.txtVirusTotal scan results, etc.

Example VERIFICATION.md

# How to Verify This Release

```bash
pip install sigstore
sigstore verify github PC_Workman_HCK.exe \
    --bundle sigstore-bundle.json \
    --cert-identity https://github.com/YourUsername

If verification succeeds you’ll see:

✅ File came from @YourUsername GitHub account
✅ File hasn't been modified since signing
✅ Signing happened on <timestamp>

If it fails, the command will exit with an error and show why.


Replace `YourUsername` with your actual GitHub username.

## Verify as a User

```bash
pip install sigstore
sigstore verify github PC_Workman_HCK.exe \
    --bundle sigstore-bundle.json \
    --cert-identity https://github.com/YourUsername

Sigstore checks:

  • Certificate identity – does the signature match the claimed GitHub account?
  • Integrity – has the file been altered since signing?
  • Timestamp – when was it signed?

No trust chain is required – pure cryptography.

Automate with GitHub Actions

name: Sign Release

on:
  push:
    tags:
      - 'v*'   # run on version tags

jobs:
  sign:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Sigstore
        run: pip install sigstore

      - name: Build executable
        run: pyinstaller main.py   # or your build command

      - name: Sign executable
        run: |
          sigstore sign \
            --bundle sigstore-bundle.json \
            dist/your-app.exe
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload signed assets
        uses: actions/upload-artifact@v3
        with:
          name: signed-release
          path: |
            dist/your-app.exe
            sigstore-bundle.json

Every tagged release will be automatically signed and the artifacts uploaded.

Building a Web of Trust (Optional Extras)

ServiceWhat It Adds
ORCID (orcid.org)Persistent digital identity for researchers/developers; link to GitHub profile.
GitHub Developer Program (github.com/developer)Shows commitment to open source; free membership.
OpenSSF Best Practices Badge (bestpractices.coreinfrastructure.org)60+ security criteria; industry‑recognized badge.

Together they create a stronger trust network around your project.

Quick 5‑Minute Challenge

# 1️⃣ Install Sigstore
pip install sigstore

# 2️⃣ Create a test file
echo "test" > test.txt

# 3️⃣ Sign it
sigstore sign --bundle test-bundle.json test.txt

# 4️⃣ Verify it
sigstore verify github test.txt \
    --bundle test-bundle.json \
    --cert-identity https://github.com/YourUsername

You’ve just cryptographically signed your first file – now apply the same steps to your real releases.

Further Reading

  • Official Sigstore docs
  • GitHub + Sigstore integration guide
  • PC_Workman releases (examples)

Frequently Asked Questions

QuestionAnswer
What if my token is missing scopes?Ensure it has read:user and user:email.
What if the bundle filename doesn’t match the uploaded file?Use the exact --bundle name you upload (e.g., sigstore-bundle.json).
What should --cert-identity look like?Use the full URL: https://github.com/YourUsername.
I’m getting “module not found” errors.Activate the Python environment where you installed Sigstore, or install it globally (pip install --user sigstore).

TL;DR

  • Setup: pip install sigstore + GitHub PAT (read:user, user:email).
  • Sign: sigstore sign --bundle sigstore-bundle.json your-app.exe.
  • Release: Upload both files + a short verification guide.
  • Verify: Users run sigstore verify github … – no blind trust required.

Free, fast, and gives your users confidence that the executable truly comes from you. 🎉

Scanning & CodeQL Analysis

(link when published on Dev.to)

Part 2: Sigstore Signing

(this article)

Part 3: OpenSSF Best Practices Badge

(coming soon)

About Me

I’m Marcin, a solo developer building PC_Workman — an open‑source system‑monitoring tool.

  • Built on a dying 2014 laptop during warehouse shifts in the Netherlands.
  • 700+ hours, 4 complete rebuilds, finally shipped.
  • Documenting everything and shipping weekly.

Follow my build‑in‑public journey:

  • GitHub: @HuckleR2003
  • Twitter:
  • Everything about me:

Tags

#sigstore #python #security #opensource #buildinpublic

0 views
Back to Blog

Related posts

Read more »

Show HN: Simple org-mode web adapter

Org Web Adapter A lightweight local web app for browsing and editing Org files. The app is implemented as a single Python server main.py plus one HTML template...

dlt MCP Server for Popular IDEs

Overview This demo showcases how to set up and use the dlt MCP Server for data pipeline validation and inspection. The MCP server enables interactive querying...