---
title: PolicySecurityService
summary: API reference for PolicySecurityService.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-24
library: SAIF.Services
reference_type: package
---

# PolicySecurityService

Determines whether a policy is visible to a given user by classifying the user (SAIF employee, agent/producer, policyholder, MCO, or medical provider) via `IUserProfileService`/`IApplicationUserProfile.IsAuthorized` checks and then testing that classification against policy, agent, and agency data read through `IUnitOfWork` repositories, delegating affiliated/related-policy lookups to `IPolicyAssociationService`. It caches per-user authorization results (agent, producer, MCO, medical-provider, policyholder) in `KeyValuePair<string, bool>` fields keyed by user ID so repeated checks in the same request avoid re-evaluating `IsAuthorized`.*

## Purpose
- Validates that a single policy is accessible to the current user or a specified user, based on the user's classification and the policy's security attributes.
- Filters a batch of policies (`ValidatePoliciesForCurrentUser`/`ValidatePoliciesForSpecifiedUser`) down to only those the user is entitled to see, using the same classification rules.
- Restricts access to SAIF corporate "secure" policies (`SecurePolicyCode == "SAIF"`) to users holding the `SAIFPolicyInfo` authorization resource.
- Resolves an agent/producer's "book" of policies (their own policies as a producer, or their agency's active producers' policies as an agency user) for use in bulk validation.

## Context
- Namespace: `SAIF.Services.Policies.SecurityServices`
- Assembly/package: `SAIF.Services` (packaged inside the `SAIF.SAIFCode.Core` NuGet package).

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| PolicySecurityService (constructor) | `public PolicySecurityService(IUnitOfWork uow, IUserProfileService userProfileService, IPolicyAssociationService policyAssociationService)` | Wires the unit of work, user-profile service, and policy-association service used to classify the caller and resolve affiliated policies. |
| IsValidPolicyForCurrentUser | `public bool IsValidPolicyForCurrentUser(long policyNumber)` | Returns `true` if the current authenticated user's classification (SAIF employee, agent, policyholder, MCO, or medical provider) grants access to the given policy. |
| IsValidPolicyForSpecifiedUser | `public bool IsValidPolicyForSpecifiedUser(long policyNumber, string userId)` | Same access check as `IsValidPolicyForCurrentUser`, but evaluated for an explicitly named user rather than the current caller. |
| ValidatePoliciesForSpecifiedUser\<T\> | `public IEnumerable<T> ValidatePoliciesForSpecifiedUser<T>(IEnumerable<T> policiesToValidate, string userId) where T : IPolicyNumber` | Filters the supplied policy collection down to the subset the named user is entitled to see, based on the user's classification. |
| ValidatePoliciesForCurrentUser\<T\> | `public IEnumerable<T> ValidatePoliciesForCurrentUser<T>(IEnumerable<T> policiesToValidate) where T : IPolicyNumber` | Filters the supplied policy collection down to the subset the current user is entitled to see, based on the user's classification. |

## Behavioral notes
- User classification (`IsSaifEmployee`, `IsAgent`, `IsProducer`, `IsMco`, `IsMedProvider`, `IsPolicyholder`) is driven entirely by `IApplicationUserProfile.IsAuthorized` checks against fixed security-resource names (e.g. `AgencyExternal`, `ARPAgencyExternal`, `ProducerExternal`, `MCO`, `MedicalProvidersExternal`, `ClaimProfileExternalPolicyholder`) and the `SAIF` domain flag.
- Access to policies flagged with `SecurePolicyCode == "SAIF"` additionally requires the `SAIFPolicyInfo` authorization resource (`HasSaifPolicyAccess`), cached per user ID.
- Agent/producer validity is resolved by loading the `Policy` from `IUnitOfWork.GetRepository<Policy>()`, mapping it to a `PolicySecurityInfo` (via a static AutoMapper map created once in the type's static constructor), and comparing the mapped agent/agency IDs to the caller's `CustomerId`/`CustomerGroupId`.
- Policyholder-affiliated policies are resolved by delegating to `IPolicyAssociationService.GetAllPolicyAssociations` and matching by parent or member policy number.
- Producer and agency "book" lists (`ProducerBookList`, `AgencyBookList`) are lazily computed once per instance and cached in private fields; the agency book excludes producers whose `ExpirationDate` has passed.
- The internal security-resource constants (`AGENT_USER`, `ARP_AGENT_USER`, `PRODUCER_USER`) are `internal`, not `public`, but are reused by the `SecurityExtensions.IsAgent` extension method declared in the same assembly.*

## Constraints and usage notes
- All three constructor parameters are null-checked via `Enforce.ArgumentNotNull` before assignment.
- Per-user cached properties (`HasSaifPolicyAccess`, `IsOneOfAgentTypes`, `IsProducer`, `IsMco`, `IsMedProvider`, `IsPolicyholder`) key their cache on `UserToValidate.UserId`, so switching the target user (current vs. specified) within the same instance correctly re-evaluates the check.*
- `ValidatePoliciesForSpecifiedUser`/`ValidatePoliciesForCurrentUser` return an empty sequence for any user classification not explicitly handled (i.e., a user who is none of SAIF employee, policyholder, agent, MCO, or medical provider gets no policies back).

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `Services/SAIF.Services/Policies/SecurityServices/PolicySecurityService.cs`
