Security

Kill Bill supports fine grained roles and permissions for the users accessing the system either through the UI or API. This can be useful in case of organizations looking to limit access across departments/teams etc. The endpoints in this group manage the users, roles and the associated permissions.

Please refer to our RBAC manual for more details.

Users

A user refers to any user or the api that maps to the user credential passed through the API.

User Roles Resource

A userRoles object contains the username, the password and the roles associated with the user.

Name Type Generated by Description
username string user Username for this user.
password string user Password for this user.
roles list user List of roles associated with this user.

Subject Resource

A Subject resource contains the information of the currently logged-in user as well as the related session information.

Name Type Generated by Description
principal string user Username for this user.
isAuthenticated boolean user Is the user authenticated.
isRemembered boolean user Specifies if Remember Me is checked for this user.
session json system Session information for the user. Refer Session Resource for more information.

Role Definition Resource

A RoleDefinition resource contains the information of the permissions associated with a role.

Name Type Generated by Description
role string user Name of the role.
permissions list user List of permissions associated with the role.

Session Resource

A Session resource contains the session information of the currently logged-in user.

Name Type Generated by Description
id string system UUID for this session.
startDate datetime system Specifies the start date for the session in UTC.
lastAccessDate datetime system Specifies the last access timestamp within the session in UTC.
timeout long system Specifies the default time in ms that any session may remain idle before expiring.
host string system Specifies the host information for the session.

List user permissions

Lists the permissions associated with the current API user.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/security/permissions

Example Request:

curl -v \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Accept: application/json" \
    "http://localhost:8080/1.0/kb/security/permissions"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.Strings;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

Strings currentUserPermissions = securityApi.getCurrentUserPermissions(requestOptions);
securityApi = KillBillClient::Model::Security

currentUserPermissions = securityApi.find_permissions(options)
securityApi = killbill.SecurityApi()

currentUserPermissions = securityApi.get_current_user_permissions()
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const currentUserPermissions: AxiosResponse<string[],any> = await securityApi.getCurrentUserPermissions();
$apiInstance = $client->getSecurityApi();

$currentUserPermissions = $apiInstance->getCurrentUserPermissions();

Example Response:

[
  "invoice:commit",
  "invoice:item_adjust",
  "entitlement:pause_resume",
  "invoice:write_off",
  "account:credit",
  "account:create",
  "invoice:credit",
  "entitlement:cancel",
  "account:update",
  "invoice:void",
  "payment:transition",
  "account:charge",
  "payment:refund",
  "invoice:delete_cba",
  "invoice:dry_run",
  "payment:chargeback",
  "payment:trigger",
  "entitlement:transfer",
  "entitlement:create",
  "payment:notification",
  "entitlement:change_plan"
]

Query Parameters

None.

Response

If successful, returns a status code of 200 and a list of permissions associated with the current API user.

Get user information

Lists the session information associated with the currently logged-in (principal) user.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/security/subject

Example Request:

curl -v \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Accept: application/json" \
    "http://localhost:8080/1.0/kb/security/subject"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.Subject;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

Subject currentUserSubject = securityApi.getCurrentUserSubject(requestOptions);
securityApi = KillBillClient::Model::Security

currentUserSubject = securityApi.find_subject(options)
securityApi = killbill.SecurityApi()

currentUserSubject = securityApi.get_current_user_subject()
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const currentUserSubject: AxiosResponse<killbill.Subject,any> = await securityApi.getCurrentUserSubject();
$apiInstance = $client->getSecurityApi();

$currentUserSubject = $apiInstance->getCurrentUserSubject();

Example Response:

{
  "principal": "admin",
  "isAuthenticated": true,
  "isRemembered": false,
  "session": {
    "id": "f6738239-b803-4fa5-85b9-b3ad13a8312c",
    "startDate": "2023-11-12T07:17:56.856Z",
    "lastAccessDate": "2023-11-12T07:27:03.792Z",
    "timeout": 3600000,
    "host": "0:0:0:0:0:0:0:1"
  }
}

Query Parameters

None.

Response

If successful, returns a status code of 200 and the session information associated with the current API user.

Add a new user with roles

Create a new user (username, password, associated roles).

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/security/users

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "username": "testUserName", "password": "testUserPassword", "roles": ["TestRole"]}' \
    "http://localhost:8080/1.0/kb/security/users"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.UserRoles;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

List<String> roles = List.of("TestRole");

UserRoles userRoles = new UserRoles();

userRoles.setUsername("TestUserName");
userRoles.setPassword("TestUserPassword");
userRoles.setRoles(roles);

UserRoles newUserDetails = securityApi.addUserRoles(userRoles, requestOptions);
user = 'user'
reason = 'reason'
comment = 'comment'

userRoles = KillBillClient::Model::UserRoles.new

userRoles.username = 'TestUserName'
userRoles.password = 'TestUserPassword'
userRoles.roles = ['TestRole']

userRoles.create(user,reason,comment,options)
securityApi = killbill.SecurityApi()

userBody = killbill.UserRoles(username = 'testUserName',
                              password = 'testUserPassword',
                              roles=['TestRole','finance'])

securityApi.add_user_roles(userBody,
                           created_by='demo',
                           reason='reason', 
                           comment='comment')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const body: killbill.UserRoles = {username: 'testUserName',
                                  password: 'testUserPassword',
                                  roles: ['TestRole', 'finance']};

securityApi.addUserRoles(body,'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$body = new UserRoles();

$body->setUsername('TestUserName');
$body->setPassword('TestUserPassword');
$body->setRoles(['TestRole']);

$apiInstance->addUserRoles($body,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Request Body

A UserRoles object consisting of the username, password and the roles to be associated with the user. The required attributes are username,password,roles.

Query Parameters

None.

Response

If successful, returns a status code of 201 and the UserRoles object for the newly created user.

Update a user password

Updates the password for a user.

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/security/users/{username}/password

curl -v \
    -X PUT \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "username": "testUserName", "password": "Updatedpassword"}' \
    "http://localhost:8080/1.0/kb/security/users/{username}/password"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.UserRoles;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

String userName = "TestUserName";

UserRoles userRoles = new UserRoles();

userRoles.setPassword("TestUserPassUpdated");    

securityApi.updateUserPassword(userName, userRoles, requestOptions);
user = 'user'
reason = 'reason'
comment = 'comment'

userRoles = KillBillClient::Model::UserRoles.new

userRoles.username = 'userName'
userRoles.password = 'userNameUpdatedpassword'

userRoles.update(user,reason,comment,options)
securityApi = killbill.SecurityApi()

userRoles = killbill.UserRoles(username='userName',
                               password='userNameUpdatedpassword',
                               roles=['TestRole'])

securityApi.update_user_password('userName',
                                  userRoles,
                                  created_by='demo',
                                  reason='reason', 
                                  comment='comment')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const body: killbill.UserRoles = {username: 'userName',
                                  password: 'userNameUpdatedpassword',
                                  roles: ['TestRole', 'finance']};

securityApi.updateUserPassword(body, 'userName', 'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$body = new UserRoles();

$body->setUsername('TestUserName');
$body->setPassword('TestUserUpdatedPassword');
$body->setRoles(['TestRole']);

$apiInstance->updateUserPassword($body,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Request Body

A userRoles object consisting of the username, password and the roles to be associated with the user. The required attributes are username,password,roles.

Query Parameters

None

Response

If successful, returns a status code of 204 and an empty body.

Get roles associated with a user

Lists the roles associated with a user.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/security/users/{username}/roles

Example Request:

curl -v \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Accept: application/json" \
    "http://localhost:8080/1.0/kb/security/users/{username}/roles"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.UserRoles;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

String userName = "testuser";

UserRoles userRoles = securityApi.getUserRoles(userName, requestOptions);
userRoles = KillBillClient::Model::UserRoles.new

userRoles.username = 'testuser'

userRoles.list(options)
securityApi = killbill.SecurityApi()

userRoles = securityApi.get_user_roles('testUser')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const response: AxiosResponse<killbill.UserRoles,any> = await securityApi.getUserRoles('testUser');
$apiInstance = $client->getSecurityApi();

$username = 'testUser';

$userRoles = $apiInstance->getUserRoles($username);

Example Response:

{
  "username": "testUser",
  "password": null,
  "roles": [
    "TestRole"
  ]
}

Query Parameters

None

Response

If successful, returns a status code of 200 and a UserRoles object.

Update roles associated with a user

Updates the roles associated with a user.

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/security/users/{username}/roles

Example Request:

curl -v \
    -X PUT \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{"roles":["TestRole"]}' \
    "http://localhost:8080/1.0/kb/security/users/{username}/roles"
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.UserRoles;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

List<String> roles = List.of("UpdatedRole");

UserRoles userRoles = new UserRoles();

String userName = "TestUser";

userRoles.setRoles(roles);

securityApi.updateUserRoles(userName, userRoles, requestOptions);
user = 'user'
reason = 'reason'
comment = 'comment'

userRoles = KillBillClient::Model::UserRoles.new

userRoles.username = 'TestUser'
userRoles.roles = ['UpdatedRole']

userRoles.update(user,reason,comment,options)
securityApi = killbill.SecurityApi()

userRoles = killbill.UserRoles(username='testUser',                               
                               roles=['TestRole'])

securityApi.update_user_roles('testUser',
                               userRoles,
                               created_by='demo',
                               reason='reason', 
                               comment='comment')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const body: killbill.UserRoles = {username: 'testUser',
                                  password: 'testUserPassword',
                                  roles: ['TestRole']};

securityApi.updateUserRoles(body, 'testUser', 'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$body = new UserRoles();

$body->setUsername('TestUserName');
$body->setPassword('TestUserPassword');
$body->setRoles(['TestUpdatedRole']);

$apiInstance->updateUserRoles($body,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Request Body

A userRoles object consisting of the username, password and the roles to be associated with the user. The required attributes are username,password,roles.

Query Parameters

None

Response

If successful, returns a status code of 204 and an empty body.

Invalidate an existing user

Invalidates a user.

HTTP Request

DELETE http://127.0.0.1:8080/1.0/kb/security/users/{username}

Example Request:

curl -v \
    -X DELETE \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \    
    "http://localhost:8080/1.0/kb/security/users/{username}"
import org.killbill.billing.client.api.gen.SecurityApi;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

String userName = "testuser";

securityApi.invalidateUser(userName, requestOptions);
user = 'user'
reason = 'reason'
comment = 'comment'

userRoles = KillBillClient::Model::UserRoles.new

userRoles.username = 'TestUser'

userRoles.destroy(user,reason,comment,options)
securityApi = killbill.SecurityApi()

securityApi.invalidate_user('testUser',
                             created_by='demo',
                             reason='reason', 
                             comment='comment')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

securityApi.invalidateUser('testUser', 'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$username = 'username';

$apiInstance->invalidateUser($username,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Query Parameters

None

Response

If successful, returns a status code of 204 and an empty body.

Roles

Kill Bill allows to segregate permissions associated with a user by defining the roles assigned to the user. For example, a user having finance role can have permissions associated to the payments, viewing invoice etc. whereas a user having sales role can have permissions to generate invoices, viewing payments etc.

Retrieve a role definition

Retrieve an existing role definition.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/security/roles/{role}

Example Request:

curl -v \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Accept: application/json" \
     'http://127.0.0.1:8080/1.0/kb/security/roles/{role}'
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.RoleDefinition;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

String role = "TestRole";

RoleDefinition roleDefinition = securityApi.getRoleDefinition(role, requestOptions);
securityApi = killbill.SecurityApi()

role = 'TestRole'

roleDefinition = securityApi.get_role_definition(role)
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const roleDefinition:AxiosResponse<killbill.RoleDefinition,any> = await securityApi.getRoleDefinition('TestRole');
$apiInstance = $client->getSecurityApi();

$role = 'TestRole';

$roleDefinition = $apiInstance->getRoleDefinition($role);

Example Response:

{
  "role": "ROLE",
  "permissions": [
    "account:*",
    "invoice:trigger"
  ]
}

Query Parameters

None.

Response

If successful, returns a status code of 200 and the role object with associated permissions.

Add a role definition

Create a new role definition.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/roles

Example Request:

curl -v \
     -X POST \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Content-Type: application/json" \
     -H "X-Killbill-CreatedBy: demo" \
     -d '{
             "role": "ROLE",
             "permissions": ["account:*","invoice:trigger"]
     }' \
     'http://127.0.0.1:8080/1.0/kb/security/roles'
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.RoleDefinition;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

List<String> permissions = List.of("account:*", "invoice:trigger");

String role = "TestRole";

RoleDefinition roleDefinition = new RoleDefinition();
roleDefinition.setRole(role);
roleDefinition.setPermissions(permissions);

RoleDefinition newRoleDefinition = securityApi.addRoleDefinition(roleDefinition, requestOptions);
user = 'user'
reason = 'reason'
comment = 'comment'

roleDef = KillBillClient::Model::RoleDefinition.new

roleDef.role = 'testRole17thDec'
roleDef.permissions = ["account:*", "invoice:trigger"]

roleDef.create(user,reason,comment,options)
securityApi = killbill.SecurityApi()

roleDefinition =killbill.RoleDefinition(role='TestRole',
                                        permissions=["account:*","invoice:trigger"])

securityApi.add_role_definition(roleDefinition,
                                created_by='demo',
                                reason='reason', 
                                comment='comment')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const body: killbill.RoleDefinition = {role: 'TestRole',
                                       permissions: ['account:*', 'invoice:trigger']};

securityApi.addRoleDefinition(body, 'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$roleDefinition = new RoleDefinition();

$roleDefinition->setRole('TestRole');
$roleDefinition->setPermissions(['account:*', 'invoice:trigger']);

$apiInstance->addRoleDefinition($roleDefinition,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Request Body

A RoleDefinition object consisting of the role and the list of permissions to be associated with the role. The required attributes are role and the associated permissions.

Query Parameters

None.

Response

If successful, returns a status code of 201 and an empty body.

Update a role definition

Update an existing role permissions.

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/roles

Example Request:

curl -v \
     -X PUT \
     -u admin:password \
     -H "X-Killbill-ApiKey: bob" \
     -H "X-Killbill-ApiSecret: lazar" \
     -H "Content-Type: application/json" \
     -H "X-Killbill-CreatedBy: demo" \
     -d '{
             "role": "ROLE",
             "permissions": ["account:*"]
     }' \
     'http://127.0.0.1:8080/1.0/kb/security/roles'
import org.killbill.billing.client.api.gen.SecurityApi;
import org.killbill.billing.client.model.gen.RoleDefinition;

SecurityApi securityApi = new SecurityApi(killBillHttpClient);

List<String> permissions = List.of("account:*", "invoice:trigger");

String role = "TestRole";

RoleDefinition roleDefinition = new RoleDefinition();
roleDefinition.setRole(role);
roleDefinition.setPermissions(permissions);

securityApi.updateRoleDefinition(roleDefinition, requestOptions);
securityApi = killbill.SecurityApi()

roleDefinition =killbill.RoleDefinition(role='TestRole',
                                        permissions=["invoice:trigger"])

securityApi.update_role_definition(roleDefinition,'KB')
const securityApi: killbill.SecurityApi = new killbill.SecurityApi(config);

const body: killbill.RoleDefinition = {role: 'TestRole',
                                       permissions: ['invoice:trigger']};

securityApi.updateRoleDefinition(body, 'created_by');
$apiInstance = $client->getSecurityApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$roleDefinition = new RoleDefinition();

$roleDefinition->setRole('TestRole');
$roleDefinition->setPermissions(['account:*', 'invoice:*']);

$apiInstance->updateRoleDefinition($roleDefinition,$xKillbillCreatedBy,$xKillbillReason,$xKillbillComment);

Request Body

A RoleDefinition object consisting of the role and the list of permissions to be associated with the role. The required attributes are role and the associated permissions.

Query Parameters

None.

Response

If successful, returns a status code of 204 and an empty body.