Vault credential access layer in Edge Functions
epic-external-system-integration-configuration-backend-infrastructure-task-002 — Implement the secure credential retrieval layer within the Edge Functions environment. Create a CredentialProvider module that reads integration API keys from Supabase Vault using the service role client, caches credentials per-invocation, and ensures credentials are never logged or returned in response payloads. Include error handling for missing or expired secrets.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Handles integration between different epics or system components. Requires coordination across multiple development streams.
Implementation Notes
Access Vault secrets via the Supabase JS client by querying the vault.decrypted_secrets view with the service role client: supabase.from('vault.decrypted_secrets').select('decrypted_secret').eq('name', secretName).single(). The secret naming convention should be integration_{integrationId}_api_key (e.g., integration_xledger_api_key) — document this convention in the shared README. Define custom error classes as simple Deno classes extending Error with a typed name property to allow instanceof checks downstream. Do not use try/catch inside CredentialProvider to suppress errors — let them propagate to the calling router which will translate them into HTTP 500/403 responses.
Ensure the Supabase client is instantiated once per module (not per call) to reuse the HTTP connection pool within an invocation.
Testing Requirements
Write Deno unit tests (using Deno.test) for CredentialProvider. Mock the Supabase client using a stub object — do not make real Vault calls in unit tests. Test scenarios: (1) getCredential returns the correct decrypted secret for a known integrationId; (2) a second call for the same integrationId uses the cache and does not call the Supabase client again; (3) when Vault returns null, CredentialNotFoundError is thrown with the correct integrationId; (4) when the Supabase call rejects, CredentialAccessError is thrown wrapping the original error. All tests must pass with deno test --allow-env.
Supabase Edge Functions have cold start latency that can cause the first sync invocation after idle periods to fail or timeout when the external API has a short connection window, leading to missed scheduled syncs that go undetected.
Mitigation & Contingency
Mitigation: Configure Edge Function memory and implement a warm-up ping mechanism before heavy sync invocations. Set generous timeout values on the external API calls. Log all cold-start incidents for monitoring.
Contingency: If cold starts cause consistent sync failures, migrate the sync scheduler to a persistent Supabase cron job that pre-warms the function 30 seconds before the scheduled sync time.
The sync scheduler must execute jobs at predictable times for financial reporting accuracy. Drift in cron execution timing (due to Supabase infrastructure delays) could cause syncs to run at wrong times, leading to missing data in accounting exports or duplicate exports across reporting periods.
Mitigation & Contingency
Mitigation: Implement idempotency keys based on integration ID + scheduled period, so re-runs of a delayed sync cannot create duplicate exports. Log actual execution timestamps vs scheduled timestamps and alert on drift exceeding 5 minutes.
Contingency: If scheduler reliability is insufficient, integrate with a dedicated cron service (e.g., pg_cron on Supabase) for millisecond-precise scheduling, replacing the application-level scheduler.
Aggressive health monitoring ping frequency could trigger rate limiting on external APIs (especially Xledger and Dynamics), causing legitimate export calls to fail after the monitor exhausts the API's request quota.
Mitigation & Contingency
Mitigation: Use lightweight health check endpoints (HEAD requests or vendor-specific ping/status endpoints) rather than data requests. Set health check frequency to once per 15 minutes minimum. Implement exponential backoff after consecutive failures.
Contingency: If rate limiting occurs, disable active health monitoring for the affected integration type and switch to passive health detection (mark unhealthy only when a scheduled sync fails).