---
title: SAIF.Application.Policy security and authorization
summary: Authorization resources, enforcement points, data-level checks, and security risks for the policy application layer.
status: draft
owner: SAIF Documentation Generation
last_reviewed: 2026-07-31
library: SAIF.Application.Policy
reference_type: package
---

# SAIF.Application.Policy security and authorization

This page documents the mixed authorization model implemented by `SAIF.Application.Policy`. The library classifies user roles with local `IsAuthorized` and domain checks, delegates per-policy authorization to `SAIF.Business.View.Policy`, and filters policy-header association types and association rows before rendering.

## Authorization architecture

Authorization is split across two local managers and one delegated dependency. `clsPolicySecurity` classifies the current principal into policy-facing roles; `clsPolicyHeaderSecurityManager` computes which association types and association rows the principal may see; and `PolicyAppManager.UserCanAccessPolicy` delegates policy-level access control to `SAIF.Business.View.Policy.clsPolicySecurity` except when `HttpContext.Current Is Nothing`, where the application layer grants access unconditionally. The library also applies three demo-masking gates and two visibility gates after authorization decisions have been made.

```mermaid
flowchart TD
    Caller[Calling application] --> Manager[PolicyAppManager]
    Manager --> LocalRoles[clsPolicySecurity]
    Manager --> ViewSecurity[View.Policy clsPolicySecurity]
    Manager --> HeaderSecurity[clsPolicyHeaderSecurityManager]
    HeaderSecurity --> AssocTypes[Association type security]
    HeaderSecurity --> AssocRows[Association row filtering]
    Manager --> HeaderProvider[clsStandardPolicyHeaderDataProvider]
    HeaderProvider --> Visibility[Demo and field visibility gates]
```

## AD resource catalog

| Resource name | Purpose | Enforcement point | Source |
| --- | --- | --- | --- |
| `AgencyExternal` | Marks an external agency user and contributes to agent status | `clsPolicySecurity.IsAgent` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `ARPAgencyExternal` | Marks an assigned-risk-plan agency user and contributes to agent status | `clsPolicySecurity.IsAgent` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `ProducerExternal` | Marks a producer and contributes to agent status | `clsPolicySecurity.IsProducer` / `IsAgent` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `AuditorExternal` | Marks an external fee auditor | `clsPolicySecurity.IsAuditorUser` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `BusinessOnlineDemo` | Marks a demo user and enables masking | `clsPolicySecurity.IsDemoUser` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `GroupsOnlineExternal` | Marks a group user | `clsPolicySecurity.IsGroupUser` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `LossControlExternal` | Marks an external loss-control consultant | `clsPolicySecurity.IsLossControlUser` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `DivPolicyholderExternal` | Marks an external policyholder | `clsPolicySecurity.IsPolicyHolder` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `PolicyPayrollQuickFileExternal` | Marks a payroll quick-file user | `clsPolicySecurity.IsQuickFileUser` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `UWQuoteUser` | Declared underwriting-quote resource constant that is not consumed by compiled code* | `clsPolicySecurity` constant only | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `<SecurityGroupName>` | Internal-user access to a secured association type | `clsPolicyHeaderSecurityManager` | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |
| `<SecurityGroupName>Ext` | External-user access to a secured association type | `clsPolicyHeaderSecurityManager` | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |

## Authorization enforcement points

### Attribute-based authorization

No attribute-based authorization is implemented in this library.

### Programmatic authorization checks

| Class | Method | Resource / Role | Check type | Source |
| --- | --- | --- | --- | --- |
| `clsPolicySecurity` | `IsAgent` | `AgencyExternal`, `ProducerExternal`, `ARPAgencyExternal` | `IsAuthorized` and delegated property composition | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsProducer` | `ProducerExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsAuditorUser` | `AuditorExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsDemoUser` | `BusinessOnlineDemo` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsGroupUser` | `GroupsOnlineExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsLossControlUser` | `LossControlExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsPolicyHolder` | `DivPolicyholderExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsQuickFileUser` | `PolicyPayrollQuickFileExternal` | `IsAuthorized` | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsSAIFEmployee` | Domain `SAIF` | Identity comparison | `Application\SAIF.Application.Policy\clsPolicySecurity.vb` |
| `clsPolicyHeaderSecurityManager` | `ValidatedUserAssociationType` | `<SecurityGroupName>` / `<SecurityGroupName>Ext` | `IsAuthorized` | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |
| `PolicyAppManager` | `UserCanAccessPolicy` | Delegated policy-level access decision | Dependency call or unconditional allow | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |
| `PolicyAppManager` | `OnRetrieve` | Access outcome application | Context/no-access/message update | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |

## Data-level authorization

| Entity type | Validation method | Mechanism | Source |
| --- | --- | --- | --- |
| Policy | `PolicyAppManager.UserCanAccessPolicy` | Delegates to `SAIF.Business.View.Policy.clsPolicySecurity.IsPolicyValidForUser(PolicyData)`; returns `True` unconditionally when `HttpContext.Current Is Nothing` | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |
| Policy association type | `clsPolicyHeaderSecurityManager.GetValidAssociationTypes` | Secured types require the principal to hold the matching internal or external security-group resource | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |
| Policy header association row (policyholder) | `clsPolicyHeaderSecurityManager.FilterAssociationsByUserType` | Keep only association types where the user's own policy is the parent | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |
| Policy header association row (agent) | `clsPolicyHeaderSecurityManager.FilterAssociationsByUserType` | Keep only rows whose `AgentNumber` or `AgencySeqNum` matches the user's number | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |

## Security interfaces and contracts

| Interface / Class | Role | Consumers | Source |
| --- | --- | --- | --- |
| `clsSecurityPrincipal` | Ambient authorization and identity service used by both local security managers | `PolicyAppManager`, `clsPolicySecurity`, `clsPolicyHeaderSecurityManager`, `clsStandardPolicyHeaderSettings`, `clsStandardPolicyHeaderDataProvider` | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |
| `IPolicyHeaderSettings` | Contract for security-filtered header settings and visibility flags | `PolicyAppManager`, header consumers | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |
| `IApplicationTestInformationProvider` | Contract for diagnostic test-information values shown outside production | `clsStandardPolicyHeaderSettings` consumers | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |
| `SAIF.Business.View.Policy.clsPolicySecurity` | Delegated policy-level authorization dependency | `PolicyAppManager` | `Application\SAIF.Application.Policy\PolicyAppManager.vb` |

## Security risks and open questions
- **Clear risk — HttpContext bypass.** `UserCanAccessPolicy` grants access unconditionally when `HttpContext.Current Is Nothing`, so non-web hosts bypass authorization. This risk is explicit and unresolved.
- **Clear risk — process-wide `Shared` authorization caches never invalidate.** Association types, resolved user numbers, and per-user validated association types are cached in `Shared` collections with no observed invalidation strategy beyond process recycling.*
- **Clear risk — fixed Oracle DB user `GEN`.** `DataLayer.DBUser = "GEN"` means database-level access cannot distinguish callers, so the data-layer identity used during authorization-adjacent reads is fixed for every user.
- **Clear risk — empty `OnCheckSecurity` override.** `PolicyAppManager.OnCheckSecurity` has an empty body, leaving `OnRetrieve` as the effective application-level security hook and raising an unresolved gap question for derived hosts.**
- `RateAccountNumber` and `RelationshipDescription` read the unfiltered association set rather than `ValidatedAssociations`; whether those values were intentionally left outside row-level filtering could not be confirmed.**
- The runtime dependency version of `SAIF.Business.View.Policy` is a 1.x package, while the documented library in this run is a 2.x codebase, so delegated authorization behavior may drift across versions.**

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **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
- `Application\SAIF.Application.Policy\PolicyAppManager.vb`
- `Application\SAIF.Application.Policy\clsPolicySecurity.vb`
- `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb`
- `Application\SAIF.Application.Policy\PolicyHeader\clsStandardPolicyHeaderDataProvider.vb`
- `Application\SAIF.Application.Policy\PolicyHeader\clsStandardPolicyHeaderSettings.vb`
- `Business\SAIF.Business.View.Policy\clsPolicySecurity.vb`
