yassinedoghri / codeigniter-altcha
A CodeIgniter4 library for ALTCHA, a GDPR, WCAG 2.2 AA, and EAA compliant, self-hosted CAPTCHA alternative with PoW mechanism.
Installs: 11
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/yassinedoghri/codeigniter-altcha
Requires
- php: >=8.2
- altcha-org/altcha: ^1.1
Requires (Dev)
- codeigniter/phpstan-codeigniter: ^1.5.4
- codeigniter4/framework: ^v4.6.0
- pestphp/pest: ^3.8.4
- pestphp/pest-plugin-type-coverage: ^3.6.1
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.1.32
- rector/rector: ^2.2.7
- symplify/coding-standard: ^13.0.0
- symplify/easy-coding-standard: ^13.0.0
README
CodeIgniter ALTCHA 🔥🔄🔒
A CodeIgniter4 library for ALTCHA, a GDPR, WCAG 2.2 AA, and EAA compliant, self-hosted CAPTCHA alternative with Proof‑of‑Work (PoW) mechanism.
Why ALTCHA?
- No frustrating puzzles. Proof‑of‑Work runs silently in the background.
- No third‑party calls. Fully self‑hosted and privacy‑first.
- Built for real users: fast, accessible, and open‑source.
👉 See 10 Reasons ALTCHA Is Better
Features
- Proof‑of‑Work CAPTCHA (no puzzles; background verification)
- Server‑side challenge issuance & verification filter for CI4
- ALTCHA widget helper with auto
challengeurl
- Proof‑of‑Work data obfuscation (protects emails, phones, and other
sensitive data)
- Cached obfuscated payloads to avoid recomputes
- Obfuscation widget helper with localized reveal label for click to reveal
- ALTCHA Sentinel (advanced detection and metrics)
Table of Contents
- 🚀 Getting started
- đź§© ALTCHA widgets
- ⚙️ Config reference
- ❤️ Acknowledgments
- 📜 License
🚀 Getting started
0. Prerequisites
- Download or install the ALTCHA widget script.
- Include the ALTCHA widget script on any page that renders
<altcha-widget>
Note
Installing via a package manager?
Check out CodeIgniter Vite 🔥⚡ for a fast and simple way to manage JavaScript and TypeScript packages in your CodeIgniter4 projects.
1. Installation
-
Install
codeigniter-altchausing composer:composer require yassinedoghri/codeigniter-altcha
-
Add
altchahelper to your Autoload.php file:public $helpers = [/*...other helpers...*/, 'altcha'];
-
Render the ALTCHA widget inside your forms using the
altcha_widget()helper:<form method="POST" action="/your-endpoint"> <!-- Your form fields go here --> <?= altcha_widget() ?> <button type="submit">Submit</button> </form>
2. Configuration
Copy the Altcha.php config file from
vendor/yassinedoghri/codeigniter-altcha/src/Config/ into your project's config
folder and update the namespace to Config. You will also need to have the class
extend the original class.
// new file - app/Config/Altcha.php <?php declare(strict_types=1); namespace Config; // ... use CodeIgniterAltcha\Config\Altcha as CodeIgniterAltcha; class Altcha extends CodeIgniterAltcha { // ... }
đź§© ALTCHA widgets
Two helpers let you render the widget either for user verification or for revealing obfuscated data.
Render the widget
Use altcha_widget() to render the <altcha-widget> element inside your forms,
with optional ui layout, attributes, and children.
See ALTCHA's widget customization docs for all available options and UI modes.
altcha_widget(string $ui = 'inline', array $attributes = [], string $children = ''): string​`
Parameters
$ui:'inline'|'floating'|'overlay'(default:'inline')$attributes:array<int|string, string>(default:[])$children:string(default:'')
Examples:
-
inline
<?= altcha_widget() ?> // <altcha-widget></altcha-widget>
-
floating
<?= altcha_widget('floating') ?> // <altcha-widget floating></altcha-widget>
-
overlay
<?= altcha_widget('overlay') ?> // <altcha-widget overlay></altcha-widget>
-
customAttributes
<?= altcha_widget('inline', ['language' => 'fr']) ?> // <altcha-widget language="fr"></altcha-widget>
Render widget in obfuscation mode
Use obfuscation to protect emails, phones, or any sensitive data from scrapers; users click to reveal.
Note
No manual setup needed: CodeIgniter ALTCHA generates the obfuscated payload for you and wires it into the widget automatically.
Important
Obfuscation deters scraping and casual bots; it does not provide strong
secrecy.
For sensitive data, avoid embedding it client‑side and return it from the
server only after verification/authentication.
See ATCHA's official docs for obfuscating data.
altcha_widget_obfuscate(string $data, array $attributes = [], ?string $customLabel = null, ?string $key = null, ?bool $promptKey = null): string
Parameters
$data:string$attributes:array<int|string, string>(default:[])$label:?string(default:null, uses localized label)$key:?string(default:null, uses config value)$promptKey:?bool(default:null, uses config value)
Examples
-
Email link
<?= altcha_widget_obfuscate('mailto:hello@example.com') ?>
-
Phone link
<?= altcha_widget_obfuscate('tel:+15554441234', [], 'Show phone') ?>
-
With extra attributes
<?= altcha_widget_obfuscate('mailto:hello@example.com', ['language' => 'de'], 'Kontakt anzeigen') ?>
⚙️ Config reference
You may control the ALTCHA integration behavior in your CodeIgniter4 app if needed, including whether the verification is active, how HMAC secrets are managed, and how challenge parameters are tuned.
Note
This library should be using sensible defaults, you should tweak things only if the need arises.
active
Type: boolean
Default: true
Enables or disables ALTCHA verification globally. When set to false, the ALTCHA filter and server-side verification are bypassed for all requests.
filterExcludedPaths
Type: list<string> list of string patterns
Default: []
Defines URI paths that bypass the ALTCHA verification filter.
Supports asterisk wildcard at the end for prefix matching (e.g., api/* matches
/api/, /api/v1/users, etc.).
Example: ['api/*', 'health'] to exclude API subtrees, a health endpoint.
hmacKey
Type: string
Default: '' (empty, ie. not defined)
Secret used to sign challenges and verify solutions via HMAC (Must be at least 24 characters long.)
For production, set a long, random secret from environment configuration and do not commit it to source control.
Required when autoGenerateHMAC is false or when the cache is unavailable.
autoGenerateHMAC
Type: boolean
Default: true
When true, an HMAC secret is generated and stored in the configured cache pool.
If the cache driver is “dummy” or cannot persist values, the library falls back
to hmacKey.
hmacKeyTTL
Type: int (seconds)
Default: DAY (number of seconds in one day)
Lifetime, in seconds, for the auto-generated HMAC secret in cache. When the TTL expires, a new secret is generated.
redirect
Type: boolean
Default: (ENVIRONMENT === 'production')
When true, failures in ALTCHA verification redirect the user back to the previous page with an error indicator (e.g., flash message) instead of rendering an inline error response.
By default, enabled in production for better UX and disabled during development to surface detailed errors inline for easier debugging.
challengeAlgorithm
Type: string|null
Default: null (ALTCHA's default)
Optional override for the challenge algorithm used by ALTCHA. When null, ALTCHA’s default algorithm is used.
Must match the client-side widget expectation; mismatches will cause verification failures.
Typical values align with ALTCHA complexity options (e.g., SHA-256). Refer to
ALTCHA’s complexity documentation for
available algorithms.
challengeMaxNumber
Type: int|null
Default: null (ALTCHA's default)
Optional override for the maximum random number used in the proof-of-work search space. Larger values increase the computational cost for the client.
When null, the server uses the library’s default. Set an explicit integer to
tune difficulty for your audience and device profile.
challengeExpires
Type: int (seconds)
Default: 10
Time window, in seconds, during which a newly issued challenge remains valid on the server. Submissions outside this window are rejected as expired.
Keep this short to limit replay risk. If legitimate users frequently time out (e.g., slow forms or long interactions), increase cautiously while balancing security and UX.
obfuscationKey
Type: string
Default: '' (empty, ie. not defined)
The optional encryption key used to generate obfuscated data; if configured to prompt, users must enter this key to reveal the content.
promptObfuscationKey
Type: bool
Default: true
Whether users are prompted to enter the obfuscation key before reveal.
obfuscationMaxNumber
Type: int
Default: 10000
Upper bound of the PoW search range for obfuscation; higher values increase client work and slow reveals.
obfuscationPayloadTTL
Type: int (seconds)
Default: MONTH
Cache lifetime for precomputed obfuscation payloads; when expired, a new payload is generated.
❤️ Acknowledgments
This wouldn't have been possible without the amazing work of the
CodeIgniter & altcha-org
teams.
Thank you 🙏
📜 License
Code released under the MIT License.
Copyright (c) 2025-present, Yassine Doghri (@yassinedoghri).