---
title: Authorize a policy for the current user
summary: Evaluates the full authorization matrix to decide whether a principal may view a policy.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-31
library: SAIF.Business.View.Policy
reference_type: package
operation_id: OP-06
trigger: A consumer asks whether the current principal may see a policy
---

# Authorize a policy for the current user

This is the authorization heart of the library. Every consuming application relies on it to decide whether the signed-in user may see a given policy, and the answer depends on both the policy (is it a SAIF-secured policy?) and the user (an agent, a policyholder, a group administrator, a loss-control consultant, a fee auditor, or SAIF staff). The evaluation is ordered so that the hard denials happen before any user-type reasoning, and it fails closed when nothing matches.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-06 |
| **Trigger** | A consumer asks whether the current principal may see a policy |
| **Inputs** | A `clsSecurityPrincipal` and `IDataPortalInfo` supplied to the constructor, plus the target policy or policy number |
| **Outputs** | A boolean access decision |
| **Primary components** | `clsPolicySecurity.IsPolicyValidForUser` |
| **Entry point** | `Business/SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Steps

1. On construction, read the `BDS_USER`, `bdsDatabase`, and `BDS_DATABASENAME` settings and build a second, SQL Server data portal for the group-membership store.
   - Missing or wrong settings are not detected here; the failure appears when the group branch first executes.**
   - See [Configuration](../configuration.md) for the settings and their risks.
2. Classify the principal into a user type — SAIF employee, agent, policyholder, group, loss control, auditor, MCO, medical provider, or bookkeeper.
   - The classification is performed by `clsUserType` from the `SAIF.BOF.Business` package; its internal steps are not visible in this repository.**
3. If the policy's secure-policy code marks it as a SAIF-secured policy and the principal does not hold the `SAIFpolicyInfo` authorization, refuse immediately ([BR-001](../business-rules.md#br-001-secure-saif-policies-require-explicit-authorization)).
   - This check runs before all others, so no user type can bypass it.
4. If the policy is invalid or its policy number is zero, refuse ([BR-002](../business-rules.md#br-002-invalid-or-unnumbered-policies-are-never-accessible)).
   - The policy header must have loaded successfully first ([Retrieve policy header](retrieve-policy-header.md), [SQL-007](../sql/SQL-007-policy-header.md)).
5. Branch on the user type and evaluate the matching rule:
   - SAIF employees, MCO users, medical providers, and bookkeepers are allowed ([BR-003](../business-rules.md#br-003-internal-and-provider-user-types-have-unrestricted-policy-visibility)).
   - An agent is allowed when the trimmed user number matches the policy's agent number or agency sequence number ([BR-004](../business-rules.md#br-004-agents-see-only-their-own-book)).
   - A policyholder is allowed when the target is their own policy or shares a parent association with it ([BR-005](../business-rules.md#br-005-policyholders-see-their-own-policy-and-policies-under-the-same-parent-association)); this loads the user's own policy ([Retrieve policy header](retrieve-policy-header.md)) and its associations ([Resolve policy associations](resolve-policy-associations.md), [SQL-026](../sql/SQL-026-policy-association-union.md)).
   - A group user is allowed when the group-membership procedure `cp_policy_in_group` returns a count greater than zero for the group, chapter, and policy ([BR-006](../business-rules.md#br-006-group-users-see-only-policies-in-their-group-or-chapter)).
   - A loss-control user is allowed when the policy's loss-control team assignment name starts with their identifier ([BR-007](../business-rules.md#br-007-loss-control-consultants-see-only-policies-they-are-assigned-to), [SQL-009](../sql/SQL-009-team-assignments.md)); demo users are matched on the assignment's user-id name instead.
   - An auditor is allowed when a current, non-cancelled audit exists for the policy under their vendor number ([BR-008](../business-rules.md#br-008-fee-auditors-see-only-policies-with-a-recent-non-cancelled-audit), [PA_AUDIT](../database-tables.md#pa-audit)).
6. Return the accumulated decision. A user type that matched no branch leaves the decision at its initial refusal ([BR-019](../business-rules.md#br-019-policy-lists-fail-closed)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Access decision requested]) --> Init[Build the group-membership<br>data portal from settings]
    Init --> UT[Classify the principal]
    UT --> Sec{Secure policy without<br>SAIFpolicyInfo?}
    Sec -->|Yes| Deny([Refuse])
    Sec -->|No| Val{Policy valid and<br>numbered?}
    Val -->|No| Deny
    Val -->|Yes| Br{User type}
    Br -->|SAIF, MCO, provider, bookkeeper| Allow([Allow])
    Br -->|Agent| A1{Agent or agency<br>number matches?}
    Br -->|Policyholder| A2{Same policy or<br>shared parent?}
    Br -->|Group| A3{In group or chapter?}
    Br -->|Loss control| A4{Assignment name<br>prefix matches?}
    Br -->|Auditor| A5{Current audit exists?}
    Br -->|Unmatched| Deny
    A1 -->|Yes| Allow
    A1 -->|No| Deny
    A2 -->|Yes| Allow
    A2 -->|No| Deny
    A3 -->|Yes| Allow
    A3 -->|No| Deny
    A4 -->|Yes| Allow
    A4 -->|No| Deny
    A5 -->|Yes| Allow
    A5 -->|No| Deny
```

## Failure and edge-case behavior

- An unmatched user type is refused rather than allowed, so the operation fails closed ([BR-019](../business-rules.md#br-019-policy-lists-fail-closed)).
- A policy with no loss-control team assignment stays inaccessible to loss-control users ([BR-007](../business-rules.md#br-007-loss-control-consultants-see-only-policies-they-are-assigned-to)).
- A misconfigured group-membership store surfaces only when a group user is evaluated.**
- The policyholder branch performs additional reads, so it is materially more expensive than the other branches.

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)
- [Procedures](../procedures/index.md)
- [Security and authorization](../security-authorization.md)
- [API reference](../api/index.md)

## Sources

- `Business/SAIF.Business.View.Policy/clsPolicySecurity.vb`
- `Business/SAIF.Business.View.Policy/clsPolicyData.vb`
