Most of the custom apps we scope for Canadian small and mid-sized businesses start the same way: someone asks for a client portal, an intake form or an internal dashboard, and halfway through the first meeting the question comes up: "Does our data have to stay in Canada?"
The honest answer is "it depends", but the engineering answer is that keeping it in Canada is cheap to do on day one and painful to do later. This post is the checklist we use to pin a small web app to Canadian infrastructure from the start, with the config snippets that make it stick.
1. Know what the rules actually say
Before touching Terraform, get the requirement straight, because "data residency" gets used loosely.
- PIPEDA (federal private-sector privacy law) does not ban storing personal data outside Canada. It makes you accountable for it, and expects you to tell people when their data may be processed in another country.
- Ontario's PHIPA applies to personal health information. Health custodians and their agents usually end up requiring Canadian storage in their contracts, even where the statute doesn't strictly demand it.
- Federally regulated financial institutions follow OSFI guidelines on outsourcing and technology risk, and their vendor questionnaires will ask exactly where data and backups live.
- Public-sector clients (municipalities, school boards, some provincial agencies) frequently write Canadian residency into the RFP itself.
So the real driver is usually a contract or a customer's procurement team, not the law alone. Ask for the clause in writing, because it tells you whether backups, logs and support access are covered too.
2. Pick regions that are actually in Canada
All three big clouds have Canadian regions, and two of them have a region in or near Toronto:
| Provider | Region | Location |
|---|---|---|
| Azure | Canada Central | Toronto |
| Azure | Canada East | Quebec City |
| AWS | ca-central-1 | Montreal area |
| AWS | ca-west-1 | Calgary |
| Google Cloud | northamerica-northeast2 | Toronto |
| Google Cloud | northamerica-northeast1 | Montreal |
For a Toronto business, Azure Canada Central or GCP northamerica-northeast2 keeps latency low for staff and customers, and a second Canadian region gives you somewhere to put backups without leaving the country.
3. Pin the region in code, not in a wiki
The most common way data leaks out of Canada is not a breach. It's a developer creating one "temporary" resource in the default region. Make the allowed regions a hard rule.
On Azure, an allowedLocations policy assignment at the subscription level does this:
{
"if": {
"not": {
"field": "location",
"in": ["canadacentral", "canadaeast", "global"]
}
},
"then": { "effect": "deny" }
}
On AWS, a Service Control Policy with an aws:RequestedRegion condition does the same job. In Terraform, fail fast in the module itself:
variable "location" {
type = string
default = "canadacentral"
validation {
condition = contains(["canadacentral", "canadaeast"], var.location)
error_message = "This app must be deployed to a Canadian region."
}
}
The validation catches mistakes in review. The cloud policy catches anything created by hand in the portal.
4. Check the services that quietly go global
Pinning your compute and database is the easy part. These are the pieces that tend to slip:
- Backups and geo-replication. Azure's paired region for Canada Central is Canada East, so geo-redundant storage stays in Canada. Double-check the pairing for any other provider or region you use.
- Email and SMS providers. Transactional email services often process and store message bodies in the US. If your portal emails documents, link to them instead of attaching them.
- Error tracking and logging SaaS. A stack trace can contain a name, an email or a health card number. Scrub request bodies before they leave, or pick a vendor with a Canadian or self-hosted option.
-
CDNs. Static assets cached worldwide are fine. Authenticated API responses should be marked
Cache-Control: private, no-storeso the edge never stores them. - AI features. If you add summarisation or a chatbot, check which region the model endpoint runs in. Several managed AI services are available in Canadian regions now, but the default is often a US one.
A small Express middleware is enough to stop personal data ending up in a CDN cache:
app.use('/api', (req, res, next) => {
res.set('Cache-Control', 'private, no-store');
next();
});
5. Encrypt, and decide who holds the keys
Encryption at rest is on by default for the managed databases on all three clouds. The stronger answer for a regulated client is a customer-managed key in a Canadian Key Vault or KMS instance, so the key itself never leaves the region either. It adds a little operational work (key rotation, access policies) but it's the line in the security questionnaire that ends the conversation fastest.
6. Write it down for the customer
Last step, and the one teams skip: a one-page data map. List each component, the region it runs in, where its backups go, and which third parties can see the data. When the next procurement questionnaire arrives, you answer it in ten minutes instead of a week.
Wrapping up
None of this is exotic. Region validation, a deny policy, a review of the "quietly global" services and a data map cover what most Canadian SMB apps need. Doing it before the first deploy costs an afternoon. Doing it after launch means migrating databases.
We build and support apps like these for businesses across the GTA; if that's useful context, here's our page on app development Toronto projects. Questions or corrections on any of the above are welcome in the comments.
Disclosure: this post is published by Senator Networks, a Toronto IT services and app development company.
Top comments (0)