APPUiO Control API: BillingEntity

This resource implements the "Manage Billing Information" features.

The BillingEntity allows a user to manage billing information in a self-service manner. It allows users to choose where to bill their used resources through a link to the Organization resource. The BillingEntity maps records and fields needed to create invoices from an external ERP to the API. All information required for an invoice can be accessed through the APPUiO Portal and the APPUiO Control API.

It is required that billing data can be modified by the billing entity owner in the APPUiO Portal and by our accounting team in the ERP.

A naive implementation with a controller that synchronizes the BillingEntity resource with the ERP would be problematic. An implementation based on a controller would create a system with multiple sources of truth.

To ensure we have a single source of truth the BillingEntity is a virtual resource that is stored in the ERP and fetched by an aggregated API server. See Billing Entity as Virtual Resource.

Object

Virtual resource
apiVersion: billing.appuio.io/v1
kind: BillingEntity
metadata:
  name: be-2494 (1)
spec:
  name: Cyber AI (2)
  phone: "+41313131313"
  emails: (3)
  - contact@cyberai.example.com
  address:
    line1: "Zisternenstrasse 3f"
    line2: ""
    postalCode: "3600"
    city: "Thun"
  accountingContact: (4)
    name: "Ursula Gurnmeister" (5)
    emails: (6)
    - ursula.gurnmeister@cyberai.example.com
    - contact@cyberai.example.com
  languagePreference: de (7)
1 The name of the BillingEntity is the billing accounts partner ID in the ERP. It is prefixed with be- to keep the name RFC 1035 compliant.
Keeping the name RFC 1035 compliant is not strictly necessary, but it makes it easier to use the name in other contexts.
2 The name of the company. Also used as the display name.
3 The general contact email address of the company.
4 The accounting contact information. Used when generating invoices.
5 The name of the accounting contact person. Used in the "c/o" line of the invoice.
6 The email addresses of the accounting contact person. Invoices are sent to these addresses.
7 The language preference of the company. Used when generating invoices for text content not from the billing system. Future use.
Organization resource
apiVersion: organization.appuio.io/v1 (1)
kind: Organization
spec:
  billingEntityRef: be-234234 (2)
status:
  billingEntityName: Acme Corp. (3)
1 Only relevant fields are shown for brevity.
2 The billingEntityRef is the reference to the BillingEntity resource. Every Organization resource must have a reference to a BillingEntity resource.
3 The cached display name of the BillingEntity resource.

Access Control

We use the same access control mechanism for BillingEntity as for Organization resources.

We use standard Kubernetes role-based access control for BillingEntity with two distinct differences.

  1. Access needs to be granted for billingentities resources in API group rbac.appuio.io and not for resources in API group billing.appuio.io. Permissions can be configured through both Roles and RoleBindings, as well as ClusterRoles and ClusterRoleBindings.

  2. For list and watch verbs the API server will only return resources that the user also has permission to get

The rbac.appuio.io API group allows us to delegate access control to the aggregate API server. With the new API group we can still use the powerful RBAC engine of Kubernetes, while bypassing the Kubernetes API server’s access control. As a consequence, by introducing this logical RBAC group, no custom code needs to be written in order to implement the access control required for multi-tenancy. The Kubernetes API server will still perform classical access control for billingentities.billing.appuio.io resources. In practice any user is allowed to perform any action on billingentities.billing.appuio.io and access control is handled by the aggregate API server.

Users with the view role on a BillingEntity can reference it in Organization resources.

Data Flow

Billing Data Flow