Skip to content
GravityKit
Buy
Sign in
0 items
  • Plugins

    GravityKit All Access

    Our complete Kit of essential tools for extending and enhancing Gravity Formsโ€”everything you need to build powerful web apps and workflows.

    Learn more
    • GravityView

      GravityView

      Bestseller

      Display Gravity Forms entries on the front-end of your site and build powerful web applications.

    • GravityImport

      GravityImport

      Trending

      Import entries from CSV files into Gravity Forms to transfer data, create new forms, or update existing entries.

    • GravityEdit

      GravityEdit

      Quickly edit Gravity Forms entries inline to save time, reduce clicks, and streamline your workflow.

    • GravityCharts

      GravityCharts

      Trending

      Turn Gravity Forms entries into interactive charts and graphs.

    • GravityActions

      GravityActions

      Update multiple Gravity Forms entries at once, send bulk emails, and streamline your workflow.

    • GravityCalendar

      GravityCalendar

      Turn Gravity Forms entries into dynamic calendars to showcase events, schedules, appointments, and more.

    • GravityExport

      GravityExport

      Export Gravity Forms entries to Excel, CSV, or PDF and share them instantly with secure download links.

    • GravityMath

      GravityMath

      Perform advanced calculations on Gravity Forms entries to display totals, averages, or build custom calculators.

    • GravityRevisions

      GravityRevisions

      Track, compare, and restore changes made to Gravity Forms forms and entries with a full version history.

    • GravityMigrate

      GravityMigrate

      Migrate all Gravity Forms data, including forms, entries, Views, feeds, uploads, and more.

    • GravityBoard

      GravityBoard

      Manage projects with collaborative project management. Coordinate with your team and streamline your workflows.

  • Ideal For

    • Nonprofits
    • Web Agencies
    • Education
    • Developers
    • Small Businesses
    • Startups
    Explore All Use Cases

    Case studies

    • West Fork Schools
    • Princeton University
    • BrightLeaf Giving
    • Jacksonville Port Authority
    • National Severe Storms Lab
    • Leadpal
    • Mediebruket
    • Dragonfly
    View All Case Studies
  • Resources

    • Blog
    • Case studies
    • Support
    • Live Demos
    • Documentation
    • Developer docs
    • GravityKit Academy
    • GravityKit Live!

    Ultimate guides

    • How to use Gravity Forms
    • Editing Gravity Forms entries
    • Importing Gravity Forms entries
    • Exporting Gravity Forms entries
    • Displaying Gravity Forms entries
    • Gravity Forms conditional logic
    • Gravity Forms calculations
    View More Articles
  • Plugins

    • GravityView

      GravityView

      Bestseller

      Display Gravity Forms entries on the front-end of your site and build powerful web applications.

    • GravityImport

      GravityImport

      Trending

      Import entries from CSV files into Gravity Forms to transfer data, create new forms, or update existing entries.

    • GravityEdit

      GravityEdit

      Quickly edit Gravity Forms entries inline to save time, reduce clicks, and streamline your workflow.

    • GravityCharts

      GravityCharts

      Trending

      Turn Gravity Forms entries into interactive charts and graphs.

    • GravityActions

      GravityActions

      Update multiple Gravity Forms entries at once, send bulk emails, and streamline your workflow.

    • GravityCalendar

      GravityCalendar

      Turn Gravity Forms entries into dynamic calendars to showcase events, schedules, appointments, and more.

    • GravityExport

      GravityExport

      Export Gravity Forms entries to Excel, CSV, or PDF and share them instantly with secure download links.

    • GravityMath

      GravityMath

      Perform advanced calculations on Gravity Forms entries to display totals, averages, or build custom calculators.

    • GravityRevisions

      GravityRevisions

      Track, compare, and restore changes made to Gravity Forms forms and entries with a full version history.

    • GravityMigrate

      GravityMigrate

      Migrate all Gravity Forms data, including forms, entries, Views, feeds, uploads, and more.

    • GravityBoard

      GravityBoard

      Manage projects with collaborative project management. Coordinate with your team and streamline your workflows.

    GravityKit All Access

    Our complete Kit of essential tools for extending and enhancing Gravity Formsโ€”everything you need to build powerful web apps and workflows.

    Learn more
  • Ideal For

    • Nonprofits
    • Web Agencies
    • Education
    • Developers
    • Small Businesses
    • Startups
    Explore All Use Cases

    Case studies

    • West Fork Schools
    • Princeton University
    • BrightLeaf Giving
    • Jacksonville Port Authority
    • National Severe Storms Lab
    • Leadpal
    • Mediebruket
    • Dragonfly
    View All Case Studies

    How to build...

    • Property Management
    • Product Catalog
    • Fundraising Dashboard
    • Real Estate Directory
    • Document Library
    • Academic Journal
    • Volunteer Management
    • Meal Tracker
    View All Guides
  • Resources

    • Blog
    • Case studies
    • Support
    • Live Demos
    • Documentation
    • Developer docs
    • GravityKit Academy
    • GravityKit Live!

    ultimate guides

    • How to use Gravity Forms
    • Editing Gravity Forms entries
    • Importing Gravity Forms entries
    • Exporting Gravity Forms entries
    • Displaying Gravity Forms entries
    • Gravity Forms conditional logic
    • Gravity Forms calculations
    View More Articles
  • Pricing
  • About
0 items

Search

Results appear automatically as you type.
Loading results…

results found matching

    Sign in
    Buy

    Docs

    • Docs Home

    Gravity Forms Add-Ons

    • GravityView
    • GravityActions
    • GravityBoard
    • GravityCalendar
    • GravityCharts
    • GravityEdit
    • GravityExport
    • GravityImport
    • GravityMath
    • GravityMigrate
    • GravityRevisions
    • GF Widget for Elementor
    • GF Dynamic Lookup
    • GF Entry Tags
    • GF Event Field
    • GF Zero Spam
    • GravityExport Lite

    GravityView

    • Getting Started
    • View Setup
    • FAQ
    • Pre-Sale
    • Advanced
    • Common Problems
    • Customizing Your Views
    • Edit Entry
    • Entry Approval
    • Filter and Sort Results
    • Gravity Forms
    • Merge Tags
    • Roles and Capabilities
    • Search
    • Shortcodes
    • View Settings
    • WordPress Posts

    General Help

    • Account, Invoices, and Billing
    • License Related
    • Plugins and Settings
    • Contact
    • Docs Home
    • Gravity Forms Add-Ons

      • GravityView
      • GravityActions
      • GravityBoard
      • GravityCalendar
      • GravityCharts
      • GravityEdit
      • GravityExport
      • GravityImport
      • GravityMath
      • GravityMigrate
      • GravityRevisions
      • GF Widget for Elementor
      • GF Dynamic Lookup
      • GF Entry Tags
      • GF Event Field
      • GF Zero Spam
      • GravityExport Lite
    • GravityView

      • Getting Started
      • View Setup
      • FAQ
      • Pre-Sale
      • Advanced
      • Common Problems
      • Customizing Your Views
      • Edit Entry
      • Entry Approval
      • Filter and Sort Results
      • Gravity Forms
      • Merge Tags
      • Roles and Capabilities
      • Search
      • Shortcodes
      • View Settings
      • WordPress Posts
    • General Help

      • Account, Invoices, and Billing
      • License Related
      • Plugins and Settings
    • Contact

    General Help

      • Downloading a copy of your invoice
      • GravityKit W-9 Form (Tax ID)
      • Invoice information is incorrect
      • Nonprofit pricing
      • Refunds
      • Transferring your license
      • Turning off auto-renew subscriptions
      • Understanding Time-Based Proration for License Upgrades
      • Update your invoice with company name, address, or VAT number
      • Upgrading your license
      • Your GravityKit Account page
      • About the “GravityView + Extensions (Legacy)” license
      • Can’t deactivate license key
      • Development websites and GravityKit licenses
      • Downgrading your license
      • Granting GravityKit Support Access to Your Website
      • GravityKit pricing updates FAQ
      • Hard-coding your license key
      • Is PDF for GravityView included in All Access?
      • Managing GravityKit Products and Licenses via WP-CLI
      • Managing Your Licenses
      • Multisite and GravityKit Licenses
      • Products show as unlicensed
      • The license key keeps disappearing
      • Transferring your license
      • Upgrading your license
      • GravityKit code signing: technical overview
      • How to Get the Most Out of GravityKit Support
      • How to hide the “Function _load_textdomain_just_in_time was called incorrectly” notice
      • How To Import App Templates to Your Site
      • Installing standalone plugins
      • Installing, Activating, and Updating GravityKit Plugins
      • Locating and Updating Settings for GravityKit Products
      • Managing GravityKit Products and Licenses via WP-CLI
      • The “Download failed. Unauthorized” message
    • Home
    • Docs
    • General Help
    • Plugins and Settings
    • GravityKit code signing: technical overview

    GravityKit code signing: technical overview

    Estimated reading: 6 minutes

    Updated on May 12, 2026

    This is the architecture-level companion to GravityKit products now give you a stronger reason to trust what you install. That post explains what changed and why a customer should care; this one is for readers who want the mechanics: the signing pipeline end-to-end, where verification hooks into WordPress’s update flow, how we manage and rotate keys, how revocation works, and what the design deliberately does not try to solve.

    In plain terms: GravityKit products distributed through gravitykit.com are cryptographically signed at build time, and the signature is verified on the customer site before WordPress unpacks the ZIP. The verifier lives in Foundation, the shared library bundled inside every GravityKit product; GravityView 2.57 is the first to carry it. Because the newest copy of Foundation on a site becomes the active one, a single product update lifts protection across all other GravityKit products already on the same install.

    The pipeline #

    Signing happens once, inside a controlled build environment. Verification happens on every install attempt. Between those two ends sit three independent components, each running in its own security context:

    • Build pipeline. Builds the plugin ZIP, then signs it with the active package key. The output is a signature triplet โ€” sha256, signature, signing_key_id โ€” written alongside the ZIP filename. The signing tool re-verifies what it just produced before continuing; any failure aborts the run and nothing is published.
    • Distribution backend. Stores the triplet against the build record and serves it through our Store API. This layer is not trusted to alter ZIP bytes or signing metadata inconsistently: a mismatched filename, hash, signature, or key ID fails verification on the customer site. The distribution backend still participates in release selection, so it is separately hardened and the Store API fails closed on incomplete integrity records.
    • Foundation on the customer site. Hooks to upgrader_pre_download early in WP_Upgrader‘s download phase. Foundation downloads the ZIP itself, or verifies the temp file if an earlier WordPress filter has already provided one. It hashes the bytes that will be unpacked, pulls the expected triplet from the Store API, and runs the signature check. Any mismatch โ€” missing signature, hash mismatch, invalid signature, or revoked key โ€” stops the install before unpacking starts.

    GravityKit-managed downloads are accepted only from HTTPS GravityKit-controlled hosts. If an install or update is identified as a GravityKit product but points at an untrusted host, Foundation blocks it instead of passing it through to WordPress unsigned.

    Two cryptographic primitives do the actual work: Ed25519 for the signature, SHA-256 for the file hash. Ed25519 is the digital-signature algorithm used by SSH, TLS 1.3, age, minisign, and many contemporary code-signing systems โ€” fast to verify, 64-byte signatures, 32-byte public keys, and none of the per-call randomness pitfalls that have produced real-world breaks in older signature schemes.

    The signature is not computed over the ZIP directly. The SHA-256 of the ZIP is embedded inside a structured envelope, and the envelope is what gets signed, so the signature transitively binds to the file’s bytes through the hash:

    gk.sig.v1.pkg:ed25519:{key_id}:{"filename":"...","sha256":"..."}

    The body is canonical JSON (sorted keys and no whitespace). That makes the bytes a verifier reconstructs match the bytes the signer produced exactly, and prevents a filename containing a colon from tricking a parser into reading part of it as a different field. The pkg purpose tag exists so a package signature cannot be replayed as a revocation manifest signature even with the same key. The key_id is regex-validated (/\A[a-z0-9-]{1,64}\z/) at both build and verify time so a hostile key ID cannot smuggle in extra colons and shift the meaning of the header.

    Three keys, three roles #

    The trust anchor is a small, fixed set of keys with strictly separated jobs.

    RoleWhat it does
    Active package keySigns every release shipping today.
    Pre-staged successorThe next package key. Public half is already shipped inside Foundation; the private half stays offline until rotation.
    Revocation rootSigns the revocation manifest only. Held separately; never used to sign packages.

    Package key trust is local. Public keys ship inside Foundation, so there is no runtime key fetch on the package path. That is also what makes the pre-staged successor work: when the time comes to rotate, we promote it from pre-staged to active and retire the previous active key. Customers do not need a Foundation update to trust the new key โ€” that trust was distributed in advance.

    Key lookups enforce three things: purpose match, algorithm match, and status filter. A package key can never resolve as the revocation root. Retired keys never resolve, so retirement immediately invalidates every package signed with that key identity.

    Revocation #

    A separately signed manifest, hosted on a verify-only endpoint and produced with the revocation root key. Customer sites fetch it at frequent intervals. The body is small JSON (a list of revoked key IDs) capped at 256 KB so a runaway upstream cannot exhaust memory on the verifier.

    Failure handling is deliberate:

    • First successful verify result is copied to a durable, network-scoped store โ€” the last-known-good manifest body.
    • Every verified revoked key ID is also copied into a durable, network-scoped set. This set is checked before the network path, so a key once observed revoked by that site stays blocked even if an older signed manifest is later replayed.
    • Fetch or signature-verify failure with a stored last-known-good: serve it back and re-prime the cache for 30 minutes. A hostile CDN serving a forged clean manifest cannot overwrite the trusted body: we reject the forged copy, and the stored one persists.
    • Either failure on cold start with nothing ever stored: cache an empty list briefly so a transient first-fetch failure does not permanently block updates. Source-baked revoked keys still apply in this state.

    The asymmetric property is precise: on Foundation versions with durable revocation memory, an attacker with sustained MITM cannot un-revoke a key that the site has already observed in a verified manifest. They can still delay delivery of a new revocation to a cold site that has never received it. For emergency cases, Foundation can also ship with a source-baked list of revoked keys so the block applies even before the remote manifest is reachable.

    What this does and does not protect #

    This protects customers from modified ZIP bytes, missing or mismatched signing metadata, invalid signatures, revoked package keys, untrusted GravityKit download hosts, and WordPress download-path short-circuits that would otherwise bypass the verifier.

    It does not claim that the Store API is a cryptographic release ledger. The package signature binds the ZIP filename and SHA-256 hash; the distribution system still decides which signed release is offered to a site. That release-selection path is operationally hardened, but it is not the same thing as signing product/channel/version metadata as a separate artifact.

    WordPress’s own signing โ€” and why it is not this #

    WordPress added a code path for cryptographic signature verification in 5.2 (May 2019). The function verify_file_signature() in wp-admin/includes/file.php is wired into core’s download path and uses Ed25519 over SHA-384. In practice, it has been non-operational as a blocking plugin-package integrity system.

    The history makes the reason clear. Signature verification arrived in changeset 44954 on March 21, 2019, six weeks before 5.2 shipped. The commit message labels the feature “experimental package signing” with “soft verification” โ€” and the wp_signature_softfail filter that arrived in the same changeset defaults to soft-fail behavior. Verification failures are demoted to a telemetry report and a non-blocking warning; WP_Upgrader::run() carries a “Pretend this error didn’t happen” path before continuing the install.

    Plugins were taken out of the picture inside the same release cycle. Changeset [45262] disabled plugin signature verification entirely after math errors on specific PHP/opcache combinations. Tellyworth’s commit note: “At the 5.2 release the API servers will only provide signatures for core update packages.” That note is from 2019. The state hasn’t changed.

    None of this gave us a foundation to build on, so we built our own. We would happily reti re it the day a shared signing model (core’s,ย FAIR’s, or whatever comes next) emerges that fits plugin distribution outside the .org directory.

    This is one layer. Other parts of how our products are built and shipped get continuous hardening too โ€” most of it invisible from a customer’s vantage point, all of it ongoing.

    If you have any questions, please reach out to support.

    Still stuck? How can we help?

    How can we help?

    "*" indicates required fields

    This field is for validation purposes and should be left unchanged.
    Replies will go to this email.
    How can we help?*
    My pre-sale question is related to...*
    My WordPress skills are....*
    My Gravity Forms skills are...*
    You will be shown articles from our documentation.
    Vous pouvez nous รฉcrire dans votre langue maternelle si cโ€™est plus facile pour vousโ€”nous nous occuperons de la traduction!
    Puedes escribirnos en tu idioma nativo si te resulta mรกs fรกcil; ยกnosotros nos encargamos de la traducciรณn!
    Sie kรถnnen uns in Ihrer Muttersprache schreiben, wenn das fรผr Sie einfacher ist โ€“ wir kรผmmern uns um die รœbersetzung!
    U kunt ons in uw moedertaal schrijven als dat gemakkelijker voor u is โ€” wij zorgen voor de vertaling!
    Du kan skrive til oss pรฅ ditt morsmรฅl hvis det er enklere for deg โ€” vi tar oss av oversettelsen!
    Du kan skriva till oss pรฅ ditt modersmรฅl om det รคr lรคttare fรถr dig โ€” vi tar hand om รถversรคttningen!
    Vocรช pode nos escrever em seu idioma nativo se for mais fรกcil para vocรช โ€” nรณs cuidaremos da traduรงรฃo!
    Puoi scriverci nella tua lingua madre se ti รจ piรน facile โ€” penseremo noi alla traduzione!
    Please provide as much detail as you're able; this helps us provide you with faster support.
    Drop files here or
    Accepted file types: jpg, jpeg, gif, png, tiff, pdf, bmp, zip, json, csv, xls, xlsx, Max. file size: 256 MB.
      Stay informed?

      Was this page helpful?

      Table Of Contents
      • The pipeline
      • Three keys, three roles
      • Revocation
      • What this does and does not protect
      • WordPress’s own signing โ€” and why it is not this
      GravityKit
      • How to Build It
      • Pricing
      • Products
      • Our Team
      • Our Values
      • Work With Us
      • Coupons
      Support
      • Support
      • Contact
      • Documentation
      • Scope of Support
      • Brand Guidelines
      • Privacy Policy
      • Terms of Service (โ€œTermsโ€)
      I am a...
      • Nonprofit
      • Web agency
      • Small business owner
      • Web developer
      • Educational institution
      • WordPress freelancer
      • Startup founder
      • One-person agency
      Get notified of updates.

      Weโ€™re constantly improving GravityKit. Fill out your email below and weโ€™ll notify you anytime major updates drop.

      • Facebook
      • Twitter
      • Mastodon
      GravityKit is a Gravity Forms Certified Developer.

      Copyright ยฉ 2026, Katz Web Services, Inc.

      GravityKit and GravityView are registered trademarks of Katz Web Services, Inc.