40 lines
3.3 KiB
Markdown
40 lines
3.3 KiB
Markdown
# Exception Effect Registry (Type-to-Effect Mapping)
|
|
|
|
## Module
|
|
Policy
|
|
|
|
## Status
|
|
IMPLEMENTED
|
|
|
|
## Description
|
|
Registry mapping (ExceptionType + ExceptionReason) pairs to policy effects (Suppress, Defer, RequireControl). Covers 11 predefined mappings including false_positive, wont_fix, vendor_pending, compensating_control, license_waiver, etc. Extensible via DI configuration with max-duration constraints.
|
|
|
|
## Implementation Details
|
|
- **ExceptionEffectRegistry**: `src/Policy/StellaOps.Policy.Engine/Adapters/ExceptionEffectRegistry.cs` (sealed class implements `IExceptionEffectRegistry`)
|
|
- Uses `FrozenDictionary<(ExceptionType, ExceptionReason), PolicyExceptionEffect>` for immutable O(1) lookups
|
|
- `GetEffect(type, reason)` returns effect for type+reason pair; falls back to `defer-default` effect if unmapped
|
|
- `GetAllEffects()` returns all registered effects
|
|
- `GetEffectById(effectId)` returns effect by ID (case-insensitive lookup)
|
|
- 8 distinct effect templates: suppress, defer, require-control, downgrade-low, downgrade-medium, defer-vendor, suppress-deprecation, suppress-license
|
|
- 40 total mappings across 4 ExceptionTypes (Vulnerability, Policy, Unknown, Component) x 10 ExceptionReasons
|
|
- `PolicyExceptionEffectType` enum: Suppress, Defer, Downgrade, RequireControl
|
|
- MaxDurationDays per effect: suppress=365, defer=90, require-control=180, downgrade=365, defer-vendor=180, suppress-deprecation=90, suppress-license=365, defer-default=30
|
|
- RoutingTemplate per effect for workflow routing (e.g., "deferred-review", "control-verification", "vendor-tracking", "legal-review", "manual-review")
|
|
- **ExceptionType enum**: `src/Policy/__Libraries/StellaOps.Policy.Exceptions/Models/ExceptionObject.cs`
|
|
- Vulnerability, Policy, Unknown, Component
|
|
- **ExceptionReason enum**: same file
|
|
- FalsePositive, AcceptedRisk, CompensatingControl, TestOnly, VendorNotAffected, ScheduledFix, DeprecationInProgress, RuntimeMitigation, NetworkIsolation, Other
|
|
|
|
## E2E Test Plan
|
|
- [ ] `GetEffect(Vulnerability, FalsePositive)` returns effect with Id="suppress", Effect=Suppress, MaxDurationDays=365
|
|
- [ ] `GetEffect(Vulnerability, CompensatingControl)` returns effect with Id="require-control", Effect=RequireControl, RequiredControlId="compensating-control-verification"
|
|
- [ ] `GetEffect(Vulnerability, RuntimeMitigation)` returns effect with Id="downgrade-low", Effect=Downgrade, DowngradeSeverity=Low
|
|
- [ ] `GetEffect(Vulnerability, NetworkIsolation)` returns effect with Id="downgrade-medium", DowngradeSeverity=Medium
|
|
- [ ] `GetEffect(Vulnerability, ScheduledFix)` returns effect with Id="defer", Effect=Defer, MaxDurationDays=90
|
|
- [ ] `GetEffect(Component, DeprecationInProgress)` returns effect with Id="suppress-deprecation", MaxDurationDays=90
|
|
- [ ] `GetEffect(Component, Other)` returns effect with Id="suppress-license", RoutingTemplate="legal-review"
|
|
- [ ] `GetEffect(Vulnerability, VendorNotAffected)` returns effect with Id="suppress"
|
|
- [ ] `GetEffectById("require-control")` returns non-null effect with matching ID
|
|
- [ ] `GetAllEffects()` returns exactly 8 distinct effects (suppress, defer, require-control, downgrade-low, downgrade-medium, defer-vendor, suppress-deprecation, suppress-license)
|
|
- [ ] Unmapped type/reason pair (if any) returns defer-default with MaxDurationDays=30, RoutingTemplate="manual-review"
|