Deploying Lambda services into customer AWS accounts
The CloudFormation patterns we use to deploy the same .NET service into dozens of isolated customer environments — without managing them.
Multi-tenant SaaS is the default model for almost every B2B product. Pool everyone into one database, isolate by tenant ID, scale the runtime once.
We don’t ship that.
Every Kanject deploy lands inside the customer’s own AWS account. Their data, their bucket, their IAM policies. We never touch it. The same .NET service ships to dozens of isolated environments, and we operate exactly zero of them.
Here’s how we do it without losing our minds.
The architecture in one paragraph
Every Kanject module — Identity, Wallet, NotificationHub, the lot — ships as a NuGet
package and a CloudFormation template. The customer runs kanject deploy (or wires
the template into their own CodePipeline). The template provisions every AWS resource the
module needs: DynamoDB tables, S3 buckets, Cognito user pools, SQS queues, Lambda
functions. All inside their account. All under their IAM.
We don’t have access. We don’t have credentials. We don’t have a control plane. The customer owns the keys.
What this changes for the customer
The pitch is simple: data residency stops being a quarterly meeting. Compliance stops being a paperwork exercise. The auditor walks into your AWS account, sees Cognito user pools and DynamoDB tables, and writes “standard AWS managed services” in the report. Done.
The customer also gets the AWS-native tooling for free. CloudWatch metrics already exist. CloudTrail audit logs already exist. AWS Backup already works. We didn’t have to ship any of that — AWS did.
What this changes for us
We don’t run anything. There’s no Kanject control plane. There’s no Kanject database that holds anyone’s data. There’s no Kanject endpoint that can leak.
This means we don’t have to be SOC 2 certified to sell to a SOC 2 customer — the customer is, because their AWS account is. We don’t have to negotiate DPAs as if we’re a data processor — we’re not, because the data never leaves their account.
It also means we can’t get hacked into a customer’s data. We literally don’t have it.
The hard part
The hard part is deployment ergonomics. CloudFormation is verbose. CDK is better but forces a build step in the customer’s CI. Terraform is great but adds a third tool to the customer’s stack.
Our answer: ship templates, not scripts. Every module’s CloudFormation template is hand-tuned for the smallest possible blast radius and the cleanest IAM policy. The customer can read it. The customer can modify it. The customer can copy it into their own infrastructure-as-code repo.
We give them the recipe. They own the kitchen.
Trade-offs we accept
This model has costs. Customer success is harder — we can’t see their logs unless they
share them. Debugging is harder — we can’t aws cli into their account. Onboarding is
slower — they have to actually deploy infrastructure before they can sign in.
We accept all of those, because the alternative — running a multi-tenant SaaS that holds every customer’s data — is the model we don’t want to be in.
If you’re evaluating Kanject and the “deploy to your AWS” model is new to you, the /baas overview walks through how each module fits together. If you’re a customer who already runs the platform and you want a deeper portability story, talk to us — we have a portability assessment doc that goes module by module.