mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-09-04 14:45:41 +00:00
feat(fleet-sync): hide other replicas' identity-scoped policies on a replica (#973)
GET /api/security/policies on a replica now returns only the policies
that apply to THIS replica. Replicated rows with a node_identity
targeting a sibling replica are filtered out so an operator cannot
enumerate the names and rules of policies meant for another node in
the fleet. Defense in depth: the security panel is admin-only, but a
backend filter is bypass-proof and matches Sencho's privacy posture.
Internal evaluators (getMatchingPolicy, evaluateScanAgainstPolicies)
keep using the unfiltered list because they already enforce identity
matching at evaluation time.
CVE suppressions are fleet-wide on every replica (no node_identity
column) so no analogous filter is needed.
Public surface:
- DatabaseService.getScanPoliciesForUi(role, selfIdentity): the
filtered variant, called from securityRouter.get('/policies').
Tests:
- 3 new vitest cases: control sees full set; replica hides
other-replica scoped rows; replica always includes locally created
rows.
- Full backend suite: 1795 pass / 5 skipped.
This commit is contained in:
@@ -410,7 +410,12 @@ securityRouter.get(
|
||||
|
||||
securityRouter.get('/policies', authMiddleware, (req: Request, res: Response): void => {
|
||||
if (!requirePaid(req, res)) return;
|
||||
res.json(DatabaseService.getInstance().getScanPolicies());
|
||||
// Replicas see only policies that apply to themselves: local-only rows plus
|
||||
// fleet-wide and self-identity-matched replicated rows. Identity-scoped
|
||||
// rows targeting other replicas are filtered out at the SQL boundary.
|
||||
const policies = DatabaseService.getInstance()
|
||||
.getScanPoliciesForUi(FleetSyncService.getRole(), FleetSyncService.getSelfIdentity());
|
||||
res.json(policies);
|
||||
});
|
||||
|
||||
securityRouter.post('/policies', authMiddleware, (req: Request, res: Response): void => {
|
||||
|
||||
Reference in New Issue
Block a user