KPO Export RBAC Fix — MC #105326 KPO Export RBAC Fix — MC #105326 Finding Proveo adversarial verify on MC #105321 (2026-07-12) found that GET /reports/kpo/export/pdf and GET /reports/kpo/export/xlsx in ReportRoutes.kt were missing the requirePermission(principal, "report:export") guard that every other export route (KIR, KPR, VAT, P&L, balance-sheet, accountant CSV package) already has. Git diff confirmed the gap pre-dated the T1b diff — it was a pre-existing asymmetry, not a regression. Fix Added if (requirePermission(principal, "report:export")) return@get to both KPO export routes in apps/api/src/main/kotlin/no/alai/bilko/routes/ReportRoutes.kt , matching the exact pattern used at the other 11 export-route call sites in the same file (13 total after the fix). Tests Added 4 integration tests to apps/api/src/test/kotlin/no/alai/bilko/routes/ReportRoutesHttpIntegrationTest.kt : GET reports kpo export pdf rejects viewer role with 403 GET reports kpo export xlsx rejects viewer role with 403 GET reports kpo export pdf allows owner role (passes RBAC, hits NotImplemented stub per MC #100038) GET reports kpo export xlsx allows owner role Verified: ./gradlew integrationTest --tests "no.alai.bilko.routes.ReportRoutesHttpIntegrationTest" --rerun → BUILD SUCCESSFUL, 0 failures / 0 errors. P2P Peer Verify Proveo independent pre-verifier: PASS. mesh-thr-d41602c0-65fa-4d4c-bca4-8fe770f11704 / mesh-msg-e3c3869f-f160-4e65-a9d0-8ba27f000686 . Transcript: /tmp/alai/p2p-pairing-evidence/mc105326-transcript.md .