GitLab’s internal GRC tool originally served the Security Compliance team with a login_required gate on every view. When Internal Audit identified a new use case requiring its own data, workflow, and sensitive information, the single-tenant pattern showed a shortcoming: authenticating users alone did not answer whether they should access a given resource.
- The tool needed to support two distinct customer bases without cross-stream data exposure.
- A unitary authentication check was insufficient for multi-tenant internal tools.
WHAT CHANGED: A CORE PROJECT WITH TWO MODULE APPS
The team restructured the tool into a core Django project that provides shared authentication, user management, and audit logging. On top of this core, two independent modules were built—one for Security Compliance and one for Internal Audit. Each module owns its own models, views, and API surface, and neither module depends on the other. TechStaged has also covered GitHub adds confidential comments to repository security advisories.
- Core has zero knowledge of the specific data domains of the two modules to preserve separation.
- The pattern is designed to be repeatable for future modules that require isolated data handling.
HOW ENFORCEMENT WORKS: MIXINS, PERMISSIONS, AND UI GUARDS
Access control is implemented with a single reusable mechanism in the core app, then subclassed per module. A GroupRequiredMixin checks group membership and raises PermissionDenied if the user isn’t in the required group. Each module uses a dedicated subclass (GasGroupRequiredMixin and IsGasGroupMember) to enforce its boundary. A template filter, user_in_group, supports navigation-level guards so the user interface reflects actual permissions.
- The mixins enforce authorization at all layers—views, APIs, and navigation.
- A UX-only navigation guard complements, but does not replace, the security boundary.
WHAT’S NEXT: GUIDANCE FOR TEAMS BUILDING MULTI-TENANT INTERNAL TOOLS
GitLab emphasizes that this approach creates a foundation that future modules can ride on, reducing infrastructure scaffolding when new audiences enter a tool. The article outlines a practical sequence for teams: identify login-versus-authorization gaps, draw module boundaries, implement a single reusable mixin, and enforce access independently across views, APIs, and navigation.
- Check for login_required versus proper authorization across views.
- Define shared versus module-specific boundaries before coding.
- Develop one reusable mixin at the core, then subclass for each module.
- Enforce access at every layer to ensure UI elements don’t imply security that isn’t there.
RELATED COVERAGE
- GitHub adds confidential comments to repository security advisories
- Stripe Projects Brings “Vibe Deploying” Into a Single Developer Workflow
- GitHub expands SecurityAdvisory GraphQL API with five new fields and two filters
- GitHub opens REST API for repository security advisory comments in public preview
- Developer Tools articles
SOURCES
- GitLab: Two front doors: Module-level access in a Django GRC app Published · Primary source




