omnishield / altcha
Omnishield ALTCHA: a proof of work the site issues and checks itself, on altcha-org/altcha - a challenge signed with the site's key, the solution the visitor's browser found checked, a solution refused the second time; no third party, no cookie.
Requires
- php: >=8.2
- altcha-org/altcha: ^2.3
- glitchr/omnishield: ^1.0@dev
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-10 14:13:37 UTC
README
ALTCHA for glitchr/omnishield: a captcha the site issues and checks itself. The visitor's browser solves a small proof of work - it derives keys until one starts as the challenge asks - and the site checks the solution: signed with the site's key, unexpired, for this action, and never posted before. Nobody else is involved: no third party, no cookie, nothing to ask the visitor's consent for.
Built on the official altcha-org/altcha (^2.3,
MIT); the widget is the altcha web component (MIT).
use Omnishield\Altcha\AltchaGatewayFactory; use Omnishield\Model\Attempt; $gateway = (new AltchaGatewayFactory($spentTokens))->create(['hmac_key' => getenv('ALTCHA_HMAC_KEY')]); $widget = $gateway->widget('contact'); echo $widget->html(); // <script type="module" ...> <altcha-widget challenge="{...}" name="altcha"> $verdict = $gateway->verify(Attempt::fromPost($_POST, $widget, $ip)); $verdict->passed; // the second time: false, reasons ['duplicate']
omnishield: gateways: forms: factory: altcha options: hmac_key: '%env(ALTCHA_HMAC_KEY)%' # required: long, random, secret # the widget's script: served by the Symfony bridge from this package (public/, MIT), the # page reaching nobody; in PHP alone a CDN by default - or copy public/altcha.min.js and name it
ALTCHA cannot tell a solution it saw before: the gateway remembers each one in the
ReplayStoreInterface given to its factory until it would have lapsed - the application's, shared
by every request (CacheReplayStore on a PSR-6 pool; the Symfony bundle gives cache.app).
Without one, this process's memory: right in a test or a worker, not behind PHP-FPM.
Documentation: the options, the widget and its script, the challenge in the page or from a route, the action, what was verified - the whole way in PHP: issued, solved by the library, verified, refused when posted again.
License: MIT since 2026-10-09; earlier versions remain published under LGPL-3.0-or-later.
Formerly omniguard/altcha, renamed on 2026-10-10 with its family (glitchr/omnishield).