Greater Atlanta's IT partner since 1989

Setup guide

Setup

Install AJC Form Guard, add its field to your Gravity Forms, and choose a challenge.

Version 1.2.1 · WordPress 6.0+ · PHP 8.1+ · Licensed GPL-2.0-or-later

Install

  1. Download the latest package from plugins.ajcomputers.com/ajc-form-guard.
  2. Plugins → Add New → Upload Plugin, then activate.
  3. Updates arrive automatically from this site after that. They are Ed25519 signed and verified before the package is unpacked; an unsigned or hash-mismatched package is refused rather than installed.

Gravity Forms 2.5 or newer must be active. If it is not, Form Guard stays dormant — it registers nothing, filters nothing, and says so with an admin notice.

Add the field to a form

This is not optional, and it is the single most common reason a site sees less filtering than it expected.

Seven of the ten checks run on every submission to every form as soon as the plugin is activated, with nothing to configure. Three of them need the Form Guard field on the form, because the field is what renders the markup they read:

Check Needs the field Why
Hidden field was filled in Yes The field renders the honeypot input.
Submitted faster than a human can type Yes The field renders the signed render stamp.
Human verification Yes The field renders the challenge widget.
The other seven No They read the submission itself.

Those three carry 135 of the plugin's points, against a default flag threshold of

  1. A form without the field is running on the remaining signals only, so

add the field to every form you care about:

  1. Open a form in the editor.
  2. Under Advanced Fields, drag Form Guard onto the form.
  3. Save. One per form is enough.

Put it near the submit button. It renders a single quiet line of status text that disappears once verification completes, plus a hidden input positioned off screen that only automated software ever fills in.

You do not need to switch on Gravity Forms' own anti-spam honeypot. Form Guard renders and reads its own, so the check works whether or not that setting is enabled. Leaving Gravity Forms' honeypot on as well is harmless.

On a form without the field, all three report abstained in the entry breakdown and contribute nothing, rather than quietly reporting a pass they never performed. Their breakdown text says which form is missing the field.

Choose a provider

Forms → Form Guard → Human verification.

Provider Where it runs Notes
Self-hosted proof of work Your server The default. Nothing transmitted, no account, no cookie.
Cloudflare Turnstile Cloudflare Free at any volume. Needs a site key and secret key.
hCaptcha hCaptcha Frictionless modes are a paid tier; the free tier shows image puzzles.
No challenge — The other nine checks still run. A valid choice for a site that would rather ask nothing of its visitors.

Secret keys are encrypted at rest before they are stored. The encryption key is derived from your site's own material and never leaves the server — see Privacy for the details.

Add this to wp-config.php:

define( 'AJC_FORM_GUARD_KEY', '<a long random string>' );

Without it, the encryption and signing keys are derived from your WordPress salts. That works — but rotating the salts, or restoring a database into a site with different ones, then makes stored provider secrets unreadable and requires re-entering them. A dedicated constant survives both.

Generate one with:

php -r 'echo base64_encode( random_bytes( 32 ) ), "\n";'

Verify it is working

  1. Submit your own form normally. It should arrive as usual, with no delay you can perceive.
  2. Open the entry. The Form Guard panel in the sidebar shows the score and the breakdown — including any checks that could not run. On a submission you made yourself in an ordinary browser, Submitted faster than a human can type and Human verification should both show a result. If either says it could not run on your own submission, the field is missing from that form or the widget could not reach the REST route; check /wp-json/ajc-form-guard/v1/challenge loads in a private window. On spam entries those same two checks reading "could not run" is normal and expected — automated submissions do not execute JavaScript. Since 1.2.0 the timing check still scores such a submission when it arrives with no render stamp at all, which means the form page was never fetched.
  3. Check Forms → Form Guard → Status. Captcha field registered should read yes; if it reads NO, the field will not appear in the form editor and the log will say why. Every Gravity Forms symbol listed should read present. Anything reading MISSING means a Gravity Forms release has moved something; the plugin degrades rather than failing, but it is worth reporting.

Uninstalling

Deactivating changes nothing but stops the filtering; your settings and the breakdowns on existing entries are left alone.

Deleting removes every option, transient and scheduled task the plugin created. Score breakdowns already attached to entries are deliberately left in place — they are inert, they belong to entries the site still owns, and walking every entry on a large site during uninstall is not something that should happen without being asked. To remove those first, run the WordPress privacy eraser under Tools → Erase Personal Data.

Questions about AJC Form Guard?

Talk to the people who build and support it.