Skip to content

TheAccessibleOrgChart β€” Enterprise (working name): Zero-Knowledge Migration Design

Status: Draft for review Author: (fill in) Date: 2026-07-06 Related product: apps/org-chart (TheAccessibleOrgChart, orgchart.theaccessible.org) Audience: Engineering + founders


1. Summary

We want a variant of the org chart product that can be sold into the federal government β€” DoD in particular β€” where the core selling point is that we never see, transit, or retain the customer’s data. The AI vision call moves to Amazon Bedrock in AWS GovCloud with a zero-data-retention (ZDR) posture, and everything else that touches customer PII (org chart image, extracted names/titles/emails/phones, rendered output) moves into the browser or into customer-controlled storage.

The expensive part of this work β€” a zero-knowledge AI path β€” is not org-chart-specific. It is the capability that unlocks all of the TheAccessible suite for DoD/gov. This doc therefore specifies it as a reusable platform capability (@accessible-org/zk-ai) with OrgChart-Enterprise as the first adopter, not as a one-off.

The headline finding from the code review: the Bedrock swap itself is small (a day or two in vision-extractor.ts). The real work is the persistence redesign β€” today the product writes full customer PII into Supabase and R2 in five different places. β€œNo access to their data” is primarily a data-storage problem, and only secondarily an AI-vendor problem.


2. Goals and non-goals

Goals

  • Zero-knowledge posture: in the Enterprise edition, the customer’s org chart image and extracted PII never persist on Anglin AI infrastructure and, ideally, never transit it.
  • Bedrock + ZDR + GovCloud: AI vision inference runs on Bedrock in AWS GovCloud (FedRAMP High / DoD IL-aligned) with no prompt/response retention.
  • Reusable: the zero-knowledge AI path is a shared package the whole suite can adopt.
  • Preserve the product experience: upload β†’ extract β†’ edit β†’ choose template β†’ export accessible HTML, with WCAG 2.1 AA output unchanged.
  • Sellable compliance story: produce artifacts (data-flow attestation, architecture diagram) a federal 508 coordinator / ISSO can put in an ATO package.

Non-goals

  • Not re-architecting the consumer/SaaS edition β€” it keeps its current server-side flow and hosted features.
  • Not pursuing our own FedRAMP authorization in v1 β€” we inherit Bedrock GovCloud’s authorization boundary and keep our own footprint out of the data path.
  • Not building customer-side SSO/CAC integration in v1 (flagged as a fast-follow).

3. Current architecture (where the data actually goes)

The live source is the main API worker, not the stale workers/org-chart-api/dist tree:

  • Routes: workers/api/src/routes/org-chart/*
  • Services: workers/api/src/services/org-chart/*
  • Templates: workers/api/src/templates/*
  • Shared types: @org-chart/shared (packages/org-chart-shared)
  • Frontend: apps/org-chart β€” a static Next.js export (apps/org-chart/out/) that calls the worker via NEXT_PUBLIC_API_URL with a Supabase bearer token.

Current flow (consumer edition)

  1. Upload β€” browser posts the image; worker stores it in R2 as source_image_r2_key and records mime type on org_charts.
  2. Extract (routes/org-chart/extract.ts) — worker fetches the image from R2, base64-encodes it, converts PDF→PNG if needed via the Cloudflare browser binding (storage.browser), then calls extractOrgChart() for both Gemini and Claude in parallel, scores them, and picks the better result.
    • Model calls live in services/org-chart/vision-extractor.ts:
      • extractWithClaude β†’ @anthropic-ai/sdk, model claude-sonnet-4-6.
      • extractWithGemini β†’ @google/genai, model gemini-2.0-flash (or Vertex when USE_VERTEX_AI=true).
    • API keys are injected by middleware/org-chart-storage-cf.ts via extractApiKeys(env) (ANTHROPIC_API_KEY, GEMINI_API_KEY_PDF || GEMINI_API_KEY).
  3. Generate (routes/org-chart/generate.ts) β€” getTemplate(id).render(input) produces HTML; validateWCAG() (pure) plus runAxeAudit(html, storage.browser) (needs the CF headless browser) validate it; output HTML + WCAG report are written to R2 and an org_chart_outputs row.
  4. Finalize (routes/org-chart/finalize.ts) β€” Stripe Checkout, FINALIZE_PRICE_CENTS = 3000 ($30) per chart; webhook sets finalized_at + paid_until (1-year hosting window). Hosted sharing/embeds serve the stored output.

Where customer PII lives today (the problem)

SinkWhat lands thereFile
R2Source image (the raw org chart)extract.ts (source_image_r2_key)
R2Rendered accessible HTML + WCAG reportgenerate.ts
Supabase org_chart_peopleFull PII, one row per person (name, title, email, phone, employee_id, custom_fields)extract.ts
Supabase extraction_quality_metrics.extracted_dataThe entire extracted org as JSON β€” written up to 3Γ— (both models + winner)extract.ts
Supabase org_chart_versions.snapshotFull snapshot of every personextract.ts, versions route
Supabase org_charts.extraction_raw_jsonRaw model outputextract.ts

Conclusion: today we have complete access to every customer’s org data. A Bedrock swap alone does not change that. The Enterprise edition must remove these sinks.

What is already portable (good news)

  • Templates (workers/api/src/templates/*) are pure functions: render(input: TemplateInput): TemplateOutput β€” no fetch, no env, no storage, no Supabase. They can run unchanged in the browser.
  • WCAG validator (services/org-chart/wcag-validator.ts) is a pure function.
  • axe-core actually gets easier client-side: today it needs storage.browser; in the browser it runs against the real DOM for free and the CF browser dependency disappears.
  • Extraction orchestration (dual-model compare/select, Zod schema, parseAndValidate, validateExtraction, calculateQualityMetrics) is pure TS.
  • PDFβ†’image is the only browser-hostile step server-side (storage.browser); replace with pdf.js client-side.

Roughly 70% of the pipeline is already pure code that can be lifted into the client bundle with little change.


4. Target architecture (zero-knowledge)

Core principle: plaintext customer data exists only in the customer’s browser and in the model provider’s ZDR inference boundary. It never lands on Anglin AI infrastructure.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Customer browser (Enterprise edition) β”‚
org chart image ───► β”‚ β”‚
│ 1. pdf.js: PDF→PNG (if needed) │
β”‚ 2. extraction orchestration (pure TS) β”‚
β”‚ 3. template.render() (pure TS) β”‚
β”‚ 4. axe-core + WCAG validate (real DOM) β”‚
β”‚ 5. state in IndexedDB / encrypted exportβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ (only the image) β”‚ (never leaves)
short-lived β”‚ β–Ό
STS creds β”‚ local edit / export /
(Cognito) β”‚ customer-owned bucket
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ AWS GovCloud β”‚
β”‚ Bedrock InvokeModel (Claude) β”‚
β”‚ Zero data retention + guardrail β”‚
β”‚ (FedRAMP High / DoD IL boundary) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Anglin AI infrastructure: issues scoped STS creds + non-PII billing counters ONLY.
Never receives the image or the extracted PII.

4.1 Browser-resident processing

Move steps 1–5 above into the client bundle. The pure code (templates, validators, orchestration, Zod schema, quality metrics) moves into a shared client-safe package so both editions can import it. PDF conversion and axe-core get browser-native implementations.

4.2 Zero-Knowledge AI Gateway (the reusable capability)

Two routing options; the choice defines how strong the claim is.

Option A β€” Browser β†’ Bedrock direct (true zero-access). Recommended.

  • The browser obtains short-lived, tightly scoped STS credentials from an Amazon Cognito Identity Pool, authorized to call only bedrock:InvokeModel on one model ARN in GovCloud.
  • The image goes browser β†’ Bedrock GovCloud and never touches our servers.
  • We cannot see the data even in transit. This is the only architecture that supports an honest β€œwe are technically incapable of accessing your data” statement to an ISSO.
  • Trade-offs: we run a Cognito Identity Pool + IAM scoping; token metering shifts to client-side counters and/or CloudTrail rather than server-side logging.

Option B β€” Thin stateless proxy (fallback).

  • Browser β†’ our Worker β†’ Bedrock, with no logging and no persistence.
  • Simpler auth and metering, reuses existing key management β€” but plaintext transits our infra, so the claim weakens to β€œwe don’t retain it,” not β€œwe can’t see it.” Weaker for a federal buyer; keep as a fallback only.

ZDR specifics: Bedrock does not store prompts/outputs or use them for training by default. In GovCloud we additionally (a) pin to a GovCloud region, (b) attach a Bedrock Guardrail configured for no-logging, and (c) disable model-invocation logging. Document this as the ZDR attestation.

Model mapping (verified July 2026): Vision-capable Claude is available in Bedrock GovCloud at FedRAMP High / DoD IL4/5 β€” this gates the whole project green. Availability, per AWS/Anthropic:

  • Initial GovCloud FedRAMP-High / IL4/5 approval (Jun 2025): Claude 3.5 Sonnet v1 and Claude 3 Haiku.
  • Claude 3.7 Sonnet added to GovCloud (Jul 2025), same authorization.
  • Claude Sonnet 4.5 now live in GovCloud US-West and US-East (default quotas raised to 5M TPM / 1,000 RPM in Feb 2026, matching commercial) β€” this is the current best target.

All of these are multimodal (image input); Anthropic explicitly markets Claude’s vision on β€œcharts, graphs and technical diagrams” β€” i.e. exactly org charts. So the Enterprise target model is Claude Sonnet 4.5 on Bedrock GovCloud, not the claude-sonnet-4-6 we use today on the Anthropic direct API (4.6 is not the GovCloud SKU β€” pin to 4.5 for the gov path and keep 4.6 on the consumer edition).

Bedrock has no Gemini, so the dual-model ensemble becomes either Claude-only or Claude Sonnet 4.5 + Amazon Nova to preserve the compare-and-select logic. Recommend launching Claude-only and adding Nova as the second scorer only if quality regresses.

GovCloud operational notes: (1) exact modelId must be confirmed in-console and will likely be a cross-region inference profile (GovCloud-prefixed) rather than a bare anthropic.claude-... ID; (2) model access in GovCloud is enabled via the associated standard (commercial) AWS account ID linked to the GovCloud account; (3) Guardrails, Agents, Knowledge Bases, and Model Evaluation are all available in GovCloud, so the no-logging ZDR guardrail in Β§4.2 is supported natively.

4.3 Persistence redesign (the real work)

Eliminate every PII sink from Β§3 for the Enterprise edition:

  • No source image in R2 β€” the image stays in the browser; it is sent only to Bedrock.
  • No org_chart_people / extraction_quality_metrics.extracted_data / versions.snapshot / extraction_raw_json β€” chart state lives in IndexedDB in the browser, with an optional encrypted export (customer holds the key) or write-through to a customer-owned bucket (their S3/GovCloud, their account).
  • Billing/usage β€” keep only non-PII counters (chart count, extraction count, timestamps, tenant id). No names, no contents.
  • Quality metrics β€” either drop for Enterprise tenants or reduce to aggregate scores with no extracted_data.

4.4 Reusable platform package

Create @accessible-org/zk-ai exporting: the Cognito/STS credential broker client, a invokeVisionModel() that targets Bedrock GovCloud, the ZDR/guardrail config, and typed request/response wrappers. OrgChart-Enterprise imports it; PDF/Web/Audit/Slides adopt it later with their own prompts. This is what makes the investment pay off across the suite rather than for one narrow product.


5. Migration plan (phased, file-by-file)

Phase 0 β€” Bedrock adapter spike (1–2 days)

  • Add extractWithBedrock(imageBase64, mimeType) to services/org-chart/vision-extractor.ts using @aws-sdk/client-bedrock-runtime InvokeModelCommand. Reuse the existing SYSTEM_PROMPT and parseAndValidate verbatim.
  • Target Claude Sonnet 4.5 in GovCloud US-West/US-East; resolve the exact inference-profile modelId in-console (enable model access via the linked commercial account ID first).
  • Add 'bedrock-claude' to the VisionModel type in @org-chart/shared and to the switch in extractOrgChart().
  • Gate on env (BEDROCK_REGION, BEDROCK_MODEL_ID). Prove parity against a handful of TestFiles/ org charts.
  • Deliverable: drop-in adapter, still server-side, proving Claude Sonnet 4.5 (Bedrock) output quality matches today’s claude-sonnet-4-6 (Anthropic direct).

Phase 1 β€” Client-safe extraction/render/validate package (1–2 weeks)

  • Create packages/org-chart-client (or extend @org-chart/shared) and move, unchanged where possible:
    • templates/* (render, buildTree, color utils) β€” pure.
    • services/org-chart/wcag-validator.ts, extraction-validator.ts, the Zod schema + parseAndValidate + quality metrics from vision-extractor.ts.
  • Replace server-only bits:
    • PDFβ†’PNG: new pdf.js implementation (was pdf-converter.ts + storage.browser).
    • axe-core: run against live DOM in the browser (was axe-validator.ts + storage.browser).
  • Frontend (apps/org-chart) calls these locally instead of hitting /extract and /generate.

Phase 2 β€” Zero-Knowledge AI Gateway (2–3 weeks)

  • Stand up Cognito Identity Pool (GovCloud) + IAM role scoped to bedrock:InvokeModel on the single model ARN.
  • Build @accessible-org/zk-ai: credential broker + invokeVisionModel() (Option A). Browser calls Bedrock directly.
  • Attach Bedrock Guardrail (no-logging) and disable invocation logging; script the ZDR config as IaC (infra/).
  • Keep Option B proxy behind a flag for environments where direct calls are blocked.

Phase 3 β€” Persistence redesign (2–4 weeks, the critical path)

  • New Enterprise data layer: IndexedDB store for chart/people/relationships/versions; encrypted export; optional customer-bucket write-through adapter.
  • Strip all PII writes for Enterprise tenants: remove org_chart_people, extracted_data, snapshot, extraction_raw_json, and R2 image/output storage from the Enterprise path.
  • Reduce Supabase to non-PII billing/usage rows (or a separate minimal schema for Enterprise tenants).

Phase 4 β€” Feature reconciliation (1–2 weeks)

  • Hosted sharing / embeds / paid_until hosting window assume server-stored charts β€” replace with a customer-storage handoff or disable for Enterprise.
  • Billing: rework the $30-at-finalize flow (finalize.ts, FINALIZE_PRICE_CENTS) to a per-tenant/seat or per-chart-count model that reads only non-PII counters. (Federal buyers won’t use consumer Stripe checkout anyway β€” see Β§7.)
  • Admin/analytics dashboards that read PII must be gated off for Enterprise tenants.

Phase 5 β€” Compliance artifacts (1 week)

  • Data-flow diagram + written attestation (β€œdata never persists on vendor infra; inference in Bedrock GovCloud under ZDR”).
  • VPAT/ACR for the Enterprise UI itself (required to sell β€” the tool must be accessible).
  • Draft answers for common ISSO/ATO questions (data residency, encryption in transit, credential lifetime, logging).

6. What breaks / decisions required

  • Gemini is gone (no Bedrock equivalent). Decide: Claude-only vs. Claude + Nova ensemble.
  • Hosted sharing/embeds conflict with zero-knowledge. Decide: drop for Enterprise, or customer-bucket hosting in their account.
  • Editing/versions move to browser state. Decide: IndexedDB-only vs. encrypted export vs. customer bucket as source of truth.
  • Billing model must stop depending on server-side data. Decide the Enterprise pricing unit (seat / tenant / chart volume).
  • Auth: consumer uses Supabase auth. Enterprise likely needs the customer’s IdP (SAML/OIDC, eventually CAC/PIV). Decide v1 scope.

7. Effort estimate

PhaseScopeRough effort
0Bedrock adapter spike1–2 days
1Client-safe render/validate/extract package1–2 weeks
2Zero-knowledge AI gateway (Cognito + Bedrock GovCloud)2–3 weeks
3Persistence redesign (critical path)2–4 weeks
4Feature reconciliation (sharing/billing/admin)1–2 weeks
5Compliance artifacts1 week

Total: ~7–12 weeks of focused engineering for a single developer, dominated by Phase 3. The Bedrock swap people assume is the hard part is the smallest line item. Because @accessible-org/zk-ai is reusable, phases 0/2/5 are amortized across the whole suite.


8. Go-to-market (WOSB) and whether it’s worth it

The honest market read

  • The mandate has teeth. DOJ oversees federal Section 508 compliance; agencies face civil penalties ($75K first / $150K repeat), active litigation (NFB v. SSA, plus DHS and Dept. of Education matters), and GSA publishes an annual governmentwide 508 assessment that keeps the failures visible. Org charts are a textbook 508 failure and DoD produces them at scale β€” often with names, titles, and chain-of-command that are sensitive/CUI, which is exactly why the zero-knowledge posture resonates.
  • WOSB is a real but modest lever. FY24: WOSBs won ~$26.6B (3.44% of federal dollars), below the 5% statutory goal, and most of that came through full-and-open competition, not set-asides. The sole-source lane exists (up to $4.5M for services / $7M manufacturing) and is useful, but relatively few dollars flow through WOSB set-asides specifically. Treat WOSB as friction reduction and a tie-breaker, not a golden ticket.
  • Org-chart-only is too narrow to be the whole business case. Agencies don’t budget for β€œaccessible org charts”; they budget for 508 remediation broadly. Competing accessible chart component libraries (Telerik, AG Charts, amCharts) mean a contractor could DIY. Our moat is specifically legacy-artifact conversion + zero-knowledge data posture + turnkey output.

Verdict

Worth building β€” but framed as a platform capability, not a standalone org-chart product. The zero-knowledge / Bedrock-GovCloud layer is what unlocks all DoD sales for the suite (PDF, Web, Audit, Slides all need the same β€œwe can’t see your data / FedRAMP-aligned” story). Build it once, ship OrgChart-Enterprise as the flagship wedge, and land-and-expand into the higher-budget remediation products. As a standalone whose entire revenue case is federal org-chart sales, the TAM is likely too thin to justify the rebuild; as adopter #1 of a reusable gov-ready capability, the ROI is strong.

Sales motion

  1. Foundational (do regardless): active SAM.gov registration + UEI; NAICS (541511/541512/541519, 513210); WOSB/EDWOSB certification via SBA; capture SDVOSB/8(a)/HUBZone if any also apply.
  2. Credential the product: VPAT/ACR for the Enterprise UI (non-negotiable β€” you can’t sell an accessibility tool that isn’t itself accessible) + the zero-knowledge data-flow attestation.
  3. Land cheap: price a pilot under the $15K micro-purchase threshold so a contracting officer / 508 coordinator can buy directly. WOSB + micro-purchase is the lowest-friction first dollar.
  4. Target the champions: agency Section 508 program managers / coordinators (every agency has one) and DoD component CIO / accessibility offices. Respond to sources-sought/RFIs even with no dollar attached β€” that’s how requirements get written.
  5. Vehicle for scale: pursue GSA MAS (~4–6 months) and, for DoD IT, SEWP / NITAAC; or sell through a reseller already on those vehicles initially.
  6. Consider SBIR/STTR: DoD runs the largest SBIR program in government β€” non-dilutive funding to build/prove exactly this, with a Phase III sole-source path.
  7. Expand: once inside on org charts, sell the broader 508 remediation products where the real budget sits.

9. Open questions / risks

  • Which exact Claude model IDs are available in Bedrock GovCloud, and is vision supported? Resolved (Jul 2026): vision-capable Claude is authorized in GovCloud at FedRAMP High / DoD IL4/5 β€” Claude 3.5 Sonnet v1, Claude 3 Haiku, Claude 3.7 Sonnet, and now Claude Sonnet 4.5 (US-West + US-East). All support image input. Target Sonnet 4.5; confirm the exact inference-profile modelId in-console. Green light for Phase 0.
  • Is direct browserβ†’Bedrock (Option A) acceptable to target agencies’ browser/network policies, or will some require the Option B proxy inside their boundary?
  • Do target agencies require the tool to run inside their own AWS/GovCloud tenancy (fully on-prem-to-them) rather than our Cognito pool? That would push toward a deployable/BYO-cloud packaging.
  • CAC/PIV auth timeline β€” v1 IdP (SAML/OIDC) vs. fast-follow.
  • Encrypted-export key management UX β€” who holds the key, recovery story.

Appendix A β€” Key files touched

  • workers/api/src/services/org-chart/vision-extractor.ts β€” add Bedrock adapter; source of the model calls and system prompt.
  • workers/api/src/routes/org-chart/extract.ts β€” the orchestration + all PII writes to remove for Enterprise.
  • workers/api/src/routes/org-chart/generate.ts β€” template render + WCAG/axe + R2/org_chart_outputs writes.
  • workers/api/src/routes/org-chart/finalize.ts β€” $30 Stripe flow to rework.
  • workers/api/src/templates/* β€” pure renderers to lift into the client bundle.
  • workers/api/src/services/org-chart/{wcag-validator,extraction-validator,pdf-converter,axe-validator}.ts β€” port/replace for browser.
  • packages/org-chart-shared β€” VisionModel type + shared schema.
  • apps/org-chart β€” static frontend that hosts the new client-side pipeline.
  • New: packages/org-chart-client, @accessible-org/zk-ai, infra/ GovCloud + Cognito IaC.