Policies
A policy (also called an “access recipe”) is a set of rules that governs who can retrieve which artifacts from a dock. Policies are composable, versioned, and support staged rollout.
Recipe Structure
A policy recipe defines:
- Who — Which recipients or recipient groups are authorized
- What — Which artifacts (by type, metadata, or explicit IDs) are accessible
- How — What authentication factors are required
- When — Optional time-based constraints (effective dates, expiration)
Persona-Based Recipes
Each stakeholder type has distinct access requirements. Here are the four standard recipe patterns:
Mortgagee — Bulk API Access
Insurance
Real Estate
Healthcare
Financial Services
{
"name": "Mortgagee Bulk Access",
"stakeholderClass": "mortgagee",
"artifactTypes": ["declaration-page", "certificate-of-insurance", "endorsement"],
"auth": {
"factors": ["shared_passphrase", "tls_certificate"],
"tls": { "require_mutual": true, "min_version": "1.2" }
},
"access": {
"method": "bulk_api",
"max_batch_size": 10000
},
"match": {
"identifiers": ["lender_id", "policy_number"]
}
}
Mortgagees authenticate with a shared passphrase (generated via the Secrets API) and a mutual TLS certificate. They access documents through the bulk retrieval API, pulling thousands of dec pages per job.{
"name": "Lender Bulk Access",
"stakeholderClass": "mortgagee",
"artifactTypes": ["closing-disclosure", "deed-of-trust", "settlement-statement", "title-policy"],
"auth": {
"factors": ["shared_passphrase", "tls_certificate"],
"tls": { "require_mutual": true, "min_version": "1.2" }
},
"access": {
"method": "bulk_api",
"max_batch_size": 10000
},
"match": {
"identifiers": ["lender_id", "file_number"]
}
}
Mortgage lenders authenticate with a shared passphrase (generated via the Secrets API) and a mutual TLS certificate. They access closing documents through the bulk retrieval API, pulling thousands of closing disclosures and title policies per job.{
"name": "Payer Bulk Access",
"stakeholderClass": "mortgagee",
"artifactTypes": ["explanation-of-benefits", "claim-summary", "pre-authorization"],
"auth": {
"factors": ["shared_passphrase", "tls_certificate"],
"tls": { "require_mutual": true, "min_version": "1.2" }
},
"access": {
"method": "bulk_api",
"max_batch_size": 5000
},
"match": {
"identifiers": ["payer_id", "member_id"]
}
}
Payers authenticate with a shared passphrase (generated via the Secrets API) and a mutual TLS certificate. They access claims and benefits documents through the bulk retrieval API, pulling thousands of EOBs and claim summaries per job.{
"name": "Investor Bulk Access",
"stakeholderClass": "mortgagee",
"artifactTypes": ["promissory-note", "closing-disclosure", "appraisal", "underwriting-decision"],
"auth": {
"factors": ["shared_passphrase", "tls_certificate"],
"tls": { "require_mutual": true, "min_version": "1.2" }
},
"access": {
"method": "bulk_api",
"max_batch_size": 10000
},
"match": {
"identifiers": ["investor_id", "loan_number"]
}
}
Warehouse lenders and investors authenticate with a shared passphrase (generated via the Secrets API) and a mutual TLS certificate. They access loan documents through the bulk retrieval API, pulling thousands of promissory notes and closing disclosures per job.
Agent — Portal + Bulk Download
Insurance
Real Estate
Healthcare
Financial Services
{
"name": "Agent Portal Access",
"stakeholderClass": "agent",
"artifactTypes": ["declaration-page", "policy-packet", "endorsement", "renewal-notice"],
"auth": {
"factors": ["webauthn"],
"webauthn": { "challenge_type": "platform_or_cross_platform" }
},
"access": {
"method": ["portal", "bulk_download"]
},
"match": {
"identifiers": ["agency_code", "policy_number"]
}
}
Insurance agents authenticate with a WebAuthn challenge — a FIDO2 security key or device biometric. They access documents through the branded portal for single lookups, or bulk download for client batch operations.{
"name": "Title Agent Portal Access",
"stakeholderClass": "agent",
"artifactTypes": ["title-commitment", "closing-disclosure", "deed-of-trust", "settlement-statement", "escrow-instructions", "title-search"],
"auth": {
"factors": ["webauthn"],
"webauthn": { "challenge_type": "platform_or_cross_platform" }
},
"access": {
"method": ["portal", "bulk_download"]
},
"match": {
"identifiers": ["agent_license", "file_number"]
}
}
Title agents and escrow officers authenticate with a WebAuthn challenge — a FIDO2 security key or device biometric. They access closing and title documents through the branded portal for single lookups, or bulk download for file batch operations.{
"name": "Provider Portal Access",
"stakeholderClass": "agent",
"artifactTypes": ["lab-results", "imaging-report", "referral-letter", "discharge-summary", "visit-summary"],
"auth": {
"factors": ["webauthn"],
"webauthn": { "challenge_type": "platform_or_cross_platform" }
},
"access": {
"method": ["portal", "bulk_download"]
},
"match": {
"identifiers": ["npi_number", "member_id"]
}
}
Healthcare providers authenticate with a WebAuthn challenge — a FIDO2 security key or device biometric. They access clinical documents through the branded portal for single patient lookups, or bulk download for panel batch operations.{
"name": "Loan Officer Portal Access",
"stakeholderClass": "agent",
"artifactTypes": ["loan-estimate", "closing-disclosure", "application-packet", "rate-lock", "underwriting-decision", "appraisal"],
"auth": {
"factors": ["webauthn"],
"webauthn": { "challenge_type": "platform_or_cross_platform" }
},
"access": {
"method": ["portal", "bulk_download"]
},
"match": {
"identifiers": ["nmls_id", "loan_number"]
}
}
Loan officers authenticate with a WebAuthn challenge — a FIDO2 security key or device biometric. They access loan documents through the branded portal for single borrower lookups, or bulk download for pipeline batch operations.
Policyholder — Single Retrieval
Insurance
Real Estate
Healthcare
Financial Services
{
"name": "Policyholder Self-Service",
"stakeholderClass": "policyholder",
"artifactTypes": ["declaration-page", "id-card", "renewal-notice"],
"auth": {
"factors": ["sms_otp"],
"otp": { "delivery": "sms", "code_length": 6, "ttl_seconds": 300 }
},
"access": {
"method": "portal",
"max_concurrent_downloads": 1
},
"match": {
"identifiers": ["email", "date_of_birth", "policy_number"]
}
}
Policyholders verify their identity with email/phone + date of birth, then receive a 6-digit SMS OTP to authorize retrieval. Access is limited to their own documents via the self-service portal.{
"name": "Buyer Self-Service",
"stakeholderClass": "policyholder",
"artifactTypes": ["closing-disclosure", "deed", "settlement-statement", "title-policy"],
"auth": {
"factors": ["sms_otp"],
"otp": { "delivery": "sms", "code_length": 6, "ttl_seconds": 300 }
},
"access": {
"method": "portal",
"max_concurrent_downloads": 1
},
"match": {
"identifiers": ["email", "date_of_birth", "file_number"]
}
}
Buyers verify their identity with email/phone + date of birth, then receive a 6-digit SMS OTP to authorize retrieval. Access is limited to their own closing documents via the self-service portal.{
"name": "Patient Self-Service",
"stakeholderClass": "policyholder",
"artifactTypes": ["explanation-of-benefits", "lab-results", "visit-summary", "immunization-record", "discharge-summary"],
"auth": {
"factors": ["sms_otp"],
"otp": { "delivery": "sms", "code_length": 6, "ttl_seconds": 300 }
},
"access": {
"method": "portal",
"max_concurrent_downloads": 1
},
"match": {
"identifiers": ["email", "date_of_birth", "member_id"]
}
}
Patients verify their identity with email/phone + date of birth, then receive a 6-digit SMS OTP to authorize retrieval. Access is limited to their own health records via the self-service portal.{
"name": "Borrower Self-Service",
"stakeholderClass": "policyholder",
"artifactTypes": ["loan-estimate", "closing-disclosure", "promissory-note", "payment-schedule"],
"auth": {
"factors": ["sms_otp"],
"otp": { "delivery": "sms", "code_length": 6, "ttl_seconds": 300 }
},
"access": {
"method": "portal",
"max_concurrent_downloads": 1
},
"match": {
"identifiers": ["email", "date_of_birth", "loan_number"]
}
}
Borrowers verify their identity with email/phone + date of birth, then receive a 6-digit SMS OTP to authorize retrieval. Access is limited to their own loan documents via the self-service portal.
Auditor — Time-Boxed Read-Only
Insurance
Real Estate
Healthcare
Financial Services
{
"name": "External Audit Access",
"stakeholderClass": "auditor",
"artifactTypes": ["*"],
"auth": {
"factors": ["badge_id", "nda_hash"],
"nda": { "hash_algorithm": "sha256", "require_match": true }
},
"access": {
"method": "portal",
"read_only": true,
"download_enabled": false
},
"match": {
"identifiers": ["badge_id", "nda_hash"]
},
"constraints": {
"time_window": {
"start": "2025-01-15T00:00:00Z",
"end": "2025-02-15T00:00:00Z"
},
"auto_expire": true
}
}
Auditors authenticate with a badge ID and the SHA-256 hash of their signed NDA. Access is read-only, non-downloadable, and automatically expires when the time window closes — no manual revocation needed.{
"name": "RESPA/TRID Compliance Audit",
"stakeholderClass": "auditor",
"artifactTypes": ["*"],
"auth": {
"factors": ["badge_id", "nda_hash"],
"nda": { "hash_algorithm": "sha256", "require_match": true }
},
"access": {
"method": "portal",
"read_only": true,
"download_enabled": false
},
"match": {
"identifiers": ["badge_id", "nda_hash"]
},
"constraints": {
"time_window": {
"start": "2025-01-15T00:00:00Z",
"end": "2025-02-15T00:00:00Z"
},
"auto_expire": true
}
}
RESPA/TRID compliance auditors authenticate with a badge ID and the SHA-256 hash of their signed NDA. Access is read-only, non-downloadable, and automatically expires when the time window closes — no manual revocation needed.{
"name": "HHS OIG Investigation Access",
"stakeholderClass": "auditor",
"artifactTypes": ["*"],
"auth": {
"factors": ["badge_id", "nda_hash"],
"nda": { "hash_algorithm": "sha256", "require_match": true }
},
"access": {
"method": "portal",
"read_only": true,
"download_enabled": false
},
"match": {
"identifiers": ["badge_id", "nda_hash"]
},
"constraints": {
"time_window": {
"start": "2025-01-15T00:00:00Z",
"end": "2025-02-15T00:00:00Z"
},
"auto_expire": true
}
}
HHS OIG investigators authenticate with a badge ID and the SHA-256 hash of their signed NDA. Access is read-only, non-downloadable, and automatically expires when the time window closes — no manual revocation needed.{
"name": "Regulatory Examination Access",
"stakeholderClass": "auditor",
"artifactTypes": ["*"],
"auth": {
"factors": ["badge_id", "nda_hash"],
"nda": { "hash_algorithm": "sha256", "require_match": true }
},
"access": {
"method": "portal",
"read_only": true,
"download_enabled": false
},
"match": {
"identifiers": ["badge_id", "nda_hash"]
},
"constraints": {
"time_window": {
"start": "2025-01-15T00:00:00Z",
"end": "2025-02-15T00:00:00Z"
},
"auto_expire": true
}
}
Regulatory examiners authenticate with a badge ID and the SHA-256 hash of their signed NDA. Access is read-only, non-downloadable, and automatically expires when the time window closes — no manual revocation needed.
How match.identifiers Works
The match.identifiers array in a recipe defines the identifiers required for access — it does not require them to be stored on the recipient record at registration time.
At access time, the policy engine resolves identifiers from two sources:
- Stored identifiers — values saved on the recipient record (via the Create Recipient or Update Recipient endpoints)
- Submitted identifiers — values the recipient provides at access time through the portal or API
The engine merges both sources and evaluates the recipe. If all required identifiers are present and valid, access is granted. If any are missing, access is denied.
| Scenario | Stored | Submitted | Result |
|---|
Mortgagee with pre-populated lender_id + policy_number | Both present | — | Access granted |
| Policyholder with no stored identifiers | — | Submits date_of_birth + policy_number | Access granted |
Policyholder with stored phone, submits date_of_birth | phone | date_of_birth, policy_number | Access granted (merged) |
Agent missing agency_code | policy_number only | — | Access denied |
Pre-populating identifiers is not required — the identifiers field on a recipient is optional. What matters is that all identifiers listed in match.identifiers are available (from either source) at the time of access.
Lifecycle
Policies progress through three stages:
DRAFT → PILOT → PRODUCTION
| Stage | Behavior |
|---|
| Draft | Not enforced. Safe to edit and iterate. |
| Pilot | Enforced for a subset of recipients. Use for testing before global rollout. |
| Production | Fully enforced for all matched recipients. |
Version Control
Every change to a policy creates a new immutable version. You can:
- List versions — See the full history of a policy
- Compare versions — Understand what changed between iterations
- Rollback — Revert to any previous version instantly
Version rollback creates a new version with the old recipe — it does not delete intermediate versions. The full history is always preserved for audit purposes.
Simulation
Before publishing a policy change, run a simulation to preview its impact:
- How many recipients gain or lose access
- Which authentication factors are missing per recipient
- Which recipients are non-compliant with the new rules
- Recommendations for transition (e.g., “16 mortgagees lack TLS certificates — consider a grace period”)
Templates
Docyard provides pre-built policy templates for each persona:
| Template | Persona | Key Factors |
|---|
mortgagee-bulk-api | Mortgagee | Passphrase + mTLS, bulk API |
agent-portal-access | Agent | WebAuthn, portal + bulk download |
policyholder-self-service | Policyholder | SMS OTP, single retrieval |
auditor-time-boxed | Auditor | Badge ID + NDA hash, auto-expiring |
Create a policy from a template and customize it for your dock.