# P1 Access Matrix and Hardening

Date: 2026-10-19
Environment: primary ERP development installation.
Status: implemented and role-template data migration applied.

## Ready-made roles

| Role | Default capability groups | Suggested assignment |
| --- | --- | --- |
| Company Administrator | Company profile, branches, warehouses, access management, products/import/export and reports | Company |
| Branch Manager | Branch/warehouse visibility, receiving/transfers, inventory and sales approvals, reports | Branch, with explicit warehouse grants |
| Accountant | Product read, finance invoice/payment/export, reports | Company |
| Warehouse Operator | Product/warehouse read, receiving and transfers; no stock adjustment approval | Branch or company, with explicit warehouse grants |
| Sales Representative | Product read, sales view/create/edit; no sales approval | Own or company as required |

The exact permission lists are versioned in app/Support/RoleTemplates.php.
Templates are editable after creation and installation is idempotent.
Existing role slugs, custom permissions and assignments are never overwritten.
No employee is assigned a template automatically.

A role with access.manage can delegate permissions in its own company; it is an administrative trust boundary, not a separation-of-duties role.
System administration stays installation-wide; company owners retain their existing company bypass.
The template installer is available in People & Access / Roles & Permissions.
New companies can use the same installer.

## Scope rules

- Company selection remains membership-validated.
- Own/team/department/branch/company row scopes fail closed on unknown or incomplete rules.
- Branch scopes require a branch; department scopes require a department.
- Branch and department combinations are validated against the selected company.
- Governance permissions (access.manage, company edits, branch administration, warehouse administration) require a company-wide role grant.
- Product listing, ID reads, edits and image-management actions enforce record scope.
- Catalog product lists and counts filter by the caller's visible products.
- Product master records currently have no branch/department columns: branch/department-only product grants do not grant company-wide master access. Assign a separate company-level read role where required.
- Shared category/catalog modification and bulk import require company-wide permission.
- Updating existing products by import additionally requires company-wide products.edit.
- Warehouse readers still need explicit warehouse grants. Branch membership does not imply warehouse access.
- Financial approval amounts and workflows are not implemented by permission keys.

## Active account and session behavior

Every authenticated web request rechecks the active flag in the database.
Inactive users are logged out, session invalidated and CSRF token rotated.
HTML requests redirect to login; JSON requests return 401.
Permission and membership revocations are read from the database on each protected request.
System administrators can deactivate/reactivate regular verified accounts from the employee list.
The UI states that global account status affects all company memberships.
Company administrators cannot change the global active flag.
This endpoint cannot modify the caller or system-administrator accounts.
Pending accounts must finish the activation flow instead of bypassing it.

## Audit coverage

- Existing role/team/assignment and warehouse events remain.
- Business-change middleware adds before/after snapshots for company, branch, product, category and catalog changes.
- Per-row product import create/update events are recorded inside the import transaction.
- Role permission changes include before/after permission IDs.
- Account status changes include before/after active flags.
- Correlation IDs connect events in the same request.
- Nested password/token/secret/credential/cookie/authorization/private-key fields are redacted.
- Audited database mutations and audit insertions share a transaction.
- Filesystem writes/removals are not transactional: orphan cleanup/recovery remains a separate requirement.
- There is no audit edit/delete UI. Database-level tamper resistance and retention are not yet implemented.

## Verification

30 automated tests / 151 assertions pass with SQLite in memory.
Coverage includes role capability separation, cross-company denial, own-row product protection,
branch/department filters, malformed scope denial, company-wide operation checks, permission revocation,
inactive-session logout, global-account administration restrictions, import edit restrictions,
before/after audit values and secret redaction.
The additive data migration 2026_10_19_020000_seed_safe_role_templates applied successfully to the development database.
The migration's down method intentionally preserves editable roles and grants; use reviewed forward corrections.
No real employee accounts were disabled or reassigned during validation.

## Backups

- /home/snyt/backups/snyt-erp/2026-10-19-p0/before-access-hardening-files.tar.gz
- /home/snyt/backups/snyt-erp/2026-10-19-p0/before-access-hardening.sql

Database backup SHA256:
6fca571d75ca5b7c02a130a185bff1b962b13bea79c426880b521e726af7c3ca

## Remaining P1/release work

- Financial approval thresholds and full business approvals.
- API authentication/token revocation when API functionality is introduced.
- Dedicated policy/service extraction from remaining route closures.
- Database-level audit immutability, retention and export UI.
- Visual browser QA and a backup restore rehearsal.
- Permission keys for finance/sales/inventory/export are contracts for future modules;
  they do not mean those operations or export endpoints are implemented.
No Git push was performed.
