Skip to content

Plugin signing: sigstore verification + identity match + air-gapped cosign fallback #233

Description

@tayebmokni

Summary

Implement plugin signature verification using sigstore (keyless OIDC). At install: verify the sigstore bundle against the bundled WASM hash, resolve the signing identity (e.g. name@acme.dev via GitHub OIDC), check identity matches manifest author, check identity matches the registry record for the slug. Refuse if any check fails.

For air-gapped installs, support offline cosign-key verification as a fallback; operators configure a local trust root.

Open question §15.5: air-gapped sigstore is unresolved. Needs docs/proposals/ design.

Design reference

  • docs/02-plugin-system.md §10.2, §15.5 (air-gapped open question)

Acceptance criteria

  • Bundle layout includes server/plugin.wasm.sig (sigstore bundle JSON)
  • At install, verifier uses sigstore-go client to:
    • Verify the bundle signature against the WASM SHA-256
    • Verify the Fulcio cert chain
    • Verify the Rekor inclusion proof (transparency log)
    • Extract the signing identity (subject)
  • Identity match: signing identity equals manifest author.email OR matches a domain in the configured publisher allowlist for the slug
  • Registry-record check: for plugins installed via the official registry, identity must match the registrys canonical_publisher for the slug
  • Hash check: bundle SHA-256 stored at install, mismatch on subsequent load = refuse to load (disabled_by_policy)
  • Air-gapped fallback: if operator configures signing.mode = offline, verifier accepts cosign-key signatures against a configured trust root (PEM bundle of trusted public keys). Sigstore checks skipped. needs-design: §15.5 — propose key-distribution story in docs/proposals/airgap-plugin-signing.md
  • All verification failures emit audit log + admin-visible error with specifics
  • Tests: valid sigstore signature accepted; tampered WASM rejected; identity mismatch rejected; air-gapped mode with valid local key accepted; air-gapped mode with wrong key rejected

Dependencies

#27 (bundle parser), #34 (manifest validator)

Complexity

L

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions