19 KiB
TenantPilot Stack Overview and Enterprise Assessment
Status: 2026-05-15
Scope: apps/platform Laravel/Filament application in wt-plattform
Project phase assumption: pre-production / MVP-to-scale-up, high criticality because Intune configuration, restore, audit, and tenant isolation are in scope.
Executive Summary
TenantPilot already has a stronger-than-average governance foundation: Spec Kit is active, workspace and tenant isolation are explicit constitutional rules, Graph calls are centralized through GraphClientInterface, queued operations are observable via OperationRun, and many Filament actions use UiEnforcement, confirmation, audit logging, and capability checks.
The main enterprise gaps are not conceptual; they are operational hardening gaps:
- P0:
composer auditandpnpm auditcurrently report high/medium advisories affecting Filament Tables, phpseclib, PHPUnit, axios, devalue, esbuild, postcss, and related packages. - P1: Several critical historical JSON payload columns still use PostgreSQL
jsonwhere the project data strategy requiresjsonbfor queryable snapshots and backup/restore payloads. - P1: Multiple Filament resources/pages exceed 1,000-5,700 lines, increasing change risk around admin workflows.
- P1: Policy coverage is inconsistent: many resources use resource-level
can*()plus gates, but not every resource-backed model has a dedicated policy. - P1: The local/Docker queue command uses
queue:listen; production should use supervisedqueue:workor Laravel 12reloadsemantics. - P2: Admin panel registration mixes explicit resources with discovery. This can be valid, but needs a documented rule to avoid accidental double mental models.
- P2: Production configuration rules need to be encoded as deployment gates:
APP_DEBUG=false, encrypted/secure sessions where needed, health checks, audit-safe logging, queue restart/reload, and backup restore testing.
Stack and Version Analysis
| Bereich | Erkannte Version | Quelle/Datei | Status | Risiko | Empfehlung |
|---|---|---|---|---|---|
| PHP runtime | 8.4.15 | Laravel Boost application_info |
supported | low | Keep 8.4; track active support until 2026-12-31 and security support until 2028-12-31. |
| PHP constraint | ^8.2 |
apps/platform/composer.json |
broad | low | Keep if needed, but CI should test the actual runtime 8.4. |
| Laravel | 12.52.0 | Boost / composer.lock |
current LTS-family app version | medium | Stay on 12.x for now; treat Laravel 13 as a planned major upgrade, not incidental. |
| Filament | 5.2.1 | Boost / composer.lock |
vulnerable range | high | Upgrade to at least 5.3.5; preferably current 5.x after regression tests. |
| Livewire | 4.1.4 | Boost / composer.lock |
compliant | low | Filament v5 + Livewire v4 compliance is satisfied. |
| Tailwind CSS | 4.2.2 | Boost / pnpm-lock.yaml |
current minor behind | low | Tailwind v4 Vite integration is correct; update during frontend dependency patch window. |
| Alpine.js | unclear direct version | bundled transitively by Filament assets | unclear | low | Do not pin separately unless a project asset needs it. |
| PostgreSQL | 16 | docker-compose.yml |
aligned | low | Use PostgreSQL-specific CI for JSONB, partial index, FK, and isolation assertions. |
| Redis | 7-alpine | docker-compose.yml |
available | medium | Use for cache/queue when scale requires it; database queue is acceptable for MVP but not the long-term default. |
| Queue | database | .env.example, config/queue.php |
MVP-grade | medium | Production should use supervised queue:work; split high/low/default queues for Graph/restore workloads. |
| Cache | database | .env.example, config/cache.php |
MVP-grade | medium | Use Redis for production if queue restart signals, locks, and scheduler overlap become load-sensitive. |
| Session | database, encrypted false | .env.example |
local default | medium | Production must set secure cookie/domain/same-site policy and consider SESSION_ENCRYPT=true. |
| log | .env.example |
local default | low | Production needs SMTP/SES/Postmark decision and alert delivery tests. | |
| Storage | local | .env.example |
local default | medium | Production backup/report artifacts should use private object storage and tested restore paths. |
| Auth | Socialite + Microsoft Azure provider | composer.json, providers |
aligned | medium | Review SocialiteProviders Microsoft-Azure 4.x to 5.x upgrade separately. |
| Testing | Pest 4.3.1, PHPUnit 12.5.4 | Boost / composer.lock |
strong but vulnerable dev dep | high | Upgrade PHPUnit to a patched 12.5.x and keep Pest 4 lanes. |
| Frontend build | pnpm 10.33, Vite 7.3.2 | root/app package files | aligned | medium | Patch axios/postcss/esbuild/devalue advisories before production. |
Enterprise Maturity Score
| Bereich | Score | Begründung | Zielzustand |
|---|---|---|---|
| Architektur | 3.0 | Strong service/job/support layers, but some Filament surfaces are very large. | Thin UI classes, explicit services/actions for business workflows, no speculative frameworking. |
| Filament | 3.0 | Correct v5/Livewire 4 basis, panel providers in bootstrap/providers.php, central RBAC helper. |
Standardized resource patterns, policy per resource, extracted schema/table/action builders where size justifies it. |
| Security | 3.0 | Tenant isolation, encrypted credential payloads, audit logs are strong. Supply-chain and policy coverage need work. | Audit gates in CI, patched dependencies, policy/resource coverage matrix, production security config gate. |
| Testing | 4.0 | Rich Pest/Filament/browser/governance lanes exist. | PostgreSQL lane required for schema/isolation changes; dependency audit gates mandatory. |
| Performance | 3.0 | Eager loading and queues exist; JSONB strategy is partially implemented. | Query budgets, JSONB indexes for queried payloads, worker separation, dashboard metrics. |
| DevOps | 3.0 | Sail-first local and Gitea CI exist. | Dokploy runbook, health checks, supervised workers, staging gate, rollback drills. |
| Observability | 3.0 | OperationRun and AuditLog create useful internal observability. |
External error tracking/APM, queue/scheduler alerts, SLO dashboards. |
| Compliance | 2.5 | Audit/isolation foundations exist; GDPR/retention docs are incomplete. | Data inventory, retention matrix, DPA/vendor review, backup encryption proof. |
| Maintainability | 3.0 | Spec Kit and constitution reduce drift; large UI files raise regression risk. | Enforced file-size/refactor triggers and feature-local extraction patterns. |
Findings Register
| ID | Kategorie | Finding | Evidenz | Risiko | Priorität | Aufwand | Empfehlung | Akzeptanzkriterium |
|---|---|---|---|---|---|---|---|---|
| F-001 | Supply Chain | Composer audit reports 8 advisories affecting 5 packages, including high severity Filament Tables XSS and phpseclib/PHPUnit advisories. | composer audit --format=plain; filament/filament 5.2.1, phpunit/phpunit 12.5.4 |
XSS, crypto/DoS, unsafe dev tooling | P0 | M | Upgrade Filament to >=5.3.5, patch transitive packages, rerun full Filament/Pest lanes. | composer audit returns no high/medium advisories accepted by default policy. |
| F-002 | Supply Chain | pnpm audit reports high/moderate advisories for axios, devalue, esbuild, postcss and workspace packages. | corepack pnpm audit --audit-level moderate --json |
SSRF, header injection, XSS, DoS | P0 | M | Update axios >=1.16.1, postcss >=8.5.10, devalue >=5.8.1, esbuild chain via dependency upgrade. | pnpm audit --audit-level moderate is clean or has approved exceptions. |
| F-003 | Datenbank | Core snapshot/backup/restore payload columns still use json, not jsonb. |
policy_versions.snapshot, backup_items.payload, restore_runs.preview/results/requested_items, audit_logs.metadata migrations |
Slow query paths, weaker indexing, inconsistency with product rule | P1 | M | Convert queryable payloads to JSONB with reversible migrations where feasible; add GIN/expression indexes only for proven queries. | Schema uses JSONB for policy snapshots, backup payloads, restore previews/results, and audit metadata query paths. |
| F-004 | Filament | Large workflow classes create high change risk. | ManagedEnvironmentOnboardingWizard.php 5748 LOC, ManagedEnvironmentResource.php 3785 LOC, RestoreRunResource.php 2779 LOC, FindingResource.php 2503 LOC |
Regression risk, difficult review, slow onboarding | P1 | L | Extract schema/table/action factories and service actions at natural workflow boundaries; keep extra layers narrow. | Largest admin workflows have test-covered extracted builders/services and no single file exceeds agreed threshold without exception. |
| F-005 | Security | Resource/model policy coverage is inconsistent. | Policies exist for many models, but resources like Policy, PolicyVersion, BackupSet, RestoreRun, ManagedEnvironment, BaselineProfile, InventoryItem, StoredReport lack obvious dedicated policies. |
Authorization drift between UI and server | P1 | M | Add policy classes or documented exceptions; make Filament resources call policies for CRUD and domain actions. | Resource-policy matrix is complete and tested. |
| F-006 | DevOps | Queue container uses php artisan queue:listen. |
docker-compose.yml:65 |
Inefficient workers, production reload ambiguity | P1 | S | Production/Dokploy should run php artisan queue:work --sleep=3 --tries=3 --timeout=300 under process supervision and reload/restart on deploy. |
Deployment checklist has worker command, process monitor, restart/reload, queue metrics. |
| F-007 | Filament | Admin panel registers explicit resources and also discovers resources. | AdminPanelProvider.php:198, :211 |
Accidental resource exposure or inconsistent registration ownership | P2 | S | Choose explicit allowlist for enterprise panels or document discovery boundaries. | Panel registration rule is documented and covered by navigation/surface tests. |
| F-008 | Graph/Integration | Default Graph version is beta. |
apps/platform/config/graph.php:12 |
API drift and production contract instability | P2 | M | Keep beta only where endpoint requires it; document endpoint version in config/graph_contracts.php and specs. |
Each Graph contract records v1.0/beta, permission, retry behavior, and production risk. |
| F-009 | Testing/CI | PostgreSQL test lane exists but should be mandatory for schema/isolation changes. | composer.json has test:pgsql; default PHPUnit uses SQLite in memory. |
SQLite misses JSONB, partial index, FK, and lock behavior | P2 | M | Add CI rule: migrations, tenant isolation, JSONB, operation locks require sail:test:pgsql or CI PostgreSQL lane. |
PR checks show PostgreSQL lane on relevant path changes. |
| F-010 | Compliance | GDPR retention and backup security are not yet consolidated in one operational matrix. | Product docs exist; no single retention/backup/privacy matrix found in requested scope. | Incomplete audit readiness | P2 | M | Create retention matrix for audit logs, backups, reports, credentials, run payloads; include deletion/export procedure. | Retention matrix exists and is referenced from deployment/security docs. |
Recommended Next 10 Actions
- Patch Composer and pnpm advisories, starting with Filament >=5.3.5 and axios/postcss/devalue.
- Add
composer auditandpnpm audit --audit-level moderateto the confidence or release lane. - Create a resource-policy matrix and add missing policy classes or documented exceptions.
- Convert core queryable JSON payloads to JSONB with targeted indexes.
- Replace production queue guidance from
queue:listento supervisedqueue:workplus Laravel 12reload/queue:restart. - Extract repeated Filament action closures from
BackupScheduleResource,RestoreRunResource, andManagedEnvironmentResourceinto focused action/service classes. - Require PostgreSQL CI for migrations, tenant isolation, operation locks, and JSONB behavior.
- Document Graph endpoint version and permission truth in
config/graph_contracts.phpfor every new integration. - Add production security config checklist: debug false, secure cookies, private storage, no secret logging, encrypted credentials.
- Create retention/backup restore drill checklist before staging promotion.
Best-Practice Target State
- Architecture: Laravel monolith with clear UI/application/domain/infrastructure boundaries; no speculative platform framework.
- Filament: v5-native resources/pages/widgets/actions with thin UI orchestration, policies,
UiEnforcement, empty states, table standards, and tested actions. - Backend: services/actions/jobs own business behavior; controllers and resources stay thin; remote work is queued and idempotent.
- Database: PostgreSQL integrity first: workspace/tenant constraints, partial unique indexes for active operations, JSONB for retained/queryable payloads.
- Security: OWASP ASVS-informed controls, deny-as-not-found isolation, least privilege, encrypted credentials, clean dependency audits.
- Testing: Pest 4 lanes protect business truth, Filament actions, policy semantics, PostgreSQL constraints, and browser-critical workflows.
- Deployment: Dokploy runbook with staging gate, health checks, migrations, asset build, supervised workers, rollback, backup restore proof.
- Observability: audit logs, operation runs, queue/scheduler metrics, Graph throttle metrics, error tracking, and production dashboards.
- Documentation: compact project rules in
docs/*-guidelines.md, current AGENTS rules, and spec-linked decisions. - AI coding: agents must follow
docs/ai-coding-rules.md, Spec Kit, and version-specific official docs.
Anti-Pattern Catalog
| Anti-Pattern | Warum problematisch | Besseres Pattern | Priorität |
|---|---|---|---|
| Fat Filament Resources/Pages | Hard to review, test, and safely change | Extract focused schema/table/action builders and domain actions | P1 |
| Business logic in closures | Authorization/audit/transaction behavior drifts | Service/action class called from UI action | P1 |
| Missing policies | UI checks become the only guard | Policy per resource-backed model or documented exception | P1 |
| N+1 table/global-search queries | Slow admin surfaces | Eager loading, withCount, aggregate subqueries |
P2 |
| Unsafe uploads | RCE/path tampering/data leakage risk | Private disk, random filenames, MIME/size validation, tamper prevention | P2 |
| Missing transactions | Partial writes in critical workflows | Transaction around intent/run/audit state changes | P1 |
| JSON where JSONB is queried | Weak indexing and repeated parsing | JSONB plus targeted GIN/expression indexes | P1 |
| Fragile broad tests | Slow suite, unclear signal | Lane-scoped tests that prove business truth | P2 |
| Plugin/package drift | Security and maintenance risk | Package governance and audit gates | P0 |
| Admin actions without audit | No accountability for critical changes | Audit event for every sensitive mutation | P1 |
| Unclear roles/rights | Tenant data exposure risk | Capability matrix, policies, deny-as-not-found | P1 |
| No queue retry strategy | Duplicate/failed operations | Idempotent jobs, locks, run identity, backoff | P1 |
Roadmap
Phase 1: Stabilisieren
Goal: remove immediate production blockers.
Tasks:
- Patch Composer and pnpm advisories.
- Add audit gates to CI/release.
- Replace production queue guidance with supervised
queue:work. - Add production env/security checklist enforcement.
- Add or confirm tests for destructive restore/backup/provider actions.
Effort: M. Risk: dependency upgrades can reveal Filament regressions. Acceptance: audits clean, critical tests pass, staging deploy runbook works.
Phase 2: Standardisieren
Goal: reduce admin workflow change risk.
Tasks:
- Build resource-policy matrix.
- Extract repeated action closure logic from largest resources.
- Standardize explicit vs discovered Filament resource registration.
- Document Graph contract version and permission rules per endpoint.
- Require PostgreSQL lane for schema/isolation changes.
Effort: L. Risk: refactors can conflict with active feature work. Acceptance: resource-policy matrix complete, top three largest surfaces have bounded extraction plan/tests.
Phase 3: Skalieren
Goal: prepare for higher tenant/data volume.
Tasks:
- Convert queryable JSON payloads to JSONB.
- Add targeted indexes for policy/backup/restore/audit query paths.
- Split queues and consider Redis for production.
- Add dashboard/queue/scheduler/Graph metrics.
- Cache stable aggregates where invalidation is clear.
Effort: L. Risk: migrations need staging timing proof. Acceptance: query plans and queue metrics are documented; staging migration time is acceptable.
Phase 4: Enterprise Readiness
Goal: compliance and operating model.
Tasks:
- Data inventory and retention matrix.
- Backup restore drill and incident response runbook.
- External error tracking/APM integration.
- Vendor/DPA/security review for mail/storage/hosting providers.
- Scheduled package/security review cadence.
Effort: XL. Risk: organizational dependencies outside code. Acceptance: production readiness checklist is signed off and rehearseable.
Open Questions
- Which production mail provider will be used: SMTP, SES, Mailgun, Postmark, or another service?
- Which production storage backend will hold backup/report artifacts: local volume, S3, R2, Spaces, or another private object store?
- Should production queue/cache move to Redis before first customer data, or after volume signals?
- What are the required retention periods for audit logs, backups, restore results, operation runs, reports, and support access logs?
- Is Microsoft Graph
betaacceptable for each production endpoint, or must some flows be v1.0-only? - What compliance bar is expected: internal GDPR readiness, enterprise customer security review, regulated procurement, or formal certification?
Sources
- Official Laravel 12 docs: deployment, authorization, queues, validation.
- Official Filament 5 docs: global search, actions, security, testing actions.
- Official Pest 4 docs: browser testing release notes.
- Official PostgreSQL 16 docs: JSON/JSONB and GIN indexing.
- OWASP: ASVS.
- NIST: SP 800-218 SSDF.
- Microsoft Learn: Graph throttling guidance.
- PHP: supported versions.
Assumptions and Uncertainties
- Production is assumed to be Dokploy on VPS with container-based deployment, as stated in
AGENTS.md. - Exact production mail/storage/cache providers are not set in
.env.example; recommendations are provider-neutral. - Alpine.js exact version is not declared directly; it is treated as Filament-managed unless the project adds custom Alpine assets.
- The current branch has unrelated modified app/test files; this assessment did not alter them.