User guide
Data Residency
Looking for what it does rather than how to use it? Read the Data Residency overview .
What it is
Solidlio stores all customer data in Microsoft Azure’s Canada Central region. Every account carries a region field that records where it is hosted and which currency it bills in; today the only value that field can hold is CA, because Canada Central is the only deployment that exists.
This guide describes what the region setting actually controls, who can change it, and what does and does not stay inside Canada.
They are not available. There is no US database and no EU database. An account cannot be placed in either, and the product will refuse the attempt rather than accept it and store your data in Canada under a European label.
Concepts
| Term | What it means |
|---|---|
| Region | Where an account’s data is hosted. CA today. Stored on the account as Account.region. |
| Stamp | One complete regional deployment: database, cache, object storage, gateway and services. Solidlio runs one, in Canada Central. |
| Home region | The region an account belongs to, carried in every access token as the homeRegion claim. |
| Current region | The region a request is being served in, carried as the currentRegion claim and forwarded to services as the X-Region header. |
| Residency region set | The regions an account may be placed in. Configured per deployment (RESIDENCY_REGIONS), defaults to CA. |
| Cross-border attempt | A request whose token names one region presented to a stamp serving another. Refused with 403 and recorded. |
Region and currency are the same decision
The region field does two jobs, and only one of them is about geography:
| What region drives | Effect |
|---|---|
| Hosting location | Canada Central. One value today, so no variation. |
| Default billing currency | CA → CAD, US → USD, EU → EUR. Applied when the account is created. |
| Stripe Connect country | An MSP’s Connect account is opened in its region’s country. Irreversible once created. |
| Platform-invoice tax country | Drives the tax treatment applied to Solidlio’s own invoices to the tenant. |
| Report stamping | Every generated report records the account’s region alongside the data. |
Changing an account’s region therefore changes real money behaviour even though it changes nothing about where bytes live. That is why the control sits with the platform operator and not with the customer.
Roles and permissions
| Action | Who | Where |
|---|---|---|
| Choose a region at signup | Anyone creating a new account | /complete-profile, step 3 |
| See an account’s region | platform administrator | /platform/accounts |
| Review blocked cross-border attempts | platform administrator | /platform/privacy |
There is deliberately no organization-level or MSP-level region control. A tenant cannot move itself into a region the operator has not deployed, and an MSP cannot place a managed client somewhere its own account is not.
Walkthroughs
Choosing a region at signup
- Start signup and verify your email.
- On Complete your profile, work through to step 3 — Data & Billing.
- Under Data region, the available regions are selectable and the rest are shown greyed out with ”— not available yet”. Today only Canada is selectable.
- The line beneath confirms where your data will be stored and which currency you will be billed in.
- Finish signup. Your account is created in that region and its default currency is set from it.
Selecting a country outside Canada (for example Germany) does not place your account in Europe. The picker will keep Canada selected, and the page states plainly that Solidlio hosts all customer data in Canada.
Reviewing an account’s region as a platform admin
- Go to Platform → Accounts.
- Open an account. The Region control shows the account’s region.
- The control is disabled and reads “Locked to platform region”. This is correct: the region cannot be changed from this screen because there is nowhere to change it to.
Reviewing blocked cross-border access
- Go to Platform → Privacy.
- The Cross-border attempts panel lists every request that was refused because the token’s region did not match the stamp serving it, with the source region, destination region, person, IP address and reason.
- On a single-region deployment this list is empty, and that is the correct result — there is no second stamp for a token to be presented to.
Configuration
| Setting | Where | Default | What it does |
|---|---|---|---|
REGION | api-gateway | unset | This gateway’s region. Used as the fallback when a request carries no region. |
If unset: every one of these defaults to the single-region behaviour — Canada only, no regional routing, no region mismatch check. Nothing breaks; the deployment simply has no regional identity.
Such a stamp would reject every account it is able to create.
Plan tiers
Data residency carries no plan gate. Every account on every tier is hosted in the same region, with the same protections. There is nothing to buy and nothing withheld.
Troubleshooting
| What you see | Cause | Fix |
|---|---|---|
400 — Data residency region "EU" has no deployment. Accounts can only be placed in: CA. | An account create/update named a region with no stamp behind it. | Use CA. To add a region, deploy it first (see below), then widen RESIDENCY_REGIONS. |
400 — Data residency region "US" is not available. Solidlio currently hosts data in: CA. | A signup posted a region that is not offered. | The picker offers only available regions; this indicates a direct API call. |
403 — REGION_MISMATCH / “Token not valid for this region” | A token minted for one region was presented to a stamp serving another. | Sign in against the account’s own region. The attempt is recorded. |
403 — REGION_ACCESS_DENIED / “User does not have access to this region” | The user’s permitted regions do not include this stamp’s region. | Same. Recorded as a cross-border attempt. |
| Cross-border attempts panel is always empty | Expected on a single-region deployment. Also expected when REGION is unset — the check is off. | Set REGION per stamp once a second region exists. |
The region dropdown on /platform/accounts is greyed out | Intentional. There is one region, so there is nothing to select. | None. |
Limits and known behaviour
Read this section before making any residency commitment to a customer.
One region
- There is one deployment: Azure Canada Central. The dev, test and production parameter files all pin
location = 'canadacentral'andregionCode = 'cac'. - Two of them describe infrastructure that does not exist. DNS records for
*.us.solidlio.comand*.eu.solidlio.comare not published. - Data residency is achieved by there being only one region. No database query anywhere is scoped by region. A per-request residency check now exists in the shared auth middleware, but it is inert on a single-region deployment — see “What is and is not enforced” below. Do not present it as residency enforcement; present the single deployment as the residency guarantee.
What is and is not enforced
- Every service now reads region context.
@solidlio/auth-middlewarepopulatesreq.regionfromX-Regionand applies a residency check before handing off, so the check cannot be missing from one service — it is part of theauthContextevery backend already mounts. - The check is INERT unless
REGIONis set on the stamp. With one deployment there is no wrong region to be in. This is the request-path half of what residency needs — it is not evidence that multi-region residency exists, and it does not create a second region. - Only a genuine MISMATCH is refused, with
403 REGION_MISMATCH. - No database query is scoped by region. That remains true, and remains the reason residency is a property of the deployment rather than of the query path.
@solidlio/rbacstill exportscreateRegionGuardfor route-specific use. It is mounted on no route, and no longer needs to be.
Changing an account’s region does not move data
Setting Account.region relabels the account. It does not copy, re-encrypt or re-home a single stored row, and there is no migration path that does. A region change is recorded in the audit log as ACCOUNT_REGION_CHANGED with an explicit dataRelocated: false, precisely so the record cannot later be mistaken for evidence of a data migration.
Data that leaves Canada
Solidlio’s own hosting is in Canada. These paths send data elsewhere, regardless of an account’s region:
Two paths that are commonly assumed and do not happen:
- Signing runs entirely on Solidlio’s built-in capture.
- No order data reaches a distributor. The TD Synnex and Ingram integrations are a one-way pull of catalogue, price and availability. Order submission is not implemented anywhere in the product — purchase orders are emailed to the vendor.
An AI feature that summarises a ticket sends that ticket’s text outside Canada. If a customer’s requirement is that no personal data leaves Canada, AI features must be left disabled. That is a real constraint, not a caveat.
Backups and redundancy
- Geo-redundant backup replicates to Azure’s paired region for Canada Central, which is Canada East — so backups stay within Canada.
- Production object storage is zone-redundant (
Standard_ZRS) within Canada Central. - GDPR export archives are deleted automatically 7 days after creation.
Adding a region
Widening RESIDENCY_REGIONS alone does nothing except allow a label. The order that actually works:
- Deploy
main.bicepagain with that region’slocationandregionCode. - Publish the region’s DNS records (
*.<region>andapi.<region>) — they are present but commented out indns-zone.bicep. - Set
platformRegion(and thereforeREGION) on each stamp. This is what arms the per-request residency check — until it is set, every stamp serves a credential from any region. - Then widen
residencyRegions. - Build the web bundle with the new region resolvable — the deploy workflow derives the offerable region set from the gateways it can actually resolve, so a region with no container app is never offered.
Steps 1–4 are infrastructure. No code change makes a region real.