Files
mimic-big/backend/src/mimic/rbac/matrix.py

99 lines
2.5 KiB
Python
Raw Normal View History

"""F11 permission matrix as code.
This mirrors the spec table 1:1 keeping it as a single source in code lets
us hash-check it against the spec in CI (spec-analyst task S0.2). Three default
groups are seeded by Alembic and align with the three user types.
"""
from __future__ import annotations
import enum
class Permission(enum.StrEnum):
"""Application permissions. Codes are kebab-case + dotted scope."""
# Engagement
ENGAGEMENT_CREATE = "engagement.create"
ENGAGEMENT_READ = "engagement.read"
ENGAGEMENT_READ_OWN = "engagement.read_own" # scoped to soc_session
ENGAGEMENT_UPDATE = "engagement.update"
ENGAGEMENT_DELETE = "engagement.delete"
ENGAGEMENT_MEMBER_MANAGE = "engagement.member.manage"
ENGAGEMENT_SOC_TOKEN_ISSUE = "engagement.soc_token.issue" # noqa: S105
# Hosts
HOST_CRUD = "host.crud"
# TTPs
TTP_READ = "ttp.read"
TTP_DRAFT = "ttp.draft"
TTP_PROMOTE = "ttp.promote"
# Imports
IMPORT_JOURNAL = "import.journal"
# Scenarios
SCENARIO_CRUD = "scenario.crud"
# Runs
RUN_START = "run.start"
RUN_CONTROL = "run.control"
# Detection / evidence
EVIDENCE_ADD = "evidence.add"
DETECTION_ADD = "detection.add"
# Cleanup
CLEANUP_TRIGGER = "cleanup.trigger"
# Reports
REPORT_GENERATE = "report.generate"
REPORT_READ = "report.read"
# Audit
AUDIT_READ = "audit.read"
# User management (D-015): gates all /api/v1/users CRUD. rt_lead only.
USER_MANAGE = "user.manage"
ALL_PERMISSIONS: tuple[Permission, ...] = tuple(Permission)
class GroupName(enum.StrEnum):
RT_OPERATOR = "rt_operator"
RT_LEAD = "rt_lead"
SOC_ANALYST = "soc_analyst"
# Source-of-truth mapping derived from spec §F11. Verified by tests against
# the spec table.
GROUP_PERMISSIONS: dict[GroupName, frozenset[Permission]] = {
GroupName.RT_OPERATOR: frozenset(
{
Permission.ENGAGEMENT_CREATE,
Permission.ENGAGEMENT_READ,
Permission.HOST_CRUD,
Permission.TTP_READ,
Permission.TTP_DRAFT,
Permission.IMPORT_JOURNAL,
Permission.SCENARIO_CRUD,
Permission.EVIDENCE_ADD,
Permission.CLEANUP_TRIGGER,
Permission.REPORT_READ,
}
),
GroupName.RT_LEAD: frozenset(ALL_PERMISSIONS),
GroupName.SOC_ANALYST: frozenset(
{
Permission.ENGAGEMENT_READ_OWN,
Permission.DETECTION_ADD,
Permission.REPORT_READ,
}
),
}
DEFAULT_GROUPS: tuple[GroupName, ...] = tuple(GroupName)