After authentication confirms user identity, authorization determines what they can access. This post covers two powerful authorization models: Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC), with practical Go implementations.
Authorization Models Overview
flowchart TD
subgraph Models["Authorization Models"]
ACL[ACL - Access Control Lists]
RBAC[RBAC - Role-Based]
ABAC[ABAC - Attribute-Based]
end
ACL --> |User -> Resource| Simple[Simple permissions]
RBAC --> |User -> Role -> Permission| Medium[Scalable roles]
ABAC --> |Policies + Attributes| Complex[Dynamic rules]
style RBAC fill:#e3f2fd
style ABAC fill:#e8f5e9
| Model | Complexity | Use Case |
|---|---|---|
| ACL | Low | Simple apps, file systems |
| RBAC | Medium | Most applications |
| ABAC | High | Complex, dynamic requirements |
Role-Based Access Control (RBAC)
Core Concepts
flowchart LR
U[User] --> R[Role]
R --> P[Permissions]
subgraph Roles
R1[Admin]
R2[Manager]
R3[User]
end
subgraph Permissions
P1[Create]
P2[Read]
P3[Update]
P4[Delete]
end
R1 --> P1
R1 --> P2
R1 --> P3
R1 --> P4
R2 --> P2
R2 --> P3
R3 --> P2
RBAC Implementation
Database Models
1 | // models/rbac.go |
Permission Service
1 | // services/rbac.go |
RBAC Middleware
1 | // middleware/rbac.go |
Using RBAC in Routes
1 | func SetupRoutes(r *gin.Engine, rbacService *RBACService) { |
Seeding Roles and Permissions
1 | func SeedRBAC(db *gorm.DB) { |
Attribute-Based Access Control (ABAC)
ABAC makes decisions based on attributes of the user, resource, action, and environment.
flowchart TD
subgraph Attributes
U[User Attributes
Department, Level]
R[Resource Attributes
Owner, Sensitivity]
A[Action Attributes
Read, Write]
E[Environment
Time, Location]
end
subgraph Policy["Policy Engine"]
P[Policy Rules]
end
U --> P
R --> P
A --> P
E --> P
P --> D{Decision}
D -->|Allow| Allow[Access Granted]
D -->|Deny| Deny[Access Denied]
style Policy fill:#e3f2fd
ABAC Implementation
Policy Definition
1 | // models/abac.go |
ABAC Service
1 | // services/abac.go |
ABAC Middleware
1 | func ABACMiddleware(abacService *ABACService, resource, action string) gin.HandlerFunc { |
Example ABAC Policies
1 | // Policy: Users can only read documents from their department |
Combining RBAC and ABAC
1 | func CombinedAuthMiddleware(rbac *RBACService, abac *ABACService, resource, action string) gin.HandlerFunc { |
Resource Ownership Check
1 | func ResourceOwnerMiddleware(resource string, getOwnerID func(c *gin.Context) uint) gin.HandlerFunc { |
Summary
| Model | Best For | Implementation |
|---|---|---|
| RBAC | Most applications | Roles + Permissions tables |
| ABAC | Complex, dynamic rules | Policy engine + attributes |
| Combined | Enterprise apps | RBAC base + ABAC overrides |
flowchart TD
R[Request] --> Auth[Authentication]
Auth --> RBAC{RBAC Check}
RBAC -->|Has Role| ABAC{ABAC Check}
RBAC -->|No Role| D1[Deny]
ABAC -->|Policy Allows| Allow[Allow]
ABAC -->|Policy Denies| D2[Deny]
style RBAC fill:#e3f2fd
style ABAC fill:#e8f5e9
Next post: Securing Go APIs: OWASP Best Practices - Protecting your API against common security vulnerabilities.
Comments