Implement signature enforcement for packages and images #56

Open
opened 2026-01-03 23:47:03 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-01-03 23:47:03 +00:00 (Migrated from github.com)

User Story

As a security-conscious developer, I want qctl to verify signatures on packages and container images so I can ensure I'm using authentic, untampered artifacts.

Design

Command Interface

# Verify package signature
qctl qbit verify @qrun/auth-sso

# Verify all installed packages
qctl qbit verify --all

# Verify container image
qctl qrun verify myapp:1.2.3

# Sign a package (for publishers)
qctl qbit sign ./my-package --key ~/.gnupg/secring.gpg

# Sign a container image (for publishers)
qctl qrun sign myapp:1.2.3 --key cosign.key

# Configure signature enforcement
qctl config set security.require_signatures true

Verification Output

Verifying @qrun/auth-sso@2.1.0...

Signature: Valid
  Signer: QRun Official <security@qrun.io>
  Key ID: 0x1234567890ABCDEF
  Signed: 2024-01-10T15:30:00Z

Integrity: Valid
  SHA-512: a1b2c3d4...
  Matches: lockfile

Package @qrun/auth-sso@2.1.0 verified successfully.

Signature Configuration

# ~/.qctl/qctl.yaml
security:
  require_signatures: true  # fail if unsigned
  warn_unsigned: true       # warn but continue
  trusted_keys:
    - id: "0x1234567890ABCDEF"
      name: "QRun Official"
      fingerprint: "ABCD 1234 5678 90AB CDEF..."
  cosign:
    public_key: ~/.qctl/cosign.pub
    rekor_url: https://rekor.sigstore.dev

Signature Storage

# Package signatures
vendor/qbits/@qrun/auth-sso/
├── auth-sso-2.1.0.jar
└── auth-sso-2.1.0.jar.asc  # PGP signature

# OCI image signatures (Sigstore)
# Stored in registry as separate artifact

Files to Create/Modify

File Action Purpose
qctl-core/src/main/java/io/qrun/qctl/core/security/SignatureVerifier.java Create Verification engine
qctl-core/src/main/java/io/qrun/qctl/core/security/PGPVerifier.java Create PGP signature verification
qctl-core/src/main/java/io/qrun/qctl/core/security/CosignVerifier.java Create Sigstore/cosign verification
qctl-core/src/main/java/io/qrun/qctl/core/security/TrustStore.java Create Trusted key management
qctl-core/src/main/java/io/qrun/qctl/core/security/model/Signature.java Create Signature model
qctl-qbit/src/main/java/io/qrun/qctl/qbit/VerifyCommand.java Create qbit verify command
qctl-qrun/src/main/java/io/qrun/qctl/qrun/VerifyCommand.java Create qrun verify command

Implementation Tasks

  • Create SignatureVerifier interface
  • Implement PGPVerifier using Bouncy Castle
  • Implement CosignVerifier for OCI images
  • Create TrustStore for managing trusted keys
  • Create qbit verify command
  • Create qrun verify command
  • Integrate verification into qbit add/update
  • Integrate verification into qrun publish
  • Add signature enforcement configuration
  • Support warn-only mode for gradual adoption
  • Bundle QRun public keys by default
  • Write unit tests for PGPVerifier
  • Write unit tests for CosignVerifier

Acceptance Criteria

  • qctl qbit verify <package> verifies PGP signature
  • qctl qrun verify <image> verifies cosign signature
  • Trusted keys configurable in qctl.yaml
  • require_signatures: true fails on unsigned artifacts
  • warn_unsigned: true warns but continues
  • Signature info shown during qbit add
  • Verification integrated into install flow
  • Clear error messages for verification failures
## User Story As a security-conscious developer, I want qctl to verify signatures on packages and container images so I can ensure I'm using authentic, untampered artifacts. ## Design ### Command Interface ```bash # Verify package signature qctl qbit verify @qrun/auth-sso # Verify all installed packages qctl qbit verify --all # Verify container image qctl qrun verify myapp:1.2.3 # Sign a package (for publishers) qctl qbit sign ./my-package --key ~/.gnupg/secring.gpg # Sign a container image (for publishers) qctl qrun sign myapp:1.2.3 --key cosign.key # Configure signature enforcement qctl config set security.require_signatures true ``` ### Verification Output ``` Verifying @qrun/auth-sso@2.1.0... Signature: Valid Signer: QRun Official <security@qrun.io> Key ID: 0x1234567890ABCDEF Signed: 2024-01-10T15:30:00Z Integrity: Valid SHA-512: a1b2c3d4... Matches: lockfile Package @qrun/auth-sso@2.1.0 verified successfully. ``` ### Signature Configuration ```yaml # ~/.qctl/qctl.yaml security: require_signatures: true # fail if unsigned warn_unsigned: true # warn but continue trusted_keys: - id: "0x1234567890ABCDEF" name: "QRun Official" fingerprint: "ABCD 1234 5678 90AB CDEF..." cosign: public_key: ~/.qctl/cosign.pub rekor_url: https://rekor.sigstore.dev ``` ### Signature Storage ``` # Package signatures vendor/qbits/@qrun/auth-sso/ ├── auth-sso-2.1.0.jar └── auth-sso-2.1.0.jar.asc # PGP signature # OCI image signatures (Sigstore) # Stored in registry as separate artifact ``` ## Files to Create/Modify | File | Action | Purpose | |------|--------|---------| | `qctl-core/src/main/java/io/qrun/qctl/core/security/SignatureVerifier.java` | Create | Verification engine | | `qctl-core/src/main/java/io/qrun/qctl/core/security/PGPVerifier.java` | Create | PGP signature verification | | `qctl-core/src/main/java/io/qrun/qctl/core/security/CosignVerifier.java` | Create | Sigstore/cosign verification | | `qctl-core/src/main/java/io/qrun/qctl/core/security/TrustStore.java` | Create | Trusted key management | | `qctl-core/src/main/java/io/qrun/qctl/core/security/model/Signature.java` | Create | Signature model | | `qctl-qbit/src/main/java/io/qrun/qctl/qbit/VerifyCommand.java` | Create | qbit verify command | | `qctl-qrun/src/main/java/io/qrun/qctl/qrun/VerifyCommand.java` | Create | qrun verify command | ## Implementation Tasks - [ ] Create SignatureVerifier interface - [ ] Implement PGPVerifier using Bouncy Castle - [ ] Implement CosignVerifier for OCI images - [ ] Create TrustStore for managing trusted keys - [ ] Create qbit verify command - [ ] Create qrun verify command - [ ] Integrate verification into qbit add/update - [ ] Integrate verification into qrun publish - [ ] Add signature enforcement configuration - [ ] Support warn-only mode for gradual adoption - [ ] Bundle QRun public keys by default - [ ] Write unit tests for PGPVerifier - [ ] Write unit tests for CosignVerifier ## Acceptance Criteria - [ ] `qctl qbit verify <package>` verifies PGP signature - [ ] `qctl qrun verify <image>` verifies cosign signature - [ ] Trusted keys configurable in qctl.yaml - [ ] `require_signatures: true` fails on unsigned artifacts - [ ] `warn_unsigned: true` warns but continues - [ ] Signature info shown during qbit add - [ ] Verification integrated into install flow - [ ] Clear error messages for verification failures
Sign in to join this conversation.