Billing Authorization Model
Authorization Boundary
Billing's business operations use protected console routes in the Accounting application. Public access is limited to deployment health. A member's status as the billed party does not grant access to Billing staff operations, and the current module exposes no member-facing repayment page.
Human access comes from applicable role assignments and permission evaluation. The Accounting application-access grant and its licensing boundary sit alongside the operation's permission. Platform owns the enforcement and refusal contracts for those gates. The gateway caches decisions for sixty seconds, and signed service context remains valid for ninety seconds. A grant change does not imply immediate invalidation of every issued context.
Commerce invokes a declared subset through a trusted service function: repayment preview, creation, reading, reduction, cancellation and payment outcome reporting. Its cloud-role authority is distinct from a person's permission assignment. The function's declaration establishes permitted invocation, while complete checkout proof remains open. Scheduled work uses machine execution with the configured owner's authority; bulk batches resolve the execution person's authority again.
Rhythm staff enter customer work through a recorded access grant and ordinary assignments covering the requested operation. HQ status alone does not authorize Billing, and customer administration does not create HQ authority.
Scopes
Customer-scoped shared roles can reach the customer's workspaces. Billing resolves records inside the authorized workspace, including references supplied by identifier. Business units narrow configuration and installment selection within that workspace, but the examined Billing operations do not establish a separate business-unit role model.
Saved-query visibility can narrow notice populations. Installment selection currently uses the configured unit under run authority rather than an individual arrangement grant. Product's open visibility question remains material: the model must not imply per-arrangement isolation that the implementation does not demonstrate. Installment estimates also omit the unit filter before a run exists, an identified control gap.
Roles
The four roles below project the shared customer roles into Billing. Their grants show the built-in allow set before scoped assignments, explicit denies, application availability and resource guards are evaluated. They are not four new Billing roles automatically assigned to people.
Administrator and Power User both receive Accounting's administrator-tier Billing permissions. Standard User receives the read and operational tiers. Read Only receives reads, queries and application entry. A customer can attach policies to custom roles to separate these powers more narrowly; no assignment is created by declaring a policy.
The generated Accounting policies are Read Only, User and Administrator. The shared role named Standard User includes the User policy. The Billing actor seed's alternate policy spelling is not the generated key. Administrator additionally receives Platform's separate export policy; Power User does not receive that built-in authority merely by holding every Accounting permission.
Commerce and the scheduler are integration actors, not human role assignments. Their authority is described at the boundary rather than represented as invented permission grants.
Permission Catalogue
| Permission | Purpose | Operations |
|---|---|---|
none: the shared health route (the operation name follows the get<Module>Health pattern of the route library) | Expose public deployment health without a permission grant; this entry preserves the service contract’s explicit no-permission marker. | getBillingHealth |
accounting.application.access | Enter the Accounting application that currently hosts Billing. | No implemented operation |
accounting.billing-notices.bulk | Declare bulk administration of billing recipient and message configuration, with no checking operation implemented in this module. | No implemented operation |
accounting.billing-notices.create | Create billing recipient and message configuration. | createBillingNotice |
accounting.billing-notices.delete | Remove eligible billing recipient and message configuration. | deleteBillingNotice |
accounting.billing-notices.read | Inspect billing recipient and message configuration. | listBillingNotices, getBillingNotice |
accounting.billing-notices.update | Change billing recipient and message configuration. | updateBillingNotice |
accounting.billing-runs.bulk | Declare bulk administration of billing runs, with no checking operation implemented in this module. | No implemented operation |
accounting.billing-runs.cancel | Stop eligible billing runs. | cancelBillingRun |
accounting.billing-runs.create | Create or estimate billing runs, prepare or refresh their populations, and change review exclusions. | createBillingRun, estimateBillingRun, prepareBillingRun, refreshBillingRun, excludeBillingRunItems |
accounting.billing-runs.delete | Remove eligible billing runs. | deleteBillingRun |
accounting.billing-runs.read | Inspect billing runs. | listBillingRuns, getBillingRun, listBillingRunItems, streamBillingRunEvents, listBillingRunEvents |
accounting.billing-runs.run | Start reviewed billing runs or retry eligible blocked work. | startBillingRun, retryBillingRun |
accounting.billing-runs.update | Declare run replacement authority, with no checking operation implemented in this module. | No implemented operation |
accounting.billing-templates.bulk | Declare bulk administration of billing instructions, with no checking operation implemented in this module. | No implemented operation |
accounting.billing-templates.create | Create billing instructions. | createBillingTemplate |
accounting.billing-templates.delete | Remove eligible billing instructions. | deleteBillingTemplate |
accounting.billing-templates.read | Inspect billing instructions. | listBillingActions, listBillingTemplates, getBillingTemplate |
accounting.billing-templates.update | Change billing instructions. | updateBillingTemplate |
accounting.installment-plans.bulk | Declare bulk administration of purchase financing definitions, with no checking operation implemented in this module. | No implemented operation |
accounting.installment-plans.create | Create purchase financing definitions. | createInstallmentPlan |
accounting.installment-plans.delete | Remove eligible purchase financing definitions. | deleteInstallmentPlan |
accounting.installment-plans.read | Inspect purchase financing definitions. | listInstallmentPlans, getInstallmentPlan |
accounting.installment-plans.update | Change purchase financing definitions. | updateInstallmentPlan |
accounting.installment-schedules.bulk | Declare bulk administration of repayment arrangements, with no checking operation implemented in this module. | No implemented operation |
accounting.installment-schedules.cancel | Stop eligible repayment arrangements. | cancelInstallmentSchedule |
accounting.installment-schedules.create | Create repayment arrangements. | createInstallmentSchedule |
accounting.installment-schedules.delete | Declare arrangement deletion authority, with no checking operation implemented in this module. | No implemented operation |
accounting.installment-schedules.process | Issue invoices for due amounts in repayment arrangements. | processInstallmentSchedule |
accounting.installment-schedules.query | Query the reporting dataset for repayment arrangements. | query |
accounting.installment-schedules.read | Inspect repayment arrangements or calculate an unsaved financing preview. | previewInstallmentSchedule, listInstallmentSchedules, getInstallmentSchedule |
accounting.installment-schedules.update | Reduce, suspend or resume repayment arrangements and report installment tender outcomes. | reduceInstallmentSchedule, suspendInstallmentSchedule, resumeInstallmentSchedule, recordInstallmentPaymentOutcome |
accounting.installments.query | Query the reporting dataset for individual installments. | query |
accounting.recurring-billing-runs.bulk | Declare bulk administration of recurring billing configuration, with no checking operation implemented in this module. | No implemented operation |
accounting.recurring-billing-runs.create | Create recurring billing configuration. | createRecurringBillingRun |
accounting.recurring-billing-runs.delete | Remove eligible recurring billing configuration. | deleteRecurringBillingRun |
accounting.recurring-billing-runs.read | Inspect recurring billing configuration. | listRecurringBillingRuns, getRecurringBillingRun, listRecurringBillingRunHistory |
accounting.recurring-billing-runs.update | Change recurring billing configuration. | updateRecurringBillingRun |
The catalogue includes all thirty-six declared Billing resource permissions and the application-entry prerequisite. Its public-health row preserves the service contract’s no-permission marker for traceability; it is not a grantable key and belongs to no role. Eight resource keys have no checking operation: configuration bulk keys, run update and bulk, and arrangement delete and bulk. Console bulk selections can still call individual guarded operations; a declared bulk key establishes no additional implemented route. Query permissions authorize their respective datasets through Platform rather than a Billing HTTP operation.
Role Entitlement Matrix
| Permission | Administrator | Power User | Standard User | Read Only |
|---|---|---|---|---|
none: the shared health route (the operation name follows the get<Module>Health pattern of the route library) | — | — | — | — |
accounting.application.access | Yes | Yes | Yes | Yes |
accounting.billing-notices.bulk | Yes | Yes | — | — |
accounting.billing-notices.create | Yes | Yes | — | — |
accounting.billing-notices.delete | Yes | Yes | — | — |
accounting.billing-notices.read | Yes | Yes | Yes | Yes |
accounting.billing-notices.update | Yes | Yes | — | — |
accounting.billing-runs.bulk | Yes | Yes | Yes | — |
accounting.billing-runs.cancel | Yes | Yes | Yes | — |
accounting.billing-runs.create | Yes | Yes | Yes | — |
accounting.billing-runs.delete | Yes | Yes | Yes | — |
accounting.billing-runs.read | Yes | Yes | Yes | Yes |
accounting.billing-runs.run | Yes | Yes | Yes | — |
accounting.billing-runs.update | Yes | Yes | Yes | — |
accounting.billing-templates.bulk | Yes | Yes | — | — |
accounting.billing-templates.create | Yes | Yes | — | — |
accounting.billing-templates.delete | Yes | Yes | — | — |
accounting.billing-templates.read | Yes | Yes | Yes | Yes |
accounting.billing-templates.update | Yes | Yes | — | — |
accounting.installment-plans.bulk | Yes | Yes | — | — |
accounting.installment-plans.create | Yes | Yes | — | — |
accounting.installment-plans.delete | Yes | Yes | — | — |
accounting.installment-plans.read | Yes | Yes | Yes | Yes |
accounting.installment-plans.update | Yes | Yes | — | — |
accounting.installment-schedules.bulk | Yes | Yes | Yes | — |
accounting.installment-schedules.cancel | Yes | Yes | Yes | — |
accounting.installment-schedules.create | Yes | Yes | Yes | — |
accounting.installment-schedules.delete | Yes | Yes | Yes | — |
accounting.installment-schedules.process | Yes | Yes | Yes | — |
accounting.installment-schedules.query | Yes | Yes | Yes | Yes |
accounting.installment-schedules.read | Yes | Yes | Yes | Yes |
accounting.installment-schedules.update | Yes | Yes | Yes | — |
accounting.installments.query | Yes | Yes | Yes | Yes |
accounting.recurring-billing-runs.bulk | Yes | Yes | — | — |
accounting.recurring-billing-runs.create | Yes | Yes | — | — |
accounting.recurring-billing-runs.delete | Yes | Yes | — | — |
accounting.recurring-billing-runs.read | Yes | Yes | Yes | Yes |
accounting.recurring-billing-runs.update | Yes | Yes | — | — |
These entries express the shared built-in roles' Billing grants. A deny or an assignment outside the requested scope can still refuse an action. Workspace export also needs the separately delegated Platform authority described above.
Protected Actions
The catalogue cites the capability guards that apply beyond each permission. Configuration changes are subject to version, lock and dependency protections. Starting reviewed work has lifecycle and version guards, while recovery depends on the eligible execution state. Current authority is resolved again during execution rather than inferred from a successful earlier read.
Recurring ownership carries an administration boundary even when the named owner differs from the person saving configuration. Repayment processing and tender reports have lifecycle, reference and payment-evidence checks. Reconciliation without a payment reference requires a reason; that input rule does not establish a separately approved exception role or a second-person approval gate. No such gate is demonstrated in the scoped implementation.
The module's findings retain gaps in notice-reference protection, stale follow-up eligibility and console action availability. A permission grant does not repair those gaps.
Guards Distinguished From Permissions
A permission answers whether the actor may request an operation in scope. A guard answers whether the selected record, supplied values and present state allow it to proceed. A stale version, locked configuration, invalid transition or unsuitable reference can therefore refuse an authorized person. Business-unit filtering constrains selection; it does not itself supply authority.
Screen visibility and disabled buttons help explain access, but the service remains the enforcement boundary. Confirmation is a user interaction, not an independent permission or a second approval. Trusted machine invocation has a separate authority path and still uses the operation's domain validation.
What People See When Refused
The gateway distinguishes missing or invalid authentication from forbidden access. Its refusal metadata names the coarse access cause and required permissions without identifying the caller or another person. A record outside the workspace is answered as absent rather than disclosed through an identifier lookup.
The run pages gate entry and explain disabled actions where the controls supply a reason. The monitor distinguishes denied reads, missing records and transport failure. Domain refusals can explain a required state, invalid field or stale version after access is established.
Current presentation has limits: the monitor treats action conflicts as changed-run errors even when another guard caused the refusal, and Notices navigation can remain visible without read authority. Those gaps remain findings; seeing a link supplies no access. Installment dataset access also has a recorded integration refusal that needs deployment verification.