Skip to content

Security Considerations ​

forceTransitionTo() Bypasses Access Control ​

The forceTransitionTo() method skips all state-based access checks and assignment overrides. It is intended for system-level operations such as console commands, scheduled jobs, and background processes.

Never call forceTransitionTo() with data that originates from user input or HTTP requests. If a user needs to trigger a transition, use the standard transitionTo() path, which enforces access rules.

php
// Safe: internal job, no user input
$order->forceTransitionTo(ShippedState::class);

// Unsafe: $request->input('state') is user-controlled
$order->forceTransitionTo($request->input('state')); // do not do this

Access Override Semantics ​

WorkflowAssignment records carry three nullable boolean columns — override_view, override_edit, override_transition. Their three values have distinct meanings:

ValueMeaning
nullFollow the state-based access rules (default)
trueExplicitly grant access regardless of state rules
falseExplicitly deny access regardless of state rules

A denial holds over the rules of the state, over a grant of the same kind, and over every opening of the record scope (visibleTo() and friends) — it wins against everything but the super admin bypass. When building an assignment management UI, display these three options clearly to administrators: an assignment with override_view = false locks a user out of the record even if the state rules would normally grant them access.

Super Admin Bypass ​

Any user with a role listed in config('filament-flow.state_access.super_admin_roles') bypasses all access checks unconditionally. The default value is ['super_admin'].

Keep this list minimal in production. Adding common roles (e.g. admin, manager) to this list will silently disable access control for a large portion of your user base.

php
'state_access' => [
    'super_admin_roles' => ['super_admin'], // keep this list short
],

Restrict the Workflow Admin Resource ​

The FilamentFlowPlugin registers a Workflow admin resource that allows users to create, edit, and delete workflow definitions. Without authorization, any authenticated Filament user can modify workflow structures.

Always restrict access in production:

php
FilamentFlowPlugin::make()
    ->authorizeUsing(fn (User $user): bool => $user->hasRole('super_admin')),

Without this guard, a standard user could alter transition rules, disable access controls, or create workflows that affect other tenants.

Transition Metadata in History ​

Each entry in workflow_state_transitions stores the ip_address and user_agent of the user who triggered the transition. This data is useful for auditing but may be subject to your application's privacy policy and regional data protection regulations (e.g. GDPR).

Review whether storing IP addresses requires user consent in your jurisdiction. If so, you can omit this logging by overriding the history-writing logic or clearing the fields before the record is saved.

Snapshot Storage ​

WorkflowTransitionSnapshot stores a full serialized copy of the record's attributes before and after each transition. For records that contain sensitive data (personal information, financial details, credentials), consider:

  • Whether snapshots should be enabled for that model type.
  • Whether snapshots should be encrypted at rest.
  • How long snapshot data should be retained before being purged.

If snapshots are not needed, disable them per workflow in the database configuration or exclude sensitive fields from the snapshotted attributes.

Queue Security ​

Notification jobs serialize model data and dispatch it to the queue backend. Ensure that your queue backend (Redis, database) is not publicly accessible and uses appropriate authentication.

For Redis-backed queues, use password authentication and consider running Redis on a private network. For database-backed queues, ensure the jobs table is not exposed through any API endpoint.

Proprietary software. All rights reserved.