This version of Kill Bill is not supported anymore, please see our latest documentation

Terminology: In this documentation, a user means a 'user or the api', which maps to the user credential passed through api.

Assumptions: We assume the reader went through the Getting started documentation and has a running system (both killbill and kaui) running on IP=127.0.0.1.

Each request to Kill Bill requires authentication. The authentication phase verifies that the user exists in the system and that its credentials are correct. Once the credentials have been validated, the roles associated to the user are then extracted, and then the set of permissions associated to each role are also retrieved. The credentials are passed in the request using http basic authentication mechanism. Kill Bill relies on shiro for the backend implementation.

Note that the authentication/authorization is orthogonal to the tenant access: The set of permissions associated to a given user is the same for all tenants (for which he has the keys). So, a potential superuser with all the permissions and with access to the api_key/api_secret for all tenants would have full control of the entire system. It is common practise to create a cross-tenant admin with the ability to only manage tenants and nothing else, and then have one superadmin per tenant,…​

User Management APIs

Configuration of the User/Role/Permissions

Shiro supports multiple backend implementations, and we integrated 3 of them:

  • Simple configuration file (shiro.ini file)

  • Database configuration

  • LDAP integration

For simple deployments where only few static users/roles need to be assigned, the shiro.ini file is the simplest and the best option. For large entreprise solution, an LDAP integration is probably the most flexible. For cases where LDAP is not available, a good middle ground is to rely on a mixed solution between the shiro.ini file and the database backend. This is what the rest of this section will describe:

Kill Bill offers apis to manage the users/roles/permissions, where new user/roles/permissions will be stored in a database. As described earlier, apis calls require authorization/authentication so there is a catch-22 situation here, hence the mixed approach:

  • The shiro.ini file is used to configure the initial user (could be a superadmin with all permissions or an admin with just enough permissions to manage the user/roles). For simplicity we will call it superadmin will assign one role containing all permissions.

  • Once deployed, the 'superadmin' is now able to make api calls to configure new users/roles.

The shiro.ini file will look like the following:

#
# Use -Dorg.killbill.security.shiroResourcePath=/var/tmp/shiro.ini to specify your own config
#

[users]
superadmin = superadmin13, root

[roles]
root = *:*

Let’s create a new role customer_support:

curl -v \
-u "superadmin:superadmin123"  \
-H "X-Killbill-CreatedBy: stephane" \
-H "Content-Type: application/json" \
-X POST \
--data-binary '{ "role": "customer_support", "permissions": ["account:create", "account:update", "entitlement:change_plan", "entitlement:pause_resume", "entitlement:cancel", "entitlement:transfer", "invoice:credit", "invoice:item_adjust", "tag:create_tag_definition", "tag:delete_tag_definition", "tag:add", "tag:delete"] }' \
'http://127.0.0.1:8080/1.0/kb/security/roles'

Let’s create a cs username that will have only one role customer_support:

curl -v \
-u 'superadmin:superadmin123' \
-H "X-Killbill-CreatedBy: stephane" \
-H "Content-Type: application/json" \
-X POST \
--data-binary '{ "username": "cs", "password": "cs123", "roles": ["customer_support"] }' \
'http://127.0.0.1:8080/1.0/kb/security/users'

Let’s assume we want to add more permissions to that user. We could create another role customer_support_manager (same step as before with the desired set of permissions), and then update our user to now have this new role:

curl -v \
-u 'superadmin:superadmin123' \
-H "X-Killbill-CreatedBy: stephane" \
-H "Content-Type: application/json" \
-X PUT \
--data-binary '{ "username": "cs", "password": "cs123", "roles": ["customer_support_manager"] }' \
'http://127.0.0.1:8080/1.0/kb/security/users/cs/roles'

Tenant Configuration

Since we did not give access for all the tenant management to our new CS account, let’s have our superadmin create a first tenant:

curl -v \
-X POST \
-u superadmin:superadmin123 \
-H 'Content-Type: application/json' \
-H 'X-Killbill-CreatedBy: admin' \
-d '{"apiKey": "bob", "apiSecret": "lazar"}' \
"http://127.0.0.1:8080/1.0/kb/tenants"

Play Time…​

Assuming our cs user knows about the api_key and api_secret of the tenant, he should now be able to make any api calls against that tenant (with the limitation of his permission set).

So for instance, creating a new account in that tenant would work because his role customer_support includes the permission account:create:

curl -v \
-u cs:cs123 \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"name":"John Doe","email":"[email protected]","externalKey":"john-doe-1234","currency":"USD"}' \
"http://127.0.0.1:8080/1.0/kb/accounts"

But the following curl to refund a payment would fail because his role customer_support does not include the permission payment:refund:

curl -v \
-u cs:cs123 \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"amount":"12.4"}' \
"http://127.0.0.1:8080/1.0/kb/invoicePayments/288983f2-5143-47e4-b967-b8962fc699d1/refunds"

KAUI

KAUI has been extended to understand all the user/role/permission management and will manage the corresponding sessions. Some of those implementation details were covered in https://killbill.io/blog/multi-tenancy-authorization[our previous blog post}.

However KAUI does not yet have the flexibility to manage the user/roles/permissions, and also requires making each user known available.

Initial Configuration

However the catch-22 situation described in the previous section to configure the very first user remains true both for killbill and KAUI:

  • For killbill server, we already described the initial configuration through the shiro.ini file

  • For KAUI, we need to also make that admin account visible (this is a small limitation configuration). Note that the credentials, roles,…​ associated to that account are entirely managed on the server side (killbill) so there is no duplication or security holes.

In the kaui database, insert the initial entry for the superadmin:

insert into kaui_allowed_users (kb_username, description, created_at, updated_at) values ('superadmin', 'super admin', NOW(), NOW());

Adding new Allowed User

Before our new cs user can be able to login to KAUI, the superadmin must make it visible. The screen /admin_allowed_users (the top right icon will bring you there), allows to enter that user. Only the name and a descriuption needs to be entered (and not the credentials/roles which are managed by the backend) need to be entered.

After entering a new user, the UI will allow to select the tenants this user has access to.