| name | ci4-shield |
| description | Comprehensive CodeIgniter 4 Shield authentication and authorization skill. Use when working with Shield auth — session login, access tokens, HMAC tokens, JWT, groups, permissions, user model/entity, filters, email activation, two-factor auth, magic links, banning, force password reset, or customizing auth views/controllers. Activates on mentions of "Shield", "auth()", "loggedIn", "groups", "permissions", "access token", "HMAC", "JWT", "Email2FA", "EmailActivator", "magic link", "Shield filter", or any Shield-specific pattern in a CI4 context. |
| version | 2.0.0 |
CodeIgniter 4 Shield — Auth Reference
Shield is the official authentication and authorization library for CodeIgniter 4. It is not Laravel Sanctum, Passport, or Breeze. Do not apply Laravel auth patterns here.
Related skills: ci4 for core framework patterns, ci4-api for REST API patterns.
Reference Documents
For deep dives, read the relevant reference from references/:
| Reference | When to read |
|---|
references/configuration.md | Auth.php, AuthGroups.php, password validators, views, authenticators |
references/session-auth.md | Login/logout flow, remember me, web authentication |
references/token-auth.md | Access tokens, HMAC tokens, JWT — generation, revocation, scopes |
references/groups-permissions.md | Groups, permissions, matrix, direct user permissions, wildcards |
references/user-model.md | User entity, UserModel, extending, creating/finding/updating users |
references/filters.md | All Shield filters, route protection, filter arguments |
references/actions.md | Email activation, Email 2FA, magic links, password handling, banning |
references/events-customization.md | Events, custom views, extending controllers, routes, testing |
Installation & Setup
composer require codeigniter4/shield
php spark shield:setup
php spark migrate
Database Tables
| Table | Purpose |
|---|
users | Core user data (username, active, last_active) |
auth_identities | All credential types (email/password, access tokens, HMAC keys) |
auth_logins | Login attempt log (success + failure) |
auth_remember_tokens | Remember-me tokens |
auth_groups_users | User-to-group pivot |
auth_permissions_users | User-to-permission pivot |
Auth Helper — Core Functions
The auth() helper is globally available. No manual loading needed.
auth()->loggedIn();
auth()->user();
auth()->id();
auth('session')->loggedIn();
auth('tokens')->user();
$result = auth()->attempt([
'email' => $email,
'password' => $password,
]);
if ($result->isOK()) { }
auth()->logout();
$result = auth()->check(['email' => $email, 'password' => $password]);
GOTCHA: attempt() returns a Result object, not a boolean. Always check $result->isOK().
Groups & Permissions (Quick Reference)
See references/groups-permissions.md for complete reference.
$user = auth()->user();
$user->addGroup('admin');
$user->removeGroup('admin');
$user->inGroup('admin');
$user->inGroup('admin', 'superadmin');
$user->getGroups();
$user->can('posts.create');
$user->cannot('users.delete');
$user->addPermission('admin.access');
$user->removePermission('admin.access');
Groups and permissions are defined in app/Config/AuthGroups.php.
Filters (Quick Reference)
See references/filters.md for complete reference. Shield auto-registers these — no manual registration needed.
| Filter | Purpose |
|---|
session | Requires session auth |
tokens | Requires Bearer token auth |
hmac | Requires HMAC token auth |
jwt | Requires JWT auth |
chain | Tries session, then tokens (SPA + mobile) |
group | Checks group membership |
permission | Checks permission |
force-reset | Checks if password reset required |
auth-rates | Rate limiting for auth routes |
$routes->get('dashboard', 'DashboardController::index', ['filter' => 'session']);
$routes->get('admin', 'AdminController::index', ['filter' => ['session', 'group:admin,superadmin']]);
$routes->get('api/me', 'Api\UserController::me', ['filter' => 'tokens']);
User Entity (Quick Reference)
See references/user-model.md for complete reference.
$user = auth()->user();
$user->getEmail();
$user->username;
$user->password = 'new-pass';
$user->isBanned();
$user->ban('Reason');
$user->unBan();
$user->isActivated();
$user->activate();
$user->forcePasswordReset();
$token = $user->generateAccessToken('name');
$user->revokeAccessToken($tokenId);
Configuration (Quick Reference)
See references/configuration.md for complete reference.
public array $redirects = ['register' => '/', 'login' => '/', 'logout' => 'login'];
public array $actions = [
'register' => null,
'login' => null,
];
public array $validFields = ['email'];
public string $defaultAuthenticator = 'session';
public array $groups = ['superadmin' => [...], 'admin' => [...], 'user' => [...]];
public string $defaultGroup = 'user';
public array $permissions = ['admin.access' => '...', 'users.create' => '...'];
public array $matrix = ['superadmin' => ['admin.*', 'users.*'], 'admin' => ['admin.access']];
Key Gotchas
See references/events-customization.md for the complete list.
attempt() returns a Result, not bool — always use $result->isOK()
raw_token only available once — capture at generation, hashed before storage
- Filter order matters —
session must run before group (auth before authz)
- Parent route group filters don't merge into children — declare on each group
- Custom UserModel must be registered in
Auth.php's $userProvider
- Password auto-hashed by entity setter — never manually hash before setting
- Credentials live in
auth_identities — not the users table
- Email config required for activation, 2FA, and magic links
$validFields controls login fields — add 'username' to allow username login
chain filter is for dual-client endpoints — don't use when auth type is known