| name | check-orgid |
| description | Audit backend code to ensure all queries properly filter by OrgId for multi-tenant security |
| disable-model-invocation | false |
| allowed-tools | Read, Grep, Glob |
Check OrgId Security Skill
Audit backend services to ensure proper OrgId filtering for multi-tenant data isolation.
Instructions
This skill performs a security audit to verify that all database queries properly filter by OrgId.
What to Check
- Service Files: All files in
backend/omsapi/Services/ ending with Service.cs
- Query Methods: Methods that query the database (GetList, GetById, etc.)
- Update/Delete Methods: Methods that modify or delete data
Security Requirements
CRITICAL: The OmsContext does NOT have global query filters enabled. All queries MUST manually filter by OrgId.
Query Methods (Get/List)
Must include: .Where(x => x.OrgId == currentOrgId)
Example:
public async Task<List<EntityDto>> GetListAsync()
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entities = await _context.Entities
.Where(x => x.OrgId == currentOrgId)
.ToListAsync();
return entities.Select(MapToDto).ToList();
}
Update/Delete Methods
Must verify OrgId ownership before modification:
public async Task<EntityDto> UpdateAsync(long id, UpdateEntityDto dto)
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = await _context.Entities
.Where(x => x.Id == id && x.OrgId == currentOrgId)
.FirstOrDefaultAsync();
if (entity == null)
throw new Exception("Entity not found or access denied");
}
Audit Process
-
Find all service files:
Glob pattern: backend/omsapi/Services/*Service.cs
-
For each service file:
- Read the file content
- Identify all methods that query
_context
- Check if they filter by OrgId
-
Look for violations:
- Queries without
.Where(x => x.OrgId == currentOrgId)
- Update/Delete without OrgId verification
- Direct
.Find() or .FirstOrDefault() without OrgId filter
-
Report findings:
- List files with violations
- Show specific line numbers
- Provide fix recommendations
Common Violations
❌ Missing OrgId filter:
var entities = await _context.Entities.ToListAsync();
✓ Correct:
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entities = await _context.Entities
.Where(x => x.OrgId == currentOrgId)
.ToListAsync();
❌ Update without verification:
var entity = await _context.Entities.FindAsync(id);
✓ Correct:
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = await _context.Entities
.Where(x => x.Id == id && x.OrgId == currentOrgId)
.FirstOrDefaultAsync();
Exceptions
Some services may legitimately skip OrgId filtering:
- AuthService: Handles authentication across organizations
- OrgService: Manages organizations themselves
- SystemConfigService: May need cross-org access for SuperAdmin
- UserService: Some methods may need cross-org for admin features
For these exceptions, verify they have proper role-based authorization checks.
Output Format
Provide a report with:
- Summary: Total services checked, violations found
- Violations: List each file and method with issues
- Recommendations: Specific fixes for each violation
- Severity: Critical (data leak risk) vs Warning (needs review)
Example:
OrgId Security Audit Report
===========================
Summary:
- Services checked: 15
- Violations found: 3
- Critical issues: 2
- Warnings: 1
Critical Issues:
1. ProductService.cs:45 - GetListAsync()
Missing OrgId filter on query
Fix: Add .Where(x => x.OrgId == currentOrgId)
2. OrderService.cs:78 - DeleteAsync()
No OrgId verification before delete
Fix: Add OrgId check in Where clause
Warnings:
1. UserService.cs:120 - GetAllUsersAsync()
Cross-org query detected - verify authorization
Automated Fix
If user approves, can automatically add OrgId filters to violations:
- Identify the query location
- Add
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId(); if missing
- Add
.Where(x => x.OrgId == currentOrgId) to the query
- Update the file
Always ask for confirmation before modifying code.