User Management Guide
What You'll Learn
- How users move through the Billerang lifecycle — from invitation to deletion
- How to invite users when SSO is not configured
- How groups control access (and why you rarely need to think about individual roles)
- How to create custom groups for your team's specific needs
- Best practices for keeping your user base clean and secure
Overview
Billerang uses a group-based access model: you assign users to groups, and groups carry a predefined set of roles. You do not assign roles directly to users in normal operation. This keeps access management simple and auditable.
User → belongs to → Group → carries → Roles → grants → Permissions
All user management operations happen through the connect component at /api/portal/users. The portal's User Management page calls these endpoints.
User Lifecycle
Invited → Pending → Active → Disabled → Deleted
| State | How you get here | What the user can do |
|---|---|---|
| Pending | Admin sends invitation | Nothing — waiting for email link |
| Active | User sets password via invitation link | Full access per their group memberships |
| Disabled | Admin sets enabled: false | Cannot log in; data is preserved |
| Deleted | Admin deletes the account | Account and all Keycloak data removed permanently |
If someone is leaving temporarily (parental leave, contractor end-of-contract), set enabled: false. Deletion is permanent and cannot be undone. Disabling preserves audit history and lets you re-enable with one click.
Invitation Flow (non-SSO mode)
When SSO is not configured, users do not create their own accounts. An administrator invites them:
Step 1: Send the invitation
Navigate to Settings > Users and click Invite User, or call the API:
curl -X POST "https://connect.billerang.com/api/portal/users/invite" \
-H "Cookie: $SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@acme.com",
"firstName": "Alice",
"lastName": "Martin",
"groups": ["Billing Manager"]
}'
The user is created in Keycloak with invitationStatus: "pending" and receives an email containing a secure one-time link.
Step 2: User sets their password
The invitation email contains a link valid for 24 hours (configurable in Keycloak). The user clicks it, sets a password, and is redirected to the portal. Their invitationStatus changes to "accepted".
Step 3: Resend if the link expires
Invitation links expire after 24 hours by default. If a user misses the email or the link expires:
curl -X POST "https://connect.billerang.com/api/portal/users/alice.martin/resend-invitation" \
-H "Cookie: $SESSION_COOKIE"
This generates a fresh link and sends a new email.
What changes when SSO is active
When an SSO provider is configured:
- The Invite User button and
POST /api/portal/users/inviteendpoint become unavailable (return 400). - Users authenticate via your corporate identity provider. The first time they log in, Keycloak creates their account automatically.
invitationStatusis always"accepted"for SSO users — they have no invitation step.- Group assignments must happen after the user logs in for the first time, or via IdP attribute mapping if configured.
Group-Based Access Control
Billerang ships with six default groups. For most organizations, these cover common access patterns without any customization.
| Group | Typical user | What they can do |
|---|---|---|
| Platform Admin | IT admin, platform owner | Everything — user management, security, billing, catalog |
| Account Manager | Sales, customer success | Manage customers, accounts, view catalog and orders |
| Billing Manager | Finance team, billing ops | Full billing and invoicing, view accounts and payments |
| Catalog Manager | Product team | Manage offers, products, pricing; view orders |
| Finance Manager | CFO, AR team | Payments, dunning, account receivables, view invoices |
| Viewer | Executives, auditors | Read-only access across all domains |
How group membership works
A user can belong to multiple groups. Their effective role set is the union of all roles from all their groups:
Alice is in: Billing Manager + Viewer
Alice's roles = (all Billing Manager roles) ∪ (all Viewer roles)
There are no conflicts — having a role from two groups simply means you have that role once.
Assigning groups when inviting
Specify the groups in the invitation payload. Alice will be added to those groups immediately when her account is created:
{
"email": "alice@acme.com",
"groups": ["Billing Manager", "Viewer"]
}
Changing group membership later
Use PUT /api/portal/users/{username} with the complete target group list. The groups field replaces the existing membership — it is not additive:
curl -X PUT "https://connect.billerang.com/api/portal/users/alice.martin" \
-H "Cookie: $SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{
"groups": ["Finance Manager", "Viewer"]
}'
Creating Custom Groups
If none of the default groups fit your team's access pattern, create a custom group:
Step 1: Decide which roles you need
Browse the available roles first:
# See all roles in a domain
curl "https://connect.billerang.com/api/portal/roles?domain=billing" \
-H "Cookie: $SESSION_COOKIE"
See Roles and Groups Reference for the complete list of all 73 roles organized by domain.
Step 2: Create the group
curl -X POST "https://connect.billerang.com/api/portal/groups" \
-H "Cookie: $SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Team",
"description": "Customer support — read access to accounts and invoices",
"roles": [
"accounts.customers.view",
"accounts.billingAccounts.view",
"billing.invoices.view",
"finance.payments.view"
]
}'
Step 3: Assign users
You can specify the custom group when inviting new users, or add existing users:
curl -X POST "https://connect.billerang.com/api/portal/groups/Support+Team/members" \
-H "Cookie: $SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{ "username": "bob.smith" }'
Updating a custom group's roles
When you update a group's role set, all current members immediately gain or lose the affected roles:
curl -X PUT "https://connect.billerang.com/api/portal/groups/Support+Team" \
-H "Cookie: $SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{
"description": "Support team with subscription visibility",
"roles": [
"accounts.customers.view",
"accounts.billingAccounts.view",
"accounts.subscriptions.view",
"billing.invoices.view",
"finance.payments.view"
]
}'
Best Practices
Use groups, not direct role assignments
Never try to work around the group model by assigning roles directly. Groups create a clear, auditable chain: "Alice is a Billing Manager, and Billing Managers can view invoices." Direct role assignments scatter access decisions across individual accounts and make audits painful.
Create team-specific groups rather than over-privileged accounts
If your support team needs to view invoices and accounts but nothing else, create a "Support Team" group with exactly those roles. Do not put support staff in "Billing Manager" just because it has the right invoice access.
Disable before you delete
Disabled accounts are preserved in audit logs. Deleted accounts create gaps. When someone leaves your organization, disable first, then delete after your audit retention period.
Review group memberships quarterly
Use the groups listing to check memberCount and the individual group detail endpoint to see the full member list. Former employees, ex-contractors, and unused service accounts should be disabled or removed.
Be careful with Platform Admin
Platform Admin grants full access including security configuration. Limit this group to the people who genuinely need to manage users, configure SSO, and run jobs. Most billing admins belong in Billing Manager, not Platform Admin.
Common Questions
Q: Can I create a user without sending an invitation email?
Yes — use POST /api/portal/users with a temporaryPassword. The user can log in immediately with that password. Keycloak will prompt them to change it on first login.
Q: What happens to a disabled user's data? Nothing. Disabled users cannot authenticate, but all their data (subscription assignments, audit history, billing records) is preserved. Re-enabling the account restores full access.
Q: Can a user be in no groups? Yes, but they will have no roles and will not be able to do anything meaningful in the portal. Always assign at least the Viewer group as a baseline.
Q: How do I find which users have access to a specific role?
Call GET /api/portal/roles/{roleName} — the response includes assignedGroups and assignedUsers, so you can see every user who holds that role either directly or through a group.
Q: What's the difference between deleting a user and removing them from all groups? Removing a user from all groups leaves the Keycloak account active but permission-less — the user can still log in but can do nothing. Deleting the account removes the user entirely. Choose based on whether you expect them to return.