Adminix Documentation Help

Security

Adminix is an admin panel package. Treat every request to Adminix routes as privileged application traffic.

Authorization

By default Adminix requires an authenticated user that implements AdminixUserInterface. The middleware checks getAdminCriteria() from that interface.

use AlexKudrya\Adminix\AdminixUser; use AlexKudrya\Adminix\AdminixUserInterface; class User extends Authenticatable implements AdminixUserInterface { use AdminixUser; }

Do not enable no_auth_access in production. It is intended only for local demos and isolated development environments.

Logout is a state-changing action and is exposed only as a POST route with CSRF protection. Use the package sidebar form or submit a POST request to adminix_login_logout; do not link to logout with a GET URL. Successful login regenerates the Laravel session ID. Logout invalidates the session and regenerates the CSRF token.

Server-side resource configuration

Create and save routes use the server-side module configuration for:

  • dataSource;

  • primary key;

  • writable fields;

  • readonly fields;

  • static hidden field values;

  • signed param:* hidden field values rendered by package views.

Legacy Blade forms still render hidden metadata for compatibility with the current frontend, but controllers do not trust hidden adminix_data_source, _primary_key, or arbitrary writable field lists from the request. param:* hidden values are accepted only from signed form context generated during server-side rendering; unsigned or tampered request values are ignored and then handled by normal validation.

Save flows reject requests with no writable input and return a not-found error when an update affects no rows. Create flows reject requests with no writable input. Modal API requests with malformed params return controlled JSON errors. Requests with missing module metadata and non-scalar list filter values are ignored or rejected with controlled errors instead of producing uncaught server errors. Adminix endpoint resolution is server-side: page, module, list, field, action, datasource, primary key, relation context, and writable fields are resolved from package configuration or signed context before an endpoint writes or reads data. Web and API endpoints return controlled redirects or JSON errors for invalid module/context/validation states.

Upload fields use only server-side ResourceField::upload() configuration for disk, directory, validation rules, remove behavior, and old-file cleanup. The request may contain a file payload or a remove checkbox, but it cannot choose a disk, directory, stored filename, or writable upload column. On update, scalar values submitted under an upload field name are rejected; only real uploaded files or an allowed remove checkbox can change stored upload paths. Readonly upload fields are ignored like other readonly fields. If validation or database update fails, Adminix cleans up newly stored files; previous files are deleted only after a successful replace/remove update when deleteReplaced is enabled. Resource create/update/upload audit events are emitted only after successful package write flows and contain server-derived module metadata, writable fields, subject, and upload descriptors. Recorder implementations must still persist audit rows with application-side tenant/user ownership rules.

Resource and detail relation managers resolve the parent record from server-side module props before building child UI. The relation list receives a server-owned foreign-key criterion; browser filters can narrow that query but cannot select another parent record. Relation create/edit modals use signed relation context for the parent resource and inject the child foreign key server-side. Child edit fetch/save adds the parent foreign-key criterion, so a child record from another parent returns a controlled not-found response instead of being updated.

List sorting accepts only asc and desc from the request. List lenses accept only configured server-side lens names from lens-{moduleName}. Lens default filters are applied only when the matching request filter key is absent; browser-provided filter keys are never silently replaced by lens defaults. List CSV export is opt-in per module, uses the server-side list datasource and fields, requires signed page-param context, and ignores browser-provided datasource or column lists. Hidden list fields are excluded from CSV unless the field is explicitly marked exportable. List bulk actions are opt-in per module and resolve the action by name from server-side ListModule::bulkActions(). Bulk requests may submit only selected scalar IDs and an action name. Adminix verifies signed page-param context, verifies signed relation context for relation child lists, applies the same datasource, primary key, base criteria, active lens, filters, search, sorting, and relation parent scope as the rendered list, and ignores IDs outside that scope. Handlers receive a scoped selected-record query; they must not rebuild writes from browser-provided datasource, writable fields, parent IDs, or hidden metadata. Bulk action audit metadata uses the same scope-filtered selected IDs; do not replace it with raw browser-selected IDs in listeners or recorders. Action handlers should read only declared adminix_action_fields values from BulkActionRequest::field()/fields(). Queued bulk actions are authorized before dispatch and reapply the signed context, saved query filters/search/lens/sorting, and current server-side list scope when the queued job runs. Queued audit entries record bulk.queued on dispatch and bulk.executed after the queued handler finishes. Typed action responses such as redirects, modals, downloads, and new-tab targets must be derived from trusted server-side state, not browser-owned datasource, IDs, field names, or tenant context. Search input escapes SQL LIKE wildcards and is capped before query application. Invalid date and date-range filter values are kept in the rendered filter state but ignored by the database query instead of producing a server error. Row action confirmation text is JSON-encoded before it is placed in inline JavaScript. Class-string data sources must be Eloquent models; non-model classes are rejected with a controlled package error.

Run Adminix Doctor during setup and before release to catch common configuration and module safety issues early:

php artisan adminix:doctor --strict

Doctor reports risky no_auth_access, invalid admin user model configuration, duplicate page identifiers, malformed criteria, invalid data sources, unsafe editable-list shape, and unsupported row-action criteria before the affected admin route is used.

Criteria validation uses the same operator contract in runtime queries, resource update lookup scopes, and Doctor diagnostics. Supported query operators are =, ==, !=, <>, >, <, >=, <=, like, and not like; row action visibility criteria remain limited to == and != because they compare already-rendered row values.

Validation

Put validation rules on module fields or module-level validation(). Update flows ignore the current row for string unique rules and Rule::unique() objects using the server-derived primary key.

Public exposure checklist

  • keep no_auth_access set to false;

  • implement AdminixUserInterface on the configured user model;

  • configure strict getAdminCriteria() rules;

  • configure only intended fields as editable or writable;

  • keep sensitive model fields out of Adminix modules unless they are intentionally managed;

  • disallow indexing Adminix URLs in robots.txt.

Last modified: 21 June 2026