Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Executive summary
The highest-risk themes are public edge endpoints that intentionally run withverify_jwt = false, service-role operations that can bypass RLS if org scoping is missed, and third-party webhook trust boundaries that rely on correct signature verification and replay protection. The largest impact areas are cross-tenant data exposure, PHI disclosure through integrations or AI tooling, and integrity compromise of payroll/background-check/telephony workflows. Critical CI controls exist, but supply-chain hardening (for actions and dependency provenance) remains an important residual risk.
Scope and assumptions
- In scope paths:
src/runtime app and auth/session handlingsupabase/functions/edge runtime (HTTP functions + shared auth/cors/supabase helpers)supabase/config.tomlplatform auth and edge JWT-mode settings.github/workflows/build.ymlcritical CI gate controlsvercel.jsondeployment headers and browser hardening
- Out of scope:
- Detailed per-integration protocol audits for every one of the 200+ edge functions
- Non-critical local tooling behavior (
dist/,node_modules/, test fixtures) - Infrastructure outside repo (cloud firewall, WAF, secret manager policies)
- Assumptions:
- Deployment is internet-exposed production SaaS with PHI and strict tenant isolation requirements.
- Supabase service-role keys are restricted to server-side functions and never exposed to clients.
- RLS is the primary tenant isolation boundary for authenticated data access.
- Third-party integrations (RingCentral, Twilio, Checkr, Plaid, Ramp, Gusto, OpenRouter) are reachable from edge functions.
- Open questions that could materially change ranking:
- Is there centralized API gateway/WAF rate limiting in front of Supabase edge endpoints?
- Are webhook replay windows and nonce caches enforced consistently per provider?
- Are CI workflows protected by branch protection + required approvals for workflow file changes?
System model
Primary components
- Browser SPA (
React+react-router) with Supabase session usage and lazy-loaded modules (src/App.tsx). - Client auth/session abstraction via
useCurrentUserand Supabase JS client (src/platform/auth/useCurrentUser.ts,src/integrations/supabase/client.ts). - Supabase Auth + Postgres (RLS + SECURITY DEFINER helper pattern) for tenant isolation (
supabase/migrations/20260211182655_6aeefd1c-c5cc-4eaf-98b0-3e38abc7ba6a.sql,tests/rls/pf-profiles.rls.test.ts). - Supabase Edge Functions for business and integration workflows (
supabase/functions/*,supabase/config.toml). - Third-party integrations: telephony/SMS, payroll, financial aggregation, background checks, AI providers (
supabase/functions/ringcentral-webhook/index.ts,supabase/functions/sms-webhook/index.ts,supabase/functions/gusto-proxy/index.ts,supabase/functions/plaid-webhook/index.ts,supabase/functions/checkr-webhook/index.ts,supabase/functions/ai-skill-execute/index.ts). - CI gate in GitHub Actions before build/test artifact acceptance (
.github/workflows/build.yml).
Data flows and trust boundaries
- Internet user browser -> SPA runtime (
src/App.tsx)- Data: credentials, access tokens, org/site context, UI inputs.
- Channel: HTTPS browser requests.
- Security guarantees: route-level auth session checks, React Query caching, error boundary.
- Validation/enforcement: session lookup and auth state listener (
supabase.auth.getSession,supabase.auth.onAuthStateChange).
- SPA runtime -> Supabase Auth/PostgREST (
src/integrations/supabase/client.ts,src/platform/auth/useCurrentUser.ts)- Data: JWT bearer token, row-scoped queries, profile/org lookups.
- Channel: HTTPS via Supabase JS.
- Security guarantees: JWT auth, RLS-backed data filtering.
- Validation/enforcement:
supabase.auth.getUser()and RLS policies.
- Internet/webhook providers -> Edge Functions with
verify_jwt = false(supabase/config.toml)- Data: webhook payloads, provider signatures/JWTs, event metadata.
- Channel: HTTPS POST webhooks.
- Security guarantees: function-local signature checks (provider specific) and CORS handling.
- Validation/enforcement: HMAC/JWT verification in webhook handlers (
verifySignature,verifyWebhookSignature,validateTwilioSignature,verifyPlaidWebhook,computeCheckrSignature).
- Edge Functions -> Postgres with service role (
supabase/functions/_shared/supabase.ts)- Data: PHI/PII metadata, payroll/banking references, audit events, role assignments.
- Channel: internal Supabase client over TLS.
- Security guarantees: elevated service credentials plus explicit org filtering.
- Validation/enforcement: manual
.eq('organization_id', ...)and role checks (verifyOrgAccess,verifyOrgRole).
- Edge Functions -> External APIs (Checkr/Gusto/Plaid/Ramp/RingCentral/OpenRouter)
- Data: integration tokens, webhook event payloads, AI prompts/messages.
- Channel: HTTPS API calls.
- Security guarantees: provider auth headers, optional encryption at rest for stored tokens.
- Validation/enforcement: per-provider request signing and error sanitization patterns.
- GitHub -> CI workflow (
.github/workflows/build.yml)- Data: source code, dependency graph, test/build outputs.
- Channel: GitHub-hosted runner execution.
- Security guarantees: validation steps and smoke gates.
- Validation/enforcement: format/type/lint/test/RLS coverage/build checks.
Diagram
Assets and security objectives
| Asset | Why it matters | Security objective (C/I/A) |
|---|---|---|
| Patient and member PHI in CL/PM tables | Regulatory harm (HIPAA/42 CFR Part 2), legal and reputational impact | C: High, I: High, A: Medium |
Multi-tenant boundaries (organization_id, role assignments) | Cross-tenant breach is a platform-level failure mode | C: High, I: High |
| Service-role credentials and integration API secrets | Compromise enables privileged data access and workflow tampering | C: High, I: High |
| Payroll/banking/background-check workflow state | Financial and compliance-critical integrity of HR/FA operations | I: High, A: High |
| Telephony/SMS communication records and consent state | Privacy, legal compliance (TCPA), and operational integrity | C: High, I: High |
| AI skill prompts/messages and tool outputs | Possible PHI leakage and policy bypass risk | C: High, I: Medium |
| CI pipeline and build artifacts | Supply-chain compromise can ship malicious code to production | I: High, A: Medium |
Audit and usage logs (pf_audit_logs, pf_ai_usage_logs) | Forensics, detection, and compliance evidence | I: High, A: Medium |
Attacker model
Capabilities
- Remote internet attacker can send arbitrary requests to public endpoints and webhook paths.
- Attacker can replay captured webhook payload/signature pairs if anti-replay controls are weak.
- Authenticated low-privilege tenant user can attempt privilege escalation and cross-tenant data access.
- Third-party integration compromise can send validly signed but maliciously crafted events.
- Dependency or CI adversary can attempt supply-chain tampering via build pipeline inputs.
Non-capabilities
- Attacker does not have assumed direct shell access to Supabase or Vercel runtime hosts.
- Attacker does not start with possession of Supabase service-role keys by default.
- Attacker cannot bypass strong cryptographic signature verification when keys remain secret and implementation is correct.
Entry points and attack surfaces
| Surface | How reached | Trust boundary | Notes | Evidence (repo path / symbol) |
|---|---|---|---|---|
| SPA auth/session bootstrap | Browser load and route navigation | Internet -> Browser SPA | Session restore and auth state drive gated routes | src/App.tsx (supabase.auth.getSession, route guard) |
| Current-user resolution | Authenticated browser calls | Browser -> Supabase Auth | Uses getUser() and query cache for identity state | src/platform/auth/useCurrentUser.ts (useCurrentUser) |
Public edge endpoints (verify_jwt = false) | Direct HTTPS request | Internet -> Edge Functions | Many functions intentionally public and rely on local checks | supabase/config.toml ([functions.*] verify_jwt = false) |
| Shared edge auth helper | Internal function call path | Edge request -> auth helper | Accepts Bearer JWT; special service-role token shortcut | supabase/functions/_shared/auth.ts (validateAuth) |
| CORS policy helper | All edge HTTP responses | Browser/Webhook -> Edge Functions | Dynamic allowlist + default origins + dev reflection fallback | supabase/functions/_shared/cors.ts (getCorsHeaders) |
| RingCentral webhook | Provider callback | RingCentral -> Edge Functions | HMAC-SHA1 signature verification and subscription checks | supabase/functions/ringcentral-webhook/index.ts (verifyWebhookSignature, verifySubscription) |
| SMS webhook (Twilio/RingCentral) | Provider callback | SMS provider -> Edge Functions | Twilio signature validation, opt-out handling, inbound writes | supabase/functions/sms-webhook/index.ts (validateTwilioSignature, handleInboundMessage) |
| Checkr webhook/session token | Provider callback + client-initiated token creation | Checkr/client -> Edge Functions | HMAC verification and org-linked credential retrieval | supabase/functions/checkr-webhook/index.ts, supabase/functions/checkr-session-token/index.ts |
| Plaid/Ramp webhooks | Provider callback | Plaid/Ramp -> Edge Functions | Signature/JWT checks then service-role DB mutation | supabase/functions/plaid-webhook/index.ts, supabase/functions/ramp-webhook/index.ts |
| AI skill execution | Client POST | Browser -> Edge Functions -> AI providers | Auth + org resolution + tool calls + OpenRouter fallback | supabase/functions/ai-skill-execute/index.ts (validateAuth, runAgenticLoop, callOpenRouterFallback) |
| Gusto proxy | Client POST to proxy | Browser -> Edge Functions -> Gusto | Token decryption/encryption and proxy header handling | supabase/functions/gusto-proxy/index.ts (decryptToken, refreshGustoTokens, getClientIp) |
| CI build workflow | Push/PR event | GitHub -> CI runner | Validation and smoke checks before build artifacts | .github/workflows/build.yml |
Top abuse paths
-
TM-001 Cross-tenant read/write via public edge path
- Attacker discovers a
verify_jwt = falsefunction lacking complete authz checks. - Sends crafted request with attacker-controlled organization identifiers.
- Function executes with service role and missing org filter on one mutation/query.
- Data from another tenant is read or modified.
- Attacker discovers a
-
TM-002 Webhook spoofing or replay for privileged workflow mutation
- Attacker replays previously valid webhook payload/signature pair.
- Endpoint accepts signature but lacks nonce/timestamp replay defense.
- Duplicate or stale financial/telephony/background-check state transition is applied.
- Integrity and downstream reporting are corrupted.
-
TM-003 Service-role token misuse in edge auth helper
- Service-role key is exposed through misconfiguration/logging/ops leak.
- Attacker sends it as Bearer token to
validateAuth-using endpoints. - Handler treats requester as internal
service-roleprincipal. - Org checks are bypassed where not independently enforced.
-
TM-004 AI exfiltration of sensitive data through tooling/fallback provider
- Authenticated user submits prompts containing PHI or data extraction requests.
- Skill executes with tool calls and optional provider fallback.
- Sensitive content may transit external provider or tool outputs beyond intended minimum scope.
- PHI handling and confidentiality boundaries are weakened.
-
TM-005 Credential misuse or weak proxy trust assumptions in payroll integration
- Attacker abuses endpoint with spoofed proxy headers or compromised account.
- Proxy path forwards actions with stored OAuth tokens.
- Unauthorized payroll API actions or data access occurs.
- Financial integrity and confidentiality are impacted.
-
TM-006 SMS/telephony ingestion manipulation and consent-state abuse
- Attacker submits forged/ambiguous inbound SMS payloads or provider-like callbacks.
- Contact matching and status updates mutate communication records.
- Consent and message status become inaccurate.
- Compliance and patient communication integrity are impacted.
-
TM-007 CI supply-chain compromise
- Malicious dependency update or compromised action behavior enters PR path.
- CI executes build/tests with attacker-controlled package code.
- Artifact or lockfile integrity is subverted and malicious code reaches deploy path.
- Broad confidentiality/integrity impact across all tenants.
-
TM-008 Resource exhaustion against public edge endpoints
- Botnet floods webhook/public function endpoints.
- Signature verification and downstream DB/API calls consume compute budget.
- Legitimate requests are delayed or dropped.
- Availability and SLA degrade across modules.
Threat model table
| Threat ID | Threat source | Prerequisites | Threat action | Impact | Impacted assets | Existing controls (evidence) | Gaps | Recommended mitigations | Detection ideas | Likelihood | Impact severity | Priority |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| TM-001 | External attacker or low-privilege authenticated user | At least one public function or manual-auth path misses complete org/role enforcement. Service-role DB client is reachable in handler logic. | Invoke edge function path to read/mutate data for another tenant using crafted org IDs. | Cross-tenant confidentiality and integrity breach; potential PHI disclosure. | PHI/PII, tenant boundary state, audit trust. | RLS baseline + org checks exist (verifyOrgAccess, verifyOrgRole) and many handlers explicitly filter by organization_id (supabase/functions/_shared/auth.ts, supabase/functions/telehealth-create-session/index.ts). | verify_jwt = false is broad in config, and control correctness is distributed per function. Manual consistency risk is high. | Add centralized middleware enforcing org context + role checks for all non-webhook verify_jwt=false functions; add static policy audit that blocks deploy when required checks are absent. | Alert on denied-org access spikes and anomalous cross-org lookup attempts; log normalized caller org + requested org for all privileged handlers. | Medium | High | high |
| TM-002 | External attacker, replay attacker, or compromised webhook sender | Access to valid payload/signature pair or weak replay window controls. | Replay or forge webhook events to trigger duplicate or stale state transitions. | Financial/telephony/background-check workflow corruption and potential unauthorized processing. | Financial records, call/message records, HR screening states, audit logs. | Signature validation is implemented in multiple handlers (verifyWebhookSignature, computeCheckrSignature, verifySignature, verifyPlaidWebhook, validateTwilioSignature) with timing-safe comparisons in key paths. | Replay resistance is not uniformly explicit (nonce/timestamp cache not consistently evident across all webhook handlers). | Enforce per-provider replay controls (timestamp tolerance + event-id dedupe store + idempotency TTL) as shared library used by all webhook handlers. | Monitor duplicate provider event IDs and signature-fail rates by endpoint; alert on unusual re-delivery bursts. | Medium | High | high |
| TM-003 | External attacker with leaked secret | Service-role key compromise via environment leak, logging, or operational mistake. | Use service-role key as Bearer token where validateAuth allows internal service shortcut. | Broad authorization bypass at edge layer where additional checks are absent; high blast radius. | Service credentials, tenant boundaries, PHI/PII. | validateAuth verifies JWT and supports service-role internal mode; many handlers still perform explicit org lookups (supabase/functions/_shared/auth.ts, supabase/functions/ai-skill-execute/index.ts). | Service-role shortcut expands blast radius if key leaks; key use is binary and powerful. | Remove Bearer service-role shortcut for internet-facing routes; require mTLS/internal network assertion or dedicated signed internal token with narrow claims. | Alert on any request authenticated as service-role outside approved internal origins/functions; continuous secret scanning and rotation telemetry. | Low | High | high |
| TM-004 | Authenticated insider or compromised tenant account | Valid user access to AI skill endpoint and skill/tool availability. | Submit PHI-rich prompts or extraction prompts that pass to external provider/tool path, including fallback provider. | PHI confidentiality risk, policy/regulatory exposure, unintended data disclosure. | PHI-containing prompts, AI outputs, tool-accessible data sets. | Auth + org resolution + usage logging + PHI detection warning are present (validateAuth, detectPHI, logUsage) and fallback path is explicit (callOpenRouterFallback). | PHI detection appears advisory (warn/log) rather than hard block/redaction; provider fallback may expand data egress surface. | Add enforceable PHI policy gate (block/redact before external provider call), skill-level data classification controls, and explicit allow/deny matrix for tool categories by role. | Monitor PHI-detection hit rates, provider-fallback usage, and high-volume extraction-like prompt patterns per user/org. | Medium | High | high |
| TM-005 | Authenticated attacker with org foothold or header spoofing attempt | Access to proxy endpoint and ability to manipulate request context. | Abuse OAuth-backed proxy to perform unauthorized payroll actions or data pulls. | Financial data exposure and payroll integrity compromise. | OAuth tokens, payroll records, HR data. | Token encryption/decryption and refresh logic exist; proxy uses server-injected tokens and client IP handling (gusto-proxy helpers). | Trust in forwarded headers can be fragile if edge/network trust boundaries are misconfigured; token misuse detection unclear. | Enforce strict trusted-proxy CIDR validation + signed internal forwarding headers; add per-user action authorization checks before proxy forwarding. | Alert on anomalous IP/header patterns, repeated refresh failures, and unusual payroll API call volume by org/user. | Medium | High | high |
| TM-006 | External attacker or message spoofing actor | Access to SMS callback routes and ability to craft provider-like payload patterns. | Trigger inbound/status processing to manipulate consent or communication records. | Compliance risk (TCPA/workflow), incorrect outreach state, data integrity loss. | SMS consent state, message delivery records, partner/contact linkage. | Twilio signature validation and opt-out keyword handling exist; provider format discrimination is implemented (sms-webhook). | Multi-provider parsing path can be abused if provider detection is ambiguous; replay/idempotency not clearly universal. | Require strict provider-specific endpoint separation or mandatory provider auth artifact per request; add idempotent message/event key enforcement. | Alert on opt-out spikes, unknown-provider payload rates, and callback format anomalies. | Medium | Medium | medium |
| TM-007 | Supply-chain attacker or compromised dependency ecosystem | Ability to influence dependency source or CI execution path. | Introduce malicious package/action behavior to alter build outputs. | Platform-wide integrity compromise and downstream tenant impact. | Build artifacts, deployed SPA/function bundles, secrets in CI context. | CI enforces format/type/lint/tests/RLS/build smoke (.github/workflows/build.yml); dependency install uses lockfile (npm ci). | Workflow actions are pinned to version tags, not immutable SHAs; provenance/attestation checks are not explicit. | Pin GitHub Actions by commit SHA, enable dependency provenance verification, and require CODEOWNERS approval for workflow/lockfile changes. | Alert on workflow-file modifications, unexpected lockfile churn, and unusual CI network egress during install/build. | Medium | High | high |
| TM-008 | External botnet / opportunistic DoS actor | Public endpoint discoverability and no effective upstream rate limiting. | Flood public edge functions and expensive verification/API paths. | Reduced availability, delayed workflows, retry storms from providers. | Edge compute budget, queue throughput, operational SLAs. | Some functions fail fast on signature/auth errors and return early; CI and docs mention rate-limiting recommendations (docs/security/AUTOMATION_SECURITY.md). | Explicit global per-endpoint rate limiting and backpressure controls are not evident in repo-level runtime code. | Apply gateway-level rate limits + per-provider quotas + circuit breakers on downstream API calls; add bounded queues for webhook processing. | Monitor 4xx/5xx ratio, latency percentiles, and retry storm indicators per function/provider. | Medium | Medium | medium |
Criticality calibration
- Critical in this repo/context:
- Any exploit yielding cross-tenant PHI exposure or mutation at scale.
- Any compromise of service-role credentials enabling broad bypass of tenant controls.
- CI compromise resulting in malicious code shipped to production.
- High in this repo/context:
- Single-tenant PHI exposure through integration or AI data egress.
- Unauthorized payroll/background-check workflow mutation with financial/compliance consequences.
- Reliable replay/spoof attacks on webhook-driven state changes.
- Medium in this repo/context:
- Availability degradation of public functions without direct confidentiality/integrity loss.
- Limited-scope consent/message integrity issues requiring multiple conditions.
- Weak observability that delays detection but does not directly grant access.
- Low in this repo/context:
- Informational leakage without tenant crossover or sensitive payload access.
- Dev-only behavior that is isolated from production paths.
- Non-exploitable hardening gaps with compensating controls and low attacker utility.
- Critical examples: TM-001 at scale with PHI extraction, TM-003 with leaked service-role key, TM-007 with malicious build artifact insertion.
- High examples: TM-002 replay against financial events, TM-004 PHI egress via AI provider fallback, TM-005 payroll proxy abuse.
- Medium examples: TM-006 consent-state manipulation with partial impact, TM-008 sustained but bounded endpoint flooding.
- Low examples: CORS/header hardening deviations without credential-bearing exploit path (none prioritized in top table).
Focus paths for security review
| Path | Why it matters | Related Threat IDs |
|---|---|---|
supabase/config.toml | Central source of verify_jwt posture and auth hardening settings for exposed functions. | TM-001, TM-008 |
supabase/functions/_shared/auth.ts | Shared auth primitive and service-role shortcut influence many function trust decisions. | TM-001, TM-003 |
supabase/functions/_shared/cors.ts | Cross-origin policy is centralized and affects all edge endpoints. | TM-001, TM-006 |
supabase/functions/_shared/supabase.ts | Service-role client creation pattern controls privileged DB access behavior. | TM-001, TM-003 |
supabase/functions/ai-skill-execute/index.ts | AI execution path with tools, PHI detection, usage logging, and provider fallback. | TM-004 |
supabase/functions/checkr-webhook/index.ts | Signature verification and accepted pre-verification read pattern; high-integrity HR workflow input. | TM-002 |
supabase/functions/checkr-session-token/index.ts | Credential brokerage path for Checkr token creation and org access checks. | TM-005 |
supabase/functions/gusto-proxy/index.ts | Payroll proxy token handling, trusted header assumptions, and API forwarding behavior. | TM-005 |
supabase/functions/plaid-webhook/index.ts | Financial webhook verification and service-role mutation path. | TM-002 |
supabase/functions/ramp-webhook/index.ts | Public financial webhook endpoint and HMAC verification path. | TM-002 |
supabase/functions/ringcentral-webhook/index.ts | Telephony event ingestion with signature verification and subscription validation logic. | TM-002, TM-006 |
supabase/functions/sms-webhook/index.ts | Multi-provider SMS callback parsing and consent-related mutation logic. | TM-006 |
src/App.tsx | Runtime auth/session gate and provider composition for core app boundaries. | TM-001 |
src/platform/auth/useCurrentUser.ts | Identity state source for frontend authorization assumptions. | TM-001 |
.github/workflows/build.yml | Build gate and supply-chain attack surface for runtime artifacts. | TM-007 |
vercel.json | Browser security headers and deployment-level hardening defaults. | TM-001 |
tests/rls/pf-profiles.rls.test.ts | Evidence of tenant/data isolation tests and expected deny behavior. | TM-001 |
supabase/migrations/20260211182655_6aeefd1c-c5cc-4eaf-98b0-3e38abc7ba6a.sql | Canonical RLS enablement and SECURITY DEFINER helper patterns. | TM-001, TM-003 |
Quality check
- Covered discovered entry points: yes (SPA auth, edge API, webhooks, AI endpoint, CI workflow).
- Covered trust boundaries in threats: yes (internet->edge, edge->DB/service role, edge->vendors, git->CI->deploy).
- Runtime vs CI/dev separation: explicit in scope/system model and TM-007.
- User clarifications reflected: yes (whole platform, PHI multi-tenant, runtime + critical CI, top-risk integration deep dive).
- Assumptions and open questions explicit: yes (scope/assumptions section).