NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

The published config/approvals.php, comments trimmed:

use RoundlyConsulting\Approvals\Models\Approval;
use RoundlyConsulting\Approvals\Models\ApprovalDelegation;
use RoundlyConsulting\Approvals\Models\ApprovalRequest;
use RoundlyConsulting\Approvals\Models\ApprovalRequestStage;

return [
    'model' => Approval::class,
    'request_model' => ApprovalRequest::class,
    'stage_model' => ApprovalRequestStage::class,
    'delegation_model' => ApprovalDelegation::class,

    'key_type' => env('APPROVALS_KEY_TYPE', 'bigint'),

    'authorization' => [
        'enabled' => env('APPROVALS_AUTHORIZATION', false),
        'ability' => 'decide-approval',
    ],

    'expiry' => [
        'default' => null,
    ],

    'workflows' => [
        // named presets — see Workflow presets
    ],
];

Every key

KeyDefaultEnvPurpose
modelApproval::class—Model for decisions. Must extend the package’s Approval.
request_modelApprovalRequest::class—Model for multi-approver requests. Must extend ApprovalRequest.
stage_modelApprovalRequestStage::class—Model for the stages of a staged request. Must extend ApprovalRequestStage.
delegation_modelApprovalDelegation::class—Model for delegations. Must extend ApprovalDelegation.
key_typebigintAPPROVALS_KEY_TYPEType of every polymorphic id column — bigint, uuid or ulid. Read by the migrations, so set it before you migrate; anything else throws InvalidConfigurationException.
authorization.enabledfalseAPPROVALS_AUTHORIZATIONGate every decision path — approve, reject, toggle, ask and cancel — through a Gate ability. The env strings true, 1, yes and on enable it, false, 0, no and off disable it, a blank value is not set (so false), and anything else throws InvalidConfigurationException.
authorization.ability'decide-approval'—The Gate ability checked against the approvable. Not set (null or blank) means decide-approval; a non-string value throws InvalidConfigurationException rather than checking a different gate.
expiry.defaultnull—Lifetime in seconds (≥ 1) of an approval given without an explicit expiry; it stops counting once that passes. Not set (null or blank) means approvals never expire unless a decision sets its own; anything else that isn’t a positive whole number throws InvalidConfigurationException.
workflows[]—Named workflow presets. Not set (null or blank) means none; any other non-array value throws InvalidConfigurationException.

Environment

Two keys are env-backed:

APPROVALS_AUTHORIZATION=true
APPROVALS_KEY_TYPE=uuid

APPROVALS_KEY_TYPE is read when the migrations run, not at runtime — set it before you migrate.

php artisan about

The package adds an Approvals section to php artisan about. It reports the gate ability by presence and the workflow presets by count, so your authorization vocabulary and business-process names never appear in the output:

php artisan about --only=approvals
RowShows
Model / Request model / Stage model / Delegation modelThe class name of each configured model.
AuthorizationENFORCED or OFF.
AbilityDEFAULT (not set — null or blank — or decide-approval), SET (a custom name, never printed) or INVALID.
Default expiryThe expiry.default value in seconds, e.g. 86400s — NEVER, or INVALID when the value would throw.
Workflow presetsThe number of presets, e.g. 2 defined — NONE, or INVALID when workflows is not an array.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.