← All workCase study · 03

One platform, many customer realities

An internal agent-management platform where authentication, feature visibility, and workflows all have to flex per customer without forking the codebase.

AWS CognitoAmplifyNext.js
The reality

One platform served many customers, each with different workflows, integrations, and access rules. A single shared codebase had to feel purpose-built to every one of them without becoming a maze of one-off conditionals.

My role

I architected a two-layer authentication model — exchanging Cognito sessions for platform access tokens — and a dynamic feature-visibility system that gates the UI per user based on feature flags, entitlements, and domain rules.

How it works

Browser → AWS Cognito/Amplify session → Next.js API routes acting as a backend-for-frontend → platform access tokens issued and refreshed server-side → feature-gated dashboard UI, with session replay, audio playback, and analytics layered on top.

No credential ever had to live in the browser.

The hard decision

I kept every token and header server-side behind the BFF instead of trusting the client with them directly. It added a hop and some latency, but it meant no credential ever had to live in the browser.

Failure modes

Token refresh races during long sessions, entitlement configuration drifting out of sync with what a customer actually purchased, and per-tenant configuration sprawling into something nobody could reason about.

Outcome

The platform now manages AI agents, tool configuration, workflows, analytics, and support ticket data for multiple customers from one codebase.

At scale

At far more tenants, per-tenant conditionals stop being viable. I'd push isolation down into the data layer itself and treat tenant configuration as versioned code, with automated tests for entitlement correctness.