If you build software used by more than one organisation, or by several kinds of people inside one, then authorisation, deciding who can see and do what, is one of the most important things you will get right or wrong. A single mistake can expose one customer's data to another, the kind of incident that ends contracts and makes the news. This guide explains role-based access control (RBAC), the main approaches to multi-tenancy, and the engineering practices that keep data where it belongs.

Authentication versus authorisation
Authentication establishes identity: this is Priya from Acme Ltd. Authorisation decides what she may do: view invoices, edit customers, delete projects. They are separate concerns, and confusing them causes real bugs. Strong authentication, through single sign-on, multi-factor authentication and well-managed sessions, is necessary but not sufficient; you must also check permissions on every request.

What is RBAC?
In role-based access control, permissions are grouped into roles, and users are assigned roles. An "Accountant" role might allow viewing and exporting invoices; a "Manager" might also approve expenses; an "Admin" can manage users. Roles simplify administration and make policy understandable. Design them around real job functions and use the principle of least privilege: grant the minimum needed. Avoid an explosion of ad hoc roles by defining a manageable set and using permissions, the individual capabilities such as invoice.read and invoice.approve, as the building blocks.
When roles are not enough
Real applications often need finer control than global roles provide. Examples: a sales rep can see only their own accounts, a regional manager only their region, a project member only the projects they belong to, a client user only their organisation's records. This is object-level or attribute-based authorisation: decisions based on the relationship between the user and the specific resource, sometimes with attributes such as department, region or status. Model the relationships explicitly in your data, for example membership tables, and check them in a central authorisation layer, not scattered through the code.
The number one API vulnerability
Broken object-level authorisation, where an endpoint accepts an ID and returns the record without checking that the caller may see it, is consistently ranked among the most common and serious flaws in web applications and APIs. An attacker simply changes the ID in a request from 1001 to 1002 and reads someone else's data. The defence is straightforward but must be universal: every access to every object must be authorised against the caller's identity and tenant, in the server, regardless of what the interface shows. Hiding a button is not security. See our article on common web vulnerabilities.
Multi-tenancy: sharing without leaking
Multi-tenant software serves many customers, the tenants, from one platform. The core question is how strongly to separate their data:
- Shared tables with a tenant identifier. Every table has a tenant column and every query filters on it. It is the most economical and scalable, but a single missing filter leaks data, so enforcement must be systematic.
- Schema per tenant. Each tenant gets a separate schema in a shared database. It improves separation and eases per-tenant backup, but schema migrations must be applied to every tenant.
- Database per tenant. Strong isolation, simpler tenant-level restores and data residency, at higher cost and operational complexity as tenants multiply.
- Deployment per tenant. Complete separation and customisation, typical for large enterprise or regulated customers, but expensive to operate.
Many products mix approaches: shared infrastructure for most customers and dedicated resources for premium or regulated ones. Your choice depends on customer expectations, regulatory needs, budget and scale. Our article on modular monoliths shows how such a structure can be organised.
Enforce isolation in the data layer, not just the application
Relying on every developer remembering to add a tenant filter is a recipe for eventual failure. Add systematic protection:
- Central tenant context. Resolve the tenant once per request from the authenticated session, and make it available to all data access.
- Scoped data access layers. Use repository or ORM features that automatically apply the tenant filter, so queries without it are impossible or fail loudly.
- Row-level security in the database, where supported. Policies enforce tenant boundaries even if application code forgets, adding a second, independent barrier.
- Tenant-scoped keys and caches. Include the tenant in cache keys, file storage paths and search indexes; the caching rules in our caching guide apply.
- Tenant-aware background jobs. Jobs and events must carry the tenant context and run within it.
- Careful cross-tenant features, such as support tooling and analytics, with explicit, audited access paths.
Design permissions to be understandable
Define permissions in a central catalogue, with clear names and descriptions. Provide sensible default roles and let administrators customise within limits. Show users why access was denied, and let admins see effective permissions for any user. Version and test the policy. When features are added, define who can use them at the same time, and default to deny. Provide safe delegation, such as time-limited access for support, which is granted, logged and expires automatically.

Audit everything that matters
Log authentication events, permission changes, access to sensitive records, exports, deletions and administrative actions, with who, what, when and from where. Protect logs from tampering, retain them per your obligations and make them searchable. Audit trails support investigations, compliance and customer trust, and they deter misuse. We discuss the enterprise angle in our audit log and compliance article.

Test for leaks continuously
- Automated tests that create two tenants and verify that user A cannot read, update or delete tenant B's objects across every endpoint and background job.
- Permission matrix tests for each role against each action.
- Static analysis and linting that flag queries without tenant scoping.
- Penetration tests and code review focused on authorisation, including ID manipulation, parameter tampering and privilege escalation.
- Monitoring for anomalies, such as a user requesting many sequential IDs.
Common mistakes
- Checking permissions only in the user interface.
- Trusting tenant or user IDs supplied by the client.
- Forgetting tenant checks in exports, search, file downloads and background jobs.
- Global admin accounts with no audit trail or MFA.
- Hard-coding role checks throughout the code instead of using a central policy.
- Failing to revoke access when people change roles or leave.
Data protection beyond access control
Complement RBAC with encryption in transit and at rest, per-tenant keys for sensitive data where appropriate, backups that respect tenant boundaries, data retention and deletion by tenant, and support for data residency requirements. Clear policies and contracts should reflect what you actually implement; see our privacy guide.
Getting it right early
Authorisation and tenancy are hardest to retrofit. Deciding the model at the start, building central enforcement and automating leak tests costs little compared with fixing a design where tenant checks are sprinkled everywhere. If you are planning a SaaS platform or a multi-role business application, our software team will design the tenancy model, permissions and testing strategy with you, and our hosting options support the isolation level your customers expect.
Put this into practice with CodeLuma
CodeLuma designs multi-tenant, role-aware applications where every request is checked and every tenant's data stays separate, with automated tests that catch permission leaks before your customers do.
- Custom software development - tailored systems, integrations and internal tools.
- Website and web application development - fast, accessible, search-friendly builds.
- Managed hosting - monitored, backed-up, Canadian-friendly hosting.
Start a conversation. Tell us about your project and we will reply with practical next steps, or browse all CodeLuma services. CodeLuma Development Inc. is based in Nova Scotia and works with teams across Canada and remotely.


