Skip to content
AskFlorence
Main Navigation ArchitectureFlorence AIAgentsMembersAgent PlatformValidationInfrastructure

Appearance

Sidebar Navigation

Overview

Home

Glossary

System Architecture

Consumer & Agent Flow

Florence AI

Overview

Principles

Runtime

Tool surface

Adding a tool

Tool registry

Knowledge: SBC scenarios & CSR

Voice

Evals & observability

Provider risk & portability

Outage playbook

Roadmap

Build plan

Agents

Overview

Workflows & pain points

Members

Overview

Medicaid coverage gap

Carriers

Overview

Marketplaces

Overview

Agency

Overview

Regulations

Overview

Agent Platform

Overview

Auth Architecture

MongoDB Permissioning

Compliance Model

Data Models

Data Sources

Overview

CMS Marketplace API

CMS dependency map

PUF Data

State Subsidies

SBE Ingestion Playbook

SBE State Watchouts + Decisions

CA Phase C/D Playbook

NY Phase C/D Playbook

Validation

Overview

Methodology

APTC Formula

California 2026

New York 2026

CAPS Formula

Scenario Results

Infrastructure

Account Inventory

AWS Setup Runbook

AWS Organizations

CloudTrail

GuardDuty

Security Hub

Config

CloudFront + WAFv2

Data sources & ingest

Phase 4 DNS

Change Log

Vulnerability Management

MongoDB Setup

Access Control

Data Classification

Documentation Hosting

Post-deploy Smoke

Development

Preflight (local CI mirror)

Testing strategy

Compliance

Overview (auditor entry point)

SOC 2 Control Mapping

HIPAA Control Mapping

CMS EDE Appendix A Mapping

Risk Assessment

Encryption Policy

Data Retention Policy

Privacy Impact Assessment

Consent Capture & Versioning

Incident Response Plan

Access Control Policy

Marketing vs. Portal Analytics

Vendor / Subprocessor Register

Dependency Vulnerability Policy

BAA / Compliance Evidence

Compliance-Automation Integration

Compliance-Automation Vendor Evaluation

Penetration Test Reports

Architecture

Portal entry handoff

Mobile app strategy

Deferred architecture decisions

Session cookie architecture

Share flows

Decisions (ADRs)

Index

0001 — Atlas project isolation

0002 — Append-only audit log

0003 — Narrow-scoped Mongo users

0004 — Cross-cluster Atlas PrivateLink

0005 — Delayed-job architecture

0006 — Mongo user simplification

0007 — Terraform owns ECS task def

0008 — E2E testing strategy

0009 — Self-hosted analytics + observability (superseded)

0010 — PostHog HIPAA Cloud (supersedes 0009)

Runbooks

Security Incident Response

Break-Glass Root Login

Onboard Team Member

Offboard Team Member

Atlas user provisioning

Deploy via Terraform (ENG-277)

Rollback via Terraform (ENG-277)

S3 data bucket migration (planned Phase 11)

Access Reviews

2026-Q2 Review

Session log

Index

2026-04-23 — Phase 10 DNS cutover

2026-04-22 — Phase 8 prod AWS mirror

2026-04-22 — Phase 7 Atlas VPC peering

2026-04-22 — Phase 6 CloudFront + WAF

2026-04-21 — Phase 5 staging go-live

2026-04-17 — Atlas staging

Briefs

Index

Member portal plan (ENG-187)

2026-04-16/17 handoff

2026-04-17 Atlas handoff

System briefing (2026-04-17)

Creative AdBundance proposal brief

Creative AdBundance analytics brief

ElevenLabs RN integration research

Policies

Overview

On this page

Atlas Access Matrix ​

Generated from infra/atlas/access-matrix.ts by npm run docs:atlas. Do not edit by hand.

Canonical source of truth for every MongoDB Atlas user, role, env-var binding, and code consumer across the AskFlorence stack. Read this file first before adding or modifying any Mongo user — it tells you what already exists and which code paths break if you narrow privileges.

Summary ​

  • Total users: 19
  • Active: 19
  • Legacy / pending deletion: 0
  • Staging cluster users: 13
  • Prod cluster users: 6

How this stays accurate ​

Three CI guards keep this doc + the manifest + Terraform + the live Atlas state in sync. Live ECS task defs are now in sync with Terraform source by construction — Terraform owns the task definition resource end-to-end as of ENG-277 (2026-05-13). See ADR 0007.

  1. atlas-env-var-coverage (PR-time, static) — every env-var declared in the manifest must be wired in the corresponding Terraform infra/envs/<env>/ *.tf files. Catches the ENG-272 class of bug (manifest says "this env needs this var" but Terraform doesn't wire it).
  2. staging-cluster-drift (nightly, live Atlas) — every active user with nightlyDriftCheck=true is verified against the live Atlas API. Catches the ENG-239 class of bug (someone widens a role via Atlas UI by hand).
  3. atlas-docs-sync (PR-time, static) — re-runs npm run docs:atlas and git diffs the result. If the committed doc is stale, the PR fails. Catches the ENG-272 class of doc-rot (manifest changes but the human-readable view doesn't).

Workflow when adding a new user or modifying an existing one: see the file header in infra/atlas/access-matrix.ts.

Why this matrix exists ​

Three earlier issues (ENG-239, ENG-249/PR91, ENG-271) each added or narrowed a Mongo user without a single place to verify the change against the FULL set of code paths that depend on it. ENG-272 surfaced the resulting silent regression: ENG-271's narrowing of staging's MONGODB_URI from app_read_staging → app_read_local_staging lost FIND on providers_staging + formularies_staging, and getReferenceDb() silently fell back to the wrong user. The break shipped to apex (the YC-application surface) and was only caught when the founder typed a real doctor name and saw "not covered" incorrectly.

This matrix prevents that class of failure by making the FULL access surface visible in one file, with CI-enforced consistency between four layers (manifest, Terraform, Atlas API, doc).

Compliance / audit relevance ​

  • SOC 2 CC6.1 — least privilege per user, demonstrable via this file
  • SOC 2 CC6.6 — segmentation enforced (no inheritedRoles, no cross-collection grants beyond the privilege list here)
  • HIPAA § 164.312(a)(1) — access control narrow + auditable
  • EDE Phase 3 — auditor lookback can grep this file's git history to reconstruct who had access to what at any point in time

Staging cluster ​

app_read_local_staging ​

fieldvalue
Clusterstaging
Custom rolerole_reader_local_staging
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: plans, zip_county, regions, plan_years, audit_log, agent_waitlist_submissions

Env-var bindings:

  • staging → MONGODB_URI

Consumers:

  • src/lib/db.ts:getDb() (staging deploy)
  • src/app/api/eligibility/route.ts
  • src/app/api/plans/route.ts
  • src/app/api/counties/route.ts
  • src/app/api/agents/discovery/route.ts (back-link dedup)

Rationale: ENG-271 — separated deployment-local reads from cross-cluster reference reads after ENG-239 narrowing of app_read_staging broke the staging consumer flow. Companion to app_read_staging.


app_read_staging ​

fieldvalue
Clusterstaging
Custom rolerole_reader_reference
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: formularies_staging, providers_staging, drug_search_index, plans, mrpuf_issuers_staging

Env-var bindings:

  • staging → MONGODB_REFERENCE_URI
  • prod → MONGODB_REFERENCE_URI
  • local → MONGODB_URI

Consumers:

  • src/lib/db.ts:getReferenceDb()
  • src/lib/provider-network-fallback.ts:lookupStagingProviderNetworks()
  • src/lib/drug-tier-fallback.ts:lookupStagingDrugTiers()
  • src/app/api/providers/covered/route.ts (network_tier enrichment)
  • src/app/api/drugs/covered/route.ts (drug_tier enrichment)

Rationale: ADR 0004 + Phase 11 — cross-cluster PrivateLink reads from prod into staging cluster's §1311 MRF dataset. ENG-272 added the missing staging env-var binding so staging doesn't 500 on the same code path that works on prod.


app_writer_survey ​

fieldvalue
Clusterstaging
Custom rolerole_writer_survey
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_survey_responses
  • INSERT on askflorence: agent_survey_responses
  • UPDATE on askflorence: agent_survey_responses
  • CREATE_INDEX on askflorence: agent_survey_responses
  • LIST_INDEXES on askflorence: agent_survey_responses

Env-var bindings:

  • staging → MONGODB_URI_SURVEY_WRITE
  • local → MONGODB_URI_SURVEY_WRITE

Consumers:

  • src/app/api/agents/discovery/route.ts (survey insert + partial-save)
  • scripts/agent-discovery-cron-reminder.ts (read partials)

Rationale: Issue #56 / Phase 2 — narrow writer for /agent-discovery survey. CLAUDE.md compliance: never share user with waitlist/agents writers.


app_writer_plans ​

fieldvalue
Clusterstaging
Custom rolerole_writer_plans
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: plans, zip_county, regions, plan_years, audit_log
  • INSERT on askflorence: plans, zip_county, regions, plan_years, audit_log
  • UPDATE on askflorence: plans, zip_county, regions, plan_years, audit_log
  • REMOVE on askflorence: plans, zip_county, regions, plan_years
  • CREATE_INDEX on askflorence: plans, zip_county, regions, plan_years, audit_log

Env-var bindings:

  • staging → MONGODB_URI_PLANS_WRITE
  • local → MONGODB_URI_PLANS_WRITE

Consumers:

  • scripts/db/ingest-puf-augment.js
  • scripts/db/ingest-qrs-ratings.js
  • scripts/db/* (other ingest scripts)

Rationale: Issue #56 — narrow writer for ingest scripts. Replaces app-write usage in scripts/db/*.


app_writer_waitlist ​

fieldvalue
Clusterstaging
Custom rolerole_writer_waitlist
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_waitlist_submissions
  • INSERT on askflorence: agent_waitlist_submissions
  • UPDATE on askflorence: agent_waitlist_submissions
  • CREATE_INDEX on askflorence: agent_waitlist_submissions
  • LIST_INDEXES on askflorence: agent_waitlist_submissions

Env-var bindings:

  • staging → MONGODB_URI_WAITLIST_WRITE
  • local → MONGODB_URI_WAITLIST_WRITE

Consumers:

  • src/app/api/waitlist/route.ts (consumer + agent waitlist writes)

Rationale: Issue #56 commit 07fd8aa — narrow writer for /api/waitlist. Used by both consumer and agent flows.


app_writer_hubspot_sync ​

fieldvalue
Clusterstaging
Custom rolerole_writer_hubspot_sync
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • INSERT on askflorence: hubspot_sync_log
  • UPDATE on askflorence: hubspot_sync_log
  • CREATE_INDEX on askflorence: hubspot_sync_log

Env-var bindings:

  • staging → MONGODB_URI_HUBSPOT_SYNC_WRITE
  • local → MONGODB_URI_HUBSPOT_SYNC_WRITE

Consumers:

  • src/lib/hubspot/sync.ts:getHubSpotSyncWriteClient()
  • scripts/hubspot/backfill.ts (with --apply)

Rationale: PR91 — distinct from app_writer_waitlist because main's earlier ENG-249 attempt re-used waitlist user and ran into perm-denied on hubspot_sync_log writes (commit b77a1ba degrade-gracefully fix).


app_writer_agents ​

fieldvalue
Clusterstaging
Custom rolerole_writer_agents
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agents, agencies, agent_sessions, agent_audit_log
  • INSERT on askflorence: agents, agencies, agent_sessions, agent_audit_log
  • UPDATE on askflorence: agents, agencies, agent_sessions
  • REMOVE on askflorence: agent_sessions
  • CREATE_INDEX on askflorence: agents, agencies, agent_sessions

Env-var bindings:

  • staging → MONGODB_URI_AGENTS_WRITE
  • local → MONGODB_URI_AGENTS_WRITE

Consumers:

  • src/app/api/agents/* (Phase 5 portal, not yet in use)

Rationale: Issue #56 / Phase 5 — narrow writer for agent portal. Append-only on agent_audit_log per ADR 0002.


app_admin_agents ​

fieldvalue
Clusterstaging
Custom rolerole_admin_agents
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agents, agencies, agent_sessions, agent_audit_log, admins
  • INSERT on askflorence: agents, agencies, agent_sessions, agent_audit_log
  • UPDATE on askflorence: agents, agencies, agent_sessions, admins
  • REMOVE on askflorence: agent_sessions
  • CREATE_INDEX on askflorence: agents, agencies, agent_sessions, admins

Env-var bindings:

  • staging → MONGODB_URI_AGENTS_ADMIN
  • local → MONGODB_URI_AGENTS_ADMIN

Consumers:

  • src/app/admin/* (Phase 5, not yet in use)

Rationale: Issue #56 / Phase 5 — admin dashboard writer. Append-only on agent_audit_log preserved (no UPDATE/REMOVE).


app_admin_schema ​

fieldvalue
Clusterstaging
Custom rolerole_admin_schema
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • CREATE_INDEX on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • LIST_INDEXES on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • DROP_INDEX on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log

Env-var bindings:

  • staging → MONGODB_URI_ADMIN_SCHEMA

Consumers:

  • scripts/db/ensure-indexes.ts (run via in-VPC ECS RunTask in deploy workflow)

Rationale: ENG-266 Phase 3.5 — separate admin user for deploy-time index ensure. Removed from request-time route handlers; runs in a one-shot Fargate task before the ECS service swap.


audit_reader ​

fieldvalue
Clusterstaging
Custom rolerole_audit_reader
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_audit_log

Env-var bindings:

  • staging → MONGODB_URI_AUDIT_READ
  • local → MONGODB_URI_AUDIT_READ

Consumers:

  • ad-hoc compliance queries (no production code path yet — Phase 5)

Rationale: Issue #56 — read-only auditor. Sole user with FIND on agent_audit_log without any write privilege.


app_read ​

fieldvalue
Clusterstaging
Custom role(built-in)
Status🟢 active
Nightly drift check✅ yes

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • staging → MONGODB_URI
  • local → MONGODB_URI

Consumers:

  • src/lib/db.ts:getDb() (staging deploy + local dev primary)
  • src/lib/db.ts:getReferenceDb() (staging deploy local + cross-cluster source for prod via PrivateLink)
  • src/app/api/eligibility/route.ts
  • src/app/api/plans/route.ts
  • src/app/api/counties/route.ts
  • src/app/api/providers/covered/route.ts (network_tier enrichment via cross-cluster path)
  • src/app/api/drugs/covered/route.ts (drug_tier enrichment via cross-cluster path)
  • src/app/api/agents/discovery/route.ts (back-link dedup)

Rationale: ENG-279 / ADR 0006 — consolidated reader. Replaces app_read_local_staging + app_read_staging. Built-in read on askflorence DB covers every collection the app reads (no per-collection role enumeration). Cross-cluster reads (prod -> staging) go through this same user via the staging-cluster PrivateLink endpoint.


app_write ​

fieldvalue
Clusterstaging
Custom role(built-in)
Status🟢 active
Nightly drift check✅ yes

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • staging → MONGODB_WRITE_URI
  • local → MONGODB_WRITE_URI

Consumers:

  • src/lib/agent-db.ts:getSurveyWriteClient()
  • src/lib/agent-db.ts:getWaitlistWriteClient()
  • src/lib/agent-db.ts:getHubSpotSyncWriteClient()
  • scripts/db/* (ingest + maintenance scripts)
  • scripts/hubspot/backfill.ts (with --apply)
  • ENG-236 LARK delta-aware MRF refresh pipeline (writes mrf_file_state_staging, formularies_staging, providers_staging)

Rationale: ENG-279 / ADR 0006 — consolidated writer. Replaces app_writer_survey, app_writer_plans, app_writer_waitlist, app_writer_hubspot_sync, app_writer_agents, app_admin_agents. Built-in readWrite on askflorence DB covers every collection the app writes plus future collections (e.g., mrf_file_state_staging) without role updates. Phase 5 per-tenant isolation shifts to MongoDB views + JWT-in-middleware rather than per-tenant DB users (see ADR 0006).


app_audit_writer ​

fieldvalue
Clusterstaging
Custom rolerole_audit_writer
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_audit_log
  • INSERT on askflorence: agent_audit_log

Env-var bindings:

  • staging → MONGODB_AUDIT_WRITE_URI
  • local → MONGODB_AUDIT_WRITE_URI

Consumers:

  • src/lib/db.ts:getAuditDb() (Phase 5 audit-log writers; no consumer Phase 1-4)

Rationale: ENG-279 / ADR 0006 — consolidated append-only audit writer. Preserves ADR 0002 verbatim (FIND + INSERT on agent_audit_log only; UPDATE/REMOVE denied at the DB permission layer). Replaces the dual append-only-on-audit_log grant previously embedded in role_writer_agents + role_admin_agents.


Prod cluster ​

app-read ​

fieldvalue
Clusterprod
Custom role(built-in)
Status🟢 active
Nightly drift check❌ no

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • prod → MONGODB_URI
  • local → MONGODB_URI

Consumers:

  • src/lib/db.ts:getDb()
  • src/lib/agent-db.ts (read paths)
  • src/app/api/eligibility/route.ts (zip lookup → CMS proxy)
  • src/app/api/plans/route.ts (plan filter / search)

Rationale: Phase 8 prod rollout deferred narrow users to a follow-up. Issue #56 prod session adds app_read_prod + writers; app-read deleted in lockstep.


app-write ​

fieldvalue
Clusterprod
Custom role(built-in)
Status🟢 active
Nightly drift check❌ no

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • prod → MONGODB_WRITE_URI
  • local → MONGODB_WRITE_URI

Consumers:

  • src/lib/agent-db.ts (write paths until narrowed)
  • scripts/db/* ingest scripts

Rationale: Dev-convenience writer. CLAUDE.md hard rule: deletion is exit criterion on Issue #56 before prod GA.


app_admin_schema ​

fieldvalue
Clusterprod
Custom rolerole_admin_schema
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • CREATE_INDEX on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • LIST_INDEXES on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log
  • DROP_INDEX on askflorence: agent_waitlist_submissions, agent_survey_responses, hubspot_sync_log

Env-var bindings:

  • prod → MONGODB_URI_ADMIN_SCHEMA

Consumers:

  • scripts/db/ensure-indexes.ts (run via in-VPC ECS RunTask in deploy workflow)

Rationale: ENG-266 Phase 3.5 prod mirror — separate admin user for deploy-time index ensure on the prod cluster. Identical pattern to staging's app_admin_schema (entry above).


app_read ​

fieldvalue
Clusterprod
Custom role(built-in)
Status🟢 active
Nightly drift check✅ yes

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • prod → MONGODB_URI

Consumers:

  • src/lib/db.ts:getDb() (prod deploy)
  • src/app/api/eligibility/route.ts
  • src/app/api/plans/route.ts
  • src/app/api/counties/route.ts
  • src/app/api/agents/discovery/route.ts (back-link dedup)

Rationale: ENG-279 / ADR 0006 — consolidated prod reader. Replaces app-read (hyphenated, built-in read) — same role shape, new snake_case name aligned with staging. Issue #56 prod deletion criterion satisfied at Phase G.


app_write ​

fieldvalue
Clusterprod
Custom role(built-in)
Status🟢 active
Nightly drift check✅ yes

Privileges:

Built-in role — privileges not enumerated here.

Env-var bindings:

  • prod → MONGODB_WRITE_URI

Consumers:

  • src/lib/agent-db.ts:getSurveyWriteClient()
  • src/lib/agent-db.ts:getWaitlistWriteClient()
  • src/lib/agent-db.ts:getHubSpotSyncWriteClient()
  • scripts/db/* when run against prod cluster

Rationale: ENG-279 / ADR 0006 — consolidated prod writer. Replaces app-write (hyphenated, built-in readWrite). CLAUDE.md exit criterion: app-write deletion before production launch is satisfied at Phase G.


app_audit_writer ​

fieldvalue
Clusterprod
Custom rolerole_audit_writer
Status🟢 active
Nightly drift check✅ yes

Privileges:

  • FIND on askflorence: agent_audit_log
  • INSERT on askflorence: agent_audit_log

Env-var bindings:

  • prod → MONGODB_AUDIT_WRITE_URI

Consumers:

  • src/lib/db.ts:getAuditDb() (Phase 5 audit-log writers)

Rationale: ENG-279 / ADR 0006 — consolidated append-only audit writer on prod cluster. Mirror of staging app_audit_writer. ADR 0002 append-only property preserved.


Pager
Next pageHome

AskFlorence Internal Documentation. Not for public distribution.

AskFlorence

Internal Documentation

Access restricted. Not for public distribution.