- Shipped
- October 18, 2026 at 6:55 PM UTC
- Author
- Kamo
- Commit
- e2b81bd
Commerce invoices: InvoicingService's CommerceInvoiceController checks no right by design (it expects SecurityService to own the session and the rights) and nothing relayed to it. /api/security/commerce-invoices is that door: list, one and the PDF take VIEW_SUBSCRIPTION_INVOICES (or MANAGE_); drafting from a job or order, finalize, void and credit take MANAGE_SUBSCRIPTION_INVOICES (@RequireRight). Org and actor come from the session only; ids are validated before they reach a path. No backfill: existing rights, no screen. Billing: BillingService takes identity from X-Org-Id/X-Member-Id, so a non-browser session holder (the SI tool plane) needs a trusted hop. /api/security/billing relays a fixed list only — own plan/coverage/ eligibility/alerts, the plan catalogue, the org's **************** and seat assign/remove — stamping both headers from the session; BillingService decides each (own account, owner, VIEW_/MANAGE_ORG_BILLING), and a seat write here also needs the owner or MANAGE_ORG_BILLING. Payment methods, buying/cancelling seats, plan changes and billing groups are never relayed. Backfill: MANAGE_ANALYTICS (440) is seeded from VIEW_ANALYTICS on the boot that introduces it (every Analytics user could change it under the shared login); VIEW_/MANAGE_ORG_BILLING are seeded to nobody.
