norialabs / keel
Modular application infrastructure for Laravel: workspace tenancy, role-based access control, audit logging, passwordless authentication, invitations, and database operations.
Requires
- php: ^8.3
- illuminate/auth: ^13.0
- illuminate/bus: ^13.0
- illuminate/console: ^13.0
- illuminate/database: ^13.0
- illuminate/events: ^13.0
- illuminate/http: ^13.0
- illuminate/queue: ^13.0
- illuminate/support: ^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.20
- laravel/sanctum: ^4.0
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0|^5.0
Suggests
- laravel/sanctum: Required only for PersonalAccessToken, the workspace-scoped token model.
Provides
None
Conflicts
None
Replaces
None
README
Modular application infrastructure for Laravel. Keel provides workspace tenancy, permissions, audit logging, authentication utilities, invitations, and database operations, alongside HTTP, money, and CSV components.
Use Keel in any Laravel application. You supply your application's models, authorization rules, and delivery providers through contracts and configuration. No external account or service is required.
Requirements
- PHP 8.3 or newer and Laravel 13. CI covers PHP 8.3, 8.4, and 8.5.
- PostgreSQL for row-level security and database rebuilds. Other components can be used without it.
- Laravel Sanctum when using the optional workspace-scoped token model.
- PHP's
intlextension for currency formatting, andsodiumfor encrypted backups. - Database client tools when using database operations; see operations.
Components
| Component | Capabilities | Integration required |
|---|---|---|
| Tenancy | Workspace context, PostgreSQL policies, tenant-aware jobs | Workspace resolver, middleware, application table policies |
| Permissions | Resource/action enums, role grants, permission ceilings | Application enums, principal resolver, role repository |
| Audit | Actor, workspace, target, request context, append-only model | Call the recorder; add database protections where required |
| Identity and authentication | Address normalization, keyed hashes, OTP verification, social state | User lookup, message delivery, routes, login flow |
| Tokens | Workspace-scoped Sanctum model and permission abilities | Sanctum, compatible token table, model registration |
| Invitations | Expiring tokens, recipient checks, revocation | Membership creation; optional delivery contract |
| Database operations | Backups, retention, encryption, restore, PostgreSQL rebuild | Storage disk, database tools and privileges |
| HTTP and errors | Security headers, trusted proxies, static error pages | Middleware registration, application views/assets |
| Money | Integer amounts, currency checks, formatting, validation | Currency and display settings |
| CSV | Preview, streamed rows/exports, upload validation | Application import/export flow |
Read the component guide for examples and integration contracts.
Install
composer require norialabs/keel php artisan vendor:publish --tag=keel-config
Laravel discovers Noria\Keel\KeelServiceProvider automatically. Settings are published to
config/keel.php. All package classes use the Noria\Keel\ namespace.
Before migrating, choose which components your application needs. The provider registers services
and commands, and loads the package migration by default. That migration creates audit_logs,
otp_challenges, and invitations; it does not create users, workspaces, roles, memberships,
or a Sanctum token table.
Tenancy and audit recording are enabled in configuration by default. HTTP middleware, message delivery, and application-specific permission bindings require explicit setup. PostgreSQL policies and database triggers must be added in your application's migrations; installing Keel alone does not establish tenant isolation.
Applications without PostgreSQL tenancy
Set this in your application's .env before using services that manage workspace context:
KEEL_TENANCY=false
If you only need components that do not use package tables, such as CSV, money, or HTTP middleware, also disable automatic migration loading and audit recording:
KEEL_LOAD_MIGRATIONS=false KEEL_AUDIT=false
Applications using package tables
Choose key types, table names, the workspace column, and your database connection before running. Package tables can be keyed on UUIDs, ULIDs, or integers, and your workspaces on UUIDs, ULIDs, integers, or slugs:
php artisan migrate
For PostgreSQL, align the connection's timezone with config('app.timezone') before migrating.
See database configuration.
For workspace isolation, continue with tenancy setup.
Quick example
The money component can be used without package tables or application model bindings:
use Noria\Keel\Money\Money; $unitPrice = Money::fromMajor('12.50', 'USD'); $total = $unitPrice->times(3); $amount = $total->rate();
$amount is "37.50". Money uses a fixed storage scale of 100; review the
money component before choosing it for your currency requirements.
Configuration
Settings live under keel.*, environment variables under KEEL_*, and Artisan commands under
keel:*. Key types, table and column names, the connection, which tables are created, models,
the audit guard, the cache store, and the permission gate name are all configurable, and the
package dispatches events for audit entries, sign-in codes, and invitations.
The shipped country and currency defaults are KE and KES. Configure them for your application;
the dialling-code map and currency display rules are explicit settings rather than a complete
internationalization database. See configuration.
Documentation
- Components and integration contracts
- Configuration, migrations, and customization
- Database operations and deployment tasks
- Upgrading from Platform
- Contributing and running tests
Support and contributions
Report reproducible bugs or propose improvements through GitHub issues. Include your PHP, Laravel, and database versions, the component involved, and a minimal example. Pull requests are welcome; see the contribution guide for local setup and checks.
License
Keel is available under the MIT license.