When building applications with user permissions, Role-Based Access Control (RBAC) provides a structured way to define who can perform specific actions. Instead of scattering authorization logic throughout your codebase, RBAC organizes permissions into roles that determine access across different parts of an application. This guide walks through implementing RBAC in a Golang application using Oso Cloud.
It covers defining role-based rules, and filtering data based on user roles. Whether managing organizational roles, resource-specific roles, or cross-organization access, this approach ensures consistent authorization decisions across your system.
What is Role-Based Access Control (RBAC) in Golang?
Roles are a common way to simplify authorization logic for engineers and users. Authorization logic that’s based on roles is called “role-based access control.” It allows access control decisions to be based on predefined roles rather than individual users.
Authentication vs. Authorization
Before diving deeper into RBAC, it's important to distinguish between authentication and authorization:
a. Authentication verifies a user’s identity (e.g., logging in with a username and password, using OAuth, or biometric authentication). Most developers integrate third-party authentication providers (e.g., OAuth, OpenID Connect) rather than building authentication from scratch.
b. Authorization determines what a user is allowed to do after authentication. Unlike authentication, developers often implement authorization logic in-house, as it can be tightly coupled with business rules.
Why is RBAC needed?
Without RBAC, managing permissions in an application can become complex and error-prone, especially as the number of users and resources grows. Hardcoding permissions or managing them on a per-user basis leads to security risks and maintenance challenges. RBAC addresses these issues by:
- Providing a structured way to group permissions under roles, reducing duplication.
- Making it easier to modify access rules without changing application code.
- Improving security by ensuring least privilege access.
For example, in a SaaS application, RBAC can help:
- Restrict access to admin panels to only users with an "admin" role.
- Control API endpoints so that only users with the "developer" role can modify application settings.
- Protect databases, allowing only "database administrators" to execute ALTER statements.
Common RBAC concepts
Roles: A role is a way to group permissions. When a user is assigned a role, the user gets every permission that the role has. Some examples of roles are: `admin`
, `editor`
, `viewer`
.
Permissions: A permission is an action that a user can take on a resource. For example, we might say that a user in an organization has permission to `read`
repositories.
Policies: A policy defines how roles and permissions interact. For example, we might say an `admin`
role has `delete`
permission on all resources.
There are a number of variations on role-based access to allow for more flexible groupings of permissions, like:
a. Organizational roles
b. Cross-organization roles
c. Resource-specific roles
DIY RBAC vs. using an authorization service
When implementing RBAC in Golang, developers have two main options: building RBAC in-house (DIY) or using a third-party authorization service like Oso Cloud.
Challenges of DIY RBAC
Manually implementing RBAC often starts simple—storing roles and permissions in a database—but quickly becomes complex as requirements grow:
a. Scalability issues – Managing permissions across multiple microservices or tenants becomes difficult.
b. Policy changes require code updates – Hardcoded permissions lead to frequent deployments.
c. Difficult to extend – Adding fine-grained controls (e.g., resource-based permissions, hierarchical roles) increases complexity.
d. Security risks – Maintaining audit logs and preventing privilege escalation requires extra effort.
DIY vs. third-party authorization service
a. Setup: DIY requires custom role structures, databases, and enforcement logic. Authorization services provide prebuilt policies and integrations.
b. Scalability: Every time you add a new type of authorization logic to a DIY system, you have to build it yourself. Services handle things like hierarchy and multi-tenancy automatically.
c. Security: DIY needs manual audits and debugging. Services offer built-in validation (logging, auditing, etc.) and reduce misconfigurations.
d. Performance: DIY relies on database queries. Services use optimized, low-latency authorization checks.
e. Flexibility: DIY only supports what you build. Services support RBAC, ReBAC, and hybrid models.
Why use Oso Cloud?
Oso Cloud simplifies authorization by providing:
- Declarative RBAC policies – Define roles and permissions without modifying application code.
- Hybrid models – Supports RBAC + ReBAC + ABAC, enabling fine-grained, relationship and attribute based access.
- Centralized management – Enforce consistent authorization across services and teams in microservices architectures.
For teams that need more than basic role checks—such as cross-organization roles or hierarchical permissions—Oso Cloud offers a scalable alternative to DIY solutions. Let's dive into it.
Oso Cloud is an authorization service for building RBAC in Go
a. Oso Cloud is fully-managed and deployed across multiple regions for low-latency and high availability
b. Oso Cloud comes out of the box with primitives for role-based access control (RBAC). It also includes built-ins for other access control models like relationship-based access control (ReBAC) or attribute-based access control (ABAC).
c. You provide Oso Cloud with the requisite authorization data, then your RBAC policy operates over that data to make authorization decisions at runtime.
d. Oso can provide yes/no authorization decisions, as well as filter lists of data.
Express RBAC in Go with Oso Cloud
To authorize whether a user has the role required to perform an action on a resource, call Oso in your controller.
user := NewValue("User", GetCurrentUser())
repo := NewValue("Repository", repoName)
oso.Authorize(user, "read", repo)
You’ll also write an Oso policy—that is, a set of rules—to implement role-based authorization. Here, we’ll show a policy for an app for source code hosting like GitHub or GitLab.
In this policy, users may or may not be able to read or make changes to a repository, depending on whether they’re members or owners. That means we need authorization based on users’ roles.
actor User {}
resource Organization {
roles = ["owner"];
}
resource Repository {
permissions = ["read", "push"];
roles = ["contributor", "maintainer"];
relations = { parent: Organization };
"read" if "contributor";
"push" if "maintainer";
"contributor" if "maintainer";
"maintainer" if "owner" on "parent";
}
For a detailed guide on RBAC concepts, read our technology-agnostic Authorization Academy.
Oso isn’t limited to Role-based access control. It comes with primitives for other common access control models, like Relationship-based access control, or ReBAC. For a guide on other authorization patterns, take a look at our guide on authorization modeling covering roles, hierarchies, groups, and other patterns.
Filter data based on a user’s role
Your app needs to be able to return all the repos that a user can see based on their role and any other relevant criteria. To do this we can use the list method.
Here's that in the Go app again:
user := NewValue("User", GetCurrentUser())
repos, err := oso.List(user, "read", "Repository")
Learn how to implement authorization in Go
To implement authorization in Go using Oso, start by installing the Oso Go SDK (go get github.com/osohq/go-oso-cloud/v2
).
Define roles and permissions using the declarative Polar language, such as granting "admin" users permission to edit documents. Once your policies are defined, load them into your Go app and enforce authorization checks to determine if a user can perform an action.
For detailed implementation steps, check out the Go SDK documentation.
Learn more about RBAC concepts, architecture, and best practices
We've written the Authorization Academy to help you get started with RBAC and other authorization topics. The guide is language and technology-agnostic and covers industry-standard authorization concepts. Learn:
a. How to architect your app for RBAC.
b. Common access control models like role-based access control (RBAC) and relationship-based access control (ReBAC) – like when to use them and how to implement them.
c. Where to enforce authorization at various layers in your app.
Conclusion
Join the community of thousands of developers in the Oso Slack (including many Gophers!) and feel free to set up a 1x1 with an Oso engineer to learn more about RBAC in Go, Oso Cloud, or just authorization in general. We'd love to talk about what you're working on and answer any questions you have.