How to Sign Your Python .exe With Sigstore (No Certificate Required)
The problem: You built an open-source app. Users download your .exe. How do they know it's actually from you and hasn't been tampered with?
Traditional solution: Buy a code signing certificate. Cost: $200-400/year.
Better solution: Sigstore. Free, open source, cryptographically secure.
This is how I sign every PC_Workman release. Takes 8 minutes to set up, 30 seconds per release.
Why This Matters
Someone could:
- Clone your GitHub repo
- Add malware to your code
- Compile a fake
.exe - Distribute it claiming it's yours
Users have no way to verify authenticity without code signing.
Sigstore solves this:
- ✅ Proves the file came from your GitHub account
- ✅ Proves it hasn't been modified since signing
- ✅ Provides cryptographic proof anyone can verify
- ✅ Completely free
What You'll Need
- Python project compiled to
.exe(PyInstaller, Nuitka, etc.) - GitHub account
- 8 minutes
That's it. No credit card, no certificate purchase, no annual fees.
Step 1: Install Sigstore
pip install sigstore
That's the entire installation. Sigstore is a Python package.
Verify installation:
sigstore --version
Expected output: sigstore, version X.X.X
Step 2: Generate GitHub Token
Sigstore authenticates via GitHub OAuth, but you need a token first.
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
Click "Generate new token (classic)"
Required scopes:
- ✅
read:user - ✅
user:email
Token expiration: Set to "No expiration" (for ongoing releases)
Copy the token. You'll only see it once.
Store it securely:
Linux/Mac
export GITHUB_TOKEN="your_token_here"
Windows (PowerShell)
$env:GITHUB_TOKEN="your_token_here"
Or save in password manager and paste when needed.
Step 3: Sign Your .exe
Navigate to your release directory:
cd /path/to/your/releases
Sign the file:
sigstore sign \
--bundle sigstore-bundle.json \
PC_Workman_HCK.exe
Replace PC_Workman_HCK.exe with your filename.
What happens:
- Sigstore opens browser for GitHub OAuth
- You authorize the app
- Sigstore generates cryptographic signature
- Creates
sigstore-bundle.json(the signature file)
Time: ~30 seconds
Output files:
-
PC_Workman_HCK.exe(unchanged) -
sigstore-bundle.json(signature proof)
Step 4: Upload Both Files to GitHub Release
When creating a GitHub release:
Files to include:
-
PC_Workman_HCK.exe(your executable) -
sigstore-bundle.json(signature) -
VERIFICATION.md(instructions for users - see below)
Example release structure:
PC_Workman_v1.6.4/
├── PC_Workman_HCK.exe
├── sigstore-bundle.json
├── VERIFICATION.md
└── README.md
Step 5: Create Verification Instructions for Users
Create VERIFICATION.md in your release:
Verifying This Release
Install Sigstore
pip install sigstore
Verify Signature
sigstore verify github PC_Workman_HCK.exe \
--bundle sigstore-bundle.json \
--cert-identity https://github.com/YourUsername
Expected Output
Signature verified successfully
What This Proves
- ✅ File came from @YourUsername GitHub account
- ✅ File hasn't been modified since signing
- ✅ Signing happened on [date]
Replace YourUsername with your actual GitHub username.
How Verification Works (User Side)
Your users run:
sigstore verify github your-app.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 modified since signing?
- Timestamp: When was this signed?
Success output:
Verified OK: PC_Workman_HCK.exe
Failure output:
Verification failed: signature invalid
No trust required. Pure cryptography.
Real-World Example: PC_Workman
Every PC_Workman release includes:
-
The executable (
PC_Workman_HCK.exe) -
Sigstore bundle (
sigstore-bundle.json) - Security report (VirusTotal scan results)
- Verification guide (how to verify)
My release checklist:
1. Build executable
pyinstaller main.py
2. Sign with Sigstore
sigstore sign --bundle sigstore-bundle.json dist/PC_Workman_HCK.exe
3. Scan on VirusTotal
(manual upload to virustotal.com)
4. Create GitHub release
Upload: .exe + bundle + security report
5. Update documentation
Link to verification guide
Time per release: 5-10 minutes total.
Beyond Basic Signing
Automated Signing in CI/CD
You can integrate Sigstore into GitHub Actions:
name: Release
on:
release:
types: [created]
jobs:
sign-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Sigstore
run: pip install sigstore
- name: Sign executable
run: |
sigstore sign \
--bundle sigstore-bundle.json \
dist/your-app.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload signed files
uses: actions/upload-artifact@v3
with:
name: signed-release
path: |
dist/your-app.exe
sigstore-bundle.json
Result: Every release = automatically signed.
Adding More Trust Signals
Sigstore proves the file came from your GitHub. But how do users know YOU'RE legitimate?
1. ORCID iD (Persistent Identity)
Register at orcid.org
- Persistent digital identity for researchers/developers
- Link to GitHub profile
- Proves you're a real person
2. GitHub Developer Program
Apply at github.com/developer
- Shows commitment to open source
- Requires public profile + active projects
- Free membership
3. OpenSSF Best Practices Badge
Apply at bestpractices.coreinfrastructure.org
- 60+ security criteria
- Comprehensive security audit
- Industry-recognized badge
Together: These create a web of trust.
Common Issues & Fixes
"GitHub OAuth failed"
Solution: Check your GitHub token has read:user and user:email scopes.
"Bundle file not found"
Solution: Make sure --bundle filename matches what you upload to releases.
"Verification failed: certificate identity mismatch"
Solution: --cert-identity must match exact GitHub URL. Use https://github.com/YourUsername, not github.com/YourUsername.
"Command not found: sigstore"
Solution: Activate the Python environment where you installed Sigstore, or install globally.
Why I Actually Did This
I was tired of people asking "how do I know this is safe?"
Not because they're paranoid. Because they're smart. Running .exe files from unknown people IS risky.
Sigstore gives users the option to verify. No blind trust required. Just math.
Setup time: 8 minutes
Per-release time: 30 seconds
Cost: $0
User confidence: Significantly improved
Worth it.
The Complete Security Stack
For PC_Workman, I combine:
- VirusTotal scanning (70 antivirus engines) - Part 1 article
- Sigstore signing (this article)
- CodeQL analysis (GitHub security scanning)
- OpenSSF Best Practices (working toward badge) - Part 3 coming soon
None of this prevents bugs. None of it proves bug-free code.
But it proves I'm serious about security and transparency.
Users can verify for themselves. That's what matters.
Try It Yourself
5-minute challenge:
- Install Sigstore:
pip install sigstore - Create a test file:
echo "test" > test.txt - Sign it:
sigstore sign --bundle test-bundle.json test.txt - Verify it:
sigstore verify github test.txt --bundle test-bundle.json --cert-identity https://github.com/YourUsername
You just cryptographically signed your first file.
Now apply this to your actual releases.
Resources
Official Sigstore docs: docs.sigstore.dev
GitHub integration guide: GitHub + Sigstore
PC_Workman releases (examples): GitHub Releases
Questions? Drop them below. I'll answer every one.
About This Series
This is Part 2 of 3 in the PC_Workman Security Series:
- Part 1: VirusTotal 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, 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.
Follow my build-in-public journey:
- GitHub: @HuckleR2003
- Twitter: https://x.com/hck_lab
- Everything about me: https://linktr.ee/marcin_firmuga
Building in public. Documenting everything. Shipping weekly.




Top comments (0)