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 403GET reports kpo export xlsx rejects viewer role with 403GET 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.
No comments to display
No comments to display