Seekmodo developer docs
Reference for the REST shim, MCP JSON-RPC surface, and storefront connectors. Authenticate with HMAC; replay window is 5 minutes.
Release-signing keys
Every Seekmodo connector zip is signed with an ed25519 keypair so you can verify, before installing, that the file you downloaded is the same file we built. This page covers the public-key inventory, how to verify a zip, and how rotations are handled.
Looking for the machine-readable JWK set? /.well-known/release-signing-keys.json is the live transparency endpoint.
Trust model — one paragraph
Every release zip ships with a vendored copy of the ed25519 public key it was signed with — the WordPress connector at assets/release-signing-keys/<kid>.pub, the Zen Cart connector at zc_plugins/Seekmodo/v<X.Y.Z>/admin/release-signing.pub. The in-plugin updater loads the vendored public key at install time and uses it to validate the detached signature on every subsequent auto-update. Trust is bootstrapped at install (the zip you download trusts itself), not at runtime — there is no network fetch of trust roots. The JWK set at /.well-known/release-signing-keys.json is for human transparency and operator-side verification only; in-plugin verifiers do not consult it.
Why a kid system
Each keypair carries a stable kid (key identifier) of the form seekmodo-YYYY-MM (with an optional -r<n> revision suffix when a mid-cycle re-key is required). Manifest entries and zip signatures embed the kid, so an operator verifying a download knows which public key to validate against without guessing.
Each kid carries a status in the JWK set:
- active — what the build pipeline signs new releases under.
- accepted — still trusted by in-plugin verifiers; older releases signed under this kid stay verifiable, but new releases are not minted here.
- retired — present for historical / audit purposes only; the in-plugin verifier would refuse such a signature anyway.
Verifying a download
For day-to-day installs the SHA-256 sidecar shipped next to the zip is sufficient (the install guides walk through this). For higher-assurance verification — e.g. before rolling a release across a fleet — the detached ed25519 signature can be verified against the published public key.
# Download the zip + its sidecars.
curl -fLO https://seekmodo.com/plugins/seekmodo-wordpress-v0.4.0.zip
curl -fLO https://seekmodo.com/plugins/seekmodo-wordpress-v0.4.0.zip.sha256
curl -fLO https://seekmodo.com/plugins/seekmodo-wordpress-v0.4.0.zip.sig
# 1. SHA-256 sidecar (everyone should do this).
sha256sum -c seekmodo-wordpress-v0.4.0.zip.sha256
# 2. ed25519 signature (high-assurance / fleet rollouts).
# The kid that signed this release is in /plugins/manifest.json
# under the matching platform's entry. Look it up here:
curl -fsS https://seekmodo.com/.well-known/release-signing-keys.json | jq '.keys[] | select(.status == "active") | {kid, x}'
# Verify with the published kid's "x" value (32 raw ed25519 bytes,
# base64url-no-pad). Any standard ed25519 library works:
python -c '
import base64, sys
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
x = "<paste the x from the JWK above>"
pub = Ed25519PublicKey.from_public_bytes(base64.urlsafe_b64decode(x + "=="))
sig = open("seekmodo-wordpress-v0.4.0.zip.sig", "rb").read()
data = open("seekmodo-wordpress-v0.4.0.zip", "rb").read()
pub.verify(sig, data)
print("OK")
'A successful verification prints OK; any tampering raises cryptography.exceptions.InvalidSignature.
Rotations
Rotations happen on a scheduled cadence (annually, June- ish, matching the kid's -YYYY-MM suffix) or on demand for any of: compromise of a private key, loss of operator access to a private key, or a vendor decision to rotate for hygiene reasons.
The practical consequence of bootstrapping trust at install is that rotating to a new kid requires a plugin update that vendors the new kid's public key into the connector tree. Already-installed copies cannot accept a release signed under a kid they didn't ship with — so a rotation rolls out as a multi-phase migration:
- Generate the new keypair operator-locally and update this page + the JWK set.
- Cut a release of every connector under the old kid that also vendors the new public key (so existing installs auto-update and pick up the new trust root).
- Wait for the install base to upgrade (~1 week dwell).
- Flip the active kid in the build pipeline. New releases sign under the new kid; auto-update verifies cleanly because every install received the Phase 2 trust root.
- Eventually retire the old kid by dropping it from new connector releases.
When a kid was burned mid-cycle without time for a clean multi-phase rotation, an -r<n> revision suffix is used (e.g. seekmodo-2026-06-r2) and the previous revision is demoted from active to accepted so older installs that already pinned the old kid keep verifying their already-installed zip.
If you see a refusal banner from your connector's Updates page
Either the in-plugin trust root is older than the kid that signed the latest release, or the zip on disk has been tampered with after download. The diagnostic is:
- Check the JWK set above for the kid the latest release was signed under (the manifest entry exposes this).
- Compare with the vendored pubkey inside the connector (path varies by connector, see Trust model above).
- If the kid in the manifest is newer than what your connector trusts, perform the one-time manual upgrade documented in the connector's install guide — Zen Cart install covers this for the Zen Cart side.
Want a deep look at the rotation plumbing or have a key- handling concern? Email [email protected] — see also our security disclosure policy.