Security Architecture

ProGit Marketplace uses the Hinge supply chain verification system from Janus, adapted for plugin distribution.

The Problem with Traditional Package Managers

❌ Typical Install Flow

# You see this
npm install express

# But the computer sees this
curl https://registry.npmjs.org/express/-/express-4.18.2.tgz \
  | npm install --legacy-peer-deps
  • ⚠️ No signature verification
  • ⚠️ No publisher identity check
  • ⚠️ Registry can serve anything
  • ⚠️ Supply chain attacks are trivial

✓ Hinge-Verified Flow

# You see this
prog plugin install sober-raccoon

# ProGit verifies:
# 1. Signature from trusted key
# 2. BLAKE3 checksum matches
# 3. Capability declarations honored
  • ✓ Dilithium3 signatures
  • ✓ Publisher KeyID verification
  • ✓ Content integrity guaranteed
  • ✓ Trust is explicit, not assumed

Core Concepts

🔑 KeyID

A publisher's identity is a content-addressed KeyID: the first 16 hex characters of blake3(public_key).

This means a key's identity is derived from its content, not assigned by a central authority.

✍️ Dilithium3 Signatures

Post-quantum digital signatures using the CRYSTALS-Dilithium3 algorithm. Future-proof against quantum computers.

Real Dilithium3 (ML-DSA-44 / FIPS 204) — post-quantum secure signatures.

🔗 Content Integrity

Every artifact is referenced by its BLAKE3 hash. If the bytes change, the hash changes. If the hash matches, the bytes are identical.

🎯 Capability Scoping

Plugins declare what they need: network access to specific hosts, filesystem access level, environment variables.

Capability enforcement is enforced at runtime by the plugin engine.

Verification Flow

1

User Clicks Deeplink

progit://install/sober-raccoon

Or runs: prog plugin install sober-raccoon

2

Fetch Manifest

Download manifest.json and manifest.sig from registry

3

Verify Signature

Using publisher's public key from keyring

blake3(manifest_json) == dilithium3_verify(pubkey, signature)
4

Check KeyID Trust

Is f04a5dcf0f9ffd2c in your trusted keyring?

~/.progit/keyring/keyring.json
5

Download & Verify Artifact

Fetch artifact, compute BLAKE3, compare to manifest

blake3(artifact) == manifest.artifact.checksum
6

Install

Plugin installed with verified integrity and declared capabilities

Trust Policies

ProGit supports multiple trust policies for different security postures:

Strict

Requires one valid signature from a trusted key.

hinge verify pkg.jpk --mode strict

Best for: Individual developers

Consensus

Requires N of M valid signatures from trusted keys.

hinge verify pkg.jpk --mode consensus --threshold 2/3

Best for: Organizations, high-security environments

Deeplinks: UX, Not Security

Important: Deeplinks like progit://install/plugin are user experience shortcuts, not security mechanisms.

⚠️ What deeplinks are NOT:

  • Not cryptographic proofs
  • Not integrity guarantees
  • Not tamper-evident
  • Not revocation channels

✓ What deeplinks ARE:

  • Convenient install triggers
  • Pointers to manifests
  • URL-encoded plugin names
  • The same as typing prog plugin install X

The security happens after the deeplink triggers the install: when ProGit fetches the manifest and runs Hinge verification.

CLI Reference

Trust Management

# Add a trusted publisher key
prog trust add https://registry.progit.dev/keys/core-team.pub

# List trusted keys
prog trust list

# Remove a trusted key
prog trust remove f04a5dcf0f9ffd2c

Plugin Verification

# Verify an installed plugin
prog plugin verify sober-raccoon

# Install with verification
prog plugin install sober-raccoon

Key Rotation (July 2026)

The original "ProGit Core Team" plugin-signing key (18a10eb52cf3c001) was a test artifact: it signed with a BLAKE3-based MAC mislabeled as dilithium3-test, with the shared secret hardcoded in public source. It has been replaced with a genuine ML-DSA-44 / Dilithiumium3 keypair:

If you trusted the old key: on your next prog plugin index update, ProGit verifies the rotated registry index and recognizes the rotatedFrom claim — the index is accepted (one-step bounded, signature-gated, stateless per-document trust). To then verify or install plugins signed by the new key, run:

prog trust add f04a5dcf0f9ffd2c

You'll see the hint after index update:

🔄 Registry index verified via key rotation from 18a10eb52cf3c001
   To trust plugins signed by the new key f04a5dcf0f9ffd2c, run:
   prog trust add f04a5dcf0f9ffd2c

Auto-promotion to direct trust was considered and rejected: the registry is a plain git repo over HTTPS, so a self-asserted rotatedFrom is not strong enough to permanently trust a key for all plugins. The index migration is stateless (per-document); trusting the new key for plugins is a deliberate one-command user action.