A franchise marketing platform is not only a place where documents sit. It holds the credentials to your ad accounts and it is able to spend real money on your behalf. That is a bigger ask than most software makes, so this page sets out what protects it, in plain words, including the parts we have not built yet.
Everything below is described in more detail further down the page. If your security team wants the long version with file names and test counts, ask and we will send the supplier pack.
Most security pages talk about data, because most software only holds data. A platform that pushes campaigns to Meta and Google holds something else as well: the ability to spend. So the question a franchisor should ask is not only whether someone could read the network's data, but how much of the network's money they could burn before anybody noticed.
Amplaro answers that with limits built into the code rather than configured on the side. There is a ceiling on a single campaign, on what one client can spend in a rolling day, on what one client can spend in a rolling month, and on what the whole platform can spend in a rolling day. There is a maximum cost per click and a longest possible flight. Those numbers hold even if nobody ever configures anything.
At the order, before any money is taken. Again when the payload is built. Again inside the only three functions in the product that can push spend to an ad platform. Nothing gets to the wire around them.
Head office can pull their own limits tighter from their settings. Every stored value is clamped on the way in, so a limit written through the console or the API can never end up higher than the built-in ceiling.
The only way to lift a hard limit is a change to our hosting environment and a release. That is deliberate. A stolen session or a stolen API key must not be able to unlock more money than shipping new code does.
If the limit check cannot complete, the push is refused rather than allowed through. The refusal is written to the audit log before the error is raised, so a blocked attempt leaves a trace.
A freeze stops every new push to Meta and Google while the rest of the platform keeps working. It is the lever for the hour where something looks wrong and you do not yet know what.
The live campaign list is pulled from both ad platforms and compared against our own records. Anything running that we did not create is flagged, including campaigns that were removed.
Stated plainly: with an API key, an admin session and the database all in the wrong hands at the same time, what can be spent is still bounded by a number, and moving that number needs access to our hosting account. Two things this does not cover, because they are outside the platform: money a client spends by editing a campaign directly in Ads Manager, and money already spent, which nothing claws back. The only hard dollar stop against an ad token used directly at the platform is that platform's own account spend cap, which is worth setting.
Checkout is a complete redirect to the payment provider's own hosted page. Not an embedded form, not a set of hosted fields, not an iframe. There is no payment script anywhere in the Amplaro front end, which we check rather than assume. The card number, expiry and security code only ever exist on the provider's own domain.
What comes back and gets stored is a session reference, a payment reference and an amount. No card number, no last four digits, no bank details, no stored card. When a partner returns from paying, the platform re-reads the payment from the provider server to server, so a faked return address proves nothing and cannot mark an order paid.
The merchant account is your own. Payouts land in head office's account, the secret key is encrypted at rest and never shown back once saved, and Amplaro never holds anybody's funds. Our reading is that this is the simplest PCI category available, since a full redirect is treated differently from an embedded payment form. That is for your assessor to confirm rather than for us to declare. What the money actually pays for is on pricing.
Two factor is mandatory for platform admins, not offered. The account cannot be used without an enrolled authenticator, and the code is required for the session rather than only at enrolment, so a password on its own creates nothing. Ten single use recovery codes are issued once, stored hashed, and a used time step is remembered so a code cannot be replayed.
For your own team, Microsoft Entra single sign-on is available per organisation. Turn it on alongside passwords, get a few people through it, then make it the only way in. After that your conditional access and MFA policy decides who gets a session, which is almost always stricter than anything we would impose. The one classic trap with Entra is the client secret expiring and locking out the very people who could fix it, so the platform records the expiry date, warns on an escalating schedule, and if the secret really does stop working it suspends the requirement instead of locking your team out. Passwords still apply, so the fallback is not a way in for anybody.
Sign-in attempts are counted against both the address and the network address, with a short lockout after repeated failures. The counters live in the database rather than in memory, so a release does not hand an attacker a clean slate, and they are stored as a salted hash so the table is not a readable list of which accounts are under attack. The refusal message is the same whether or not the account exists.
Sessions can be revoked for one person or for everyone on the platform at once, and both need a written reason and get logged. Changing a password signs that person out everywhere. The session cookie itself is signed, http only, and only sent over HTTPS in production.
There are two roles, head office and franchise partner, plus a platform admin flag that no screen, form, import or endpoint in the product can grant. A partner sees their own stores and nothing else. What head office can and cannot do is on for head office, and the rules a partner cannot get around are on brand control.
Ad platform tokens, the payment key, the single sign-on client secret and two factor seeds are encrypted in the database column with AES-256-GCM. The key is an environment variable. It is not in the database, it is not in the repository, and it is not in any backup, so a copy of the database on its own does not open your ad accounts.
Production refuses to start without that key. On every boot the server decrypts a known value to prove the key is the right one, and if it is not, the new version never starts serving, so the previous one keeps running instead of the platform quietly failing on every campaign. Encrypted values carry a key version with them, so keys can be rotated: the rotation tool dry runs first, refuses to continue if a single value cannot be read, checks every rewritten value before committing, and does the whole rewrite in one transaction.
Passwords are stored as bcrypt hashes and are never recoverable, only resettable. Everything travels over HTTPS with strict transport security for a year. Every page carries a content security policy that is the same idea as the rest of this page: everything from our own address, nothing else. No external script can load, and code injected into a page cannot send anything to another host. On top of that: no content type sniffing, frames refused, a strict referrer policy, and a permissions policy that turns off geolocation, camera, microphone and payment.
Recovery point objective 24 hours, recovery time objective 4 hours. Those are the numbers we commit to. A restore of a database this size takes minutes, so most of the 4 hours is allowance for noticing, deciding and provisioning.
A backup is a full logical dump of every row of every table, written with a checksum and a row count per table, so a half finished file can never be mistaken for a good one. Each new dump is copied off site to storage held by a different company from the host, encrypted under a separate key before it leaves the server, so losing the hosting account does not take the backups with it and the storage provider never holds readable data. A successful upload is not treated as proof on its own: the object is asked for again afterwards and the stored size compared with what was sent.
Restores are tested rather than assumed. The test takes a fresh dump, fingerprints every row, restores it into a throwaway target that cannot touch live data, and compares. The result and its date sit in the console, so "when did you last test a restore" always has an answer with evidence behind it. A full drill has been run end to end: a dump restored into an empty database, the application booted against it, sign-in working, and new records written afterwards receiving correct identifiers rather than colliding with restored ones.
Around 1,500 automated checks run across twelve parts of the platform before anything ships. That proves the code. It does not prove the live platform, so there is a second sweep that runs every night against production itself: can a partner order right now, can every recent order still be confirmed, does the payment provider answer, do Meta and Google still accept our credentials, is there a recent backup, is the audit log still being written.
The report goes out on a good night too. A report that only arrives when something is wrong is indistinguishable from a report that has stopped working, and you find out which one you had on the night you needed it. Separately, an unhandled error raises an alert within seconds rather than waiting for the evening. Alerts about the platform come to us and never to a client.
One honest note on this. The check that notices a sweep has gone stale runs in the same process as the sweep, so it cannot notice that process being dead. An external uptime check is on the list and is not in place yet.
Yes, technically, and we would rather write it here than have it surface halfway through your review. There is a platform admin account that can act inside an organisation, which is what makes support possible at all. Every use of it is written into that organisation's own audit log, so it is visible to you and not only to us. There is exactly one platform admin account, because nothing in the product can grant that flag to anybody.
One franchise brand cannot reach another one's data anywhere in Amplaro. Worth knowing for a security review: that separation is enforced in application code rather than at the database level, and the platform-wide health screen is the one place a platform admin can see across organisations, which is why it is admin only and why it defaults to showing only the organisation you are signed in to.
The audit log records who did what and when, with a name attached, across campaign packages, launches, payments, user changes, settings and anything a platform admin does inside your organisation. It is kept for two years. Keeping it forever is not a policy, it is the absence of one. What else head office keeps hold of is on for head office, and what is reported back per store is on reporting.
A short list on purpose. Amplaro runs as one application with nine runtime dependencies, no shell, no SSH and no admin port exposed. These are the other companies involved in delivering it, and what each of them can actually see.
| Who | What they do | What they can see |
|---|---|---|
| Railway | Runs the application and the managed database | Everything, as the host |
| Cloudflare R2 | Holds the off-site backup copies | Encrypted files. The key is not held there |
| Stripe | Takes card payments on their own hosted page | The card and the payment, nothing else |
| Meta and Google | The ad platforms campaigns are pushed to | Your own ad accounts, which you already own |
| Cloudprinter | Prints and delivers local print material | The artwork and delivery address for that order |
| Resend | Sends notification and alert email | The address and contents of those emails |
| OpenStreetMap and Carto | Map tiles behind the delivery area editor | Which map tiles a browser asked for |
Swipe the table sideways to see the rest.
On residency: the application and its database run in a hosted United States region today. Moving to an Australian or European region is a move rather than a rewrite, but it needs lead time. If residency is a hard requirement for your brand, raise it in the first conversation. We would rather agree the region up front than find out late that it blocks a review. How data is collected and handled is set out on privacy, and the commercial side on terms.
Every vendor security page is a list of yeses. That is not much use to the person who has to sign off on the risk, because the interesting question is what is missing. So here is ours, and we would rather you read it here than find it in the review.
Amplaro is not certified against either, and we will not imply that it is. If certification is a hard procurement requirement, say so in the first conversation.
It is on the list. For a brand with a preferred testing partner we would rather use yours than pick our own, so the report is one your security team already trusts.
There is no continuous vulnerability or dependency scanning in the release pipeline. Nine runtime dependencies keeps the surface small, but small is not the same as scanned.
It is mandatory for platform admins and available to everyone, but not yet compulsory for head office and partner accounts, unless your organisation uses single sign-on and your own policy requires it.
One brand cannot reach another one's data, but that boundary is enforced in application code rather than at the database level. Worth knowing, and worth asking about.
A regional outage at the host is an outage. And there is no SCIM, so accounts are created in Amplaro rather than provisioned from your directory.
Most of these are work rather than a decision, and several move quickly once a brand tells us they matter. What we will not do is answer yes to a questionnaire question we cannot evidence. If any of the above is a blocker for you, it is much cheaper to find out in week one. Start that conversation on contact.
Email hello@amplaro.com.au with "security" in the subject line and we will confirm we have it. There is no paid bug bounty. What we ask in return is the usual: please do not test against real client data, do not run anything that would degrade the service for a franchise partner who is trying to work, and give us a reasonable window to fix it before publishing.
If you are running a vendor security review and want the long version, ask us for the supplier pack. It has the architecture and data flow diagrams, the control descriptions with the file names behind them, the test counts, and the same gap list as above with dates against it.
No. Amplaro holds no ISO 27001 certification, no SOC 2 report and no third party penetration test report, and we are not going to imply otherwise. What we can give a security review instead is a written description of every control, an architecture and data flow diagram generated from the repository rather than drawn by hand, and a list of what is missing. If certification is a hard requirement for your procurement process, raise it in the first conversation rather than the fifth.
The application and its database run in a hosted United States region today, and encrypted off-site backup copies are held by a separate storage provider. If Australian or European data residency is a requirement for your brand, it is a move rather than a rewrite, but it needs lead time and it needs to be raised before a security questionnaire asks. We would rather agree the region up front than discover it is a blocker late.
Yes, technically, and we would rather say so here than have it surface halfway through your review. There is a platform admin account that can act inside an organisation, which is what makes support possible at all. Every use of it is written into that organisation's own audit log, so it is visible to you and not only to us. There is exactly one platform admin account, because no screen, form, import or endpoint anywhere in the product can grant that flag to anybody.
A bounded amount, and that is the point. Spend limits are built into the code rather than configured on the side: a ceiling per campaign, per client per day, per client per month and across the whole platform per day, plus a maximum cost per click and a longest possible flight. They fail closed, they are checked at the order, at the payload and at the moment anything is pushed to Meta or Google, and a stored override can only ever lower a limit. Raising a ceiling needs a change to our hosting environment and a deploy, so a stolen session, a stolen API key or a compromised database cannot lift it.
No. Checkout is a full redirect to the payment provider's own hosted page, not an embedded form and not an iframe. There is no payment script anywhere in the Amplaro front end. Card number, expiry and security code only ever exist on the provider's domain. We keep the session reference, the payment reference and the amount, and nothing else, so there is no card number, no last four digits, no bank details and no stored card in the database. Our reading is that this puts the integration in the simplest PCI category, which is for a qualified assessor to confirm rather than for us to rule on.
Yes, Microsoft Entra ID, configured per organisation with your own app registration. It can be switched on alongside passwords first and then made the only way in, so your own conditional access and MFA policy decides who gets a session. The client secret has an expiry date that Entra will not let you avoid, so the platform tracks that date, warns on an escalating schedule as it approaches, and if the secret does stop working the requirement suspends itself rather than locking your whole head office team out at once. Google Workspace and Okta are not built. There is no SCIM, so accounts are created in Amplaro rather than provisioned from your directory.
Daily, with a stated recovery point objective of 24 hours and a recovery time objective of 4 hours, and the interval is a single setting if a client needs it tighter. Each backup is a full logical dump, checksummed when written, copied off site to a storage provider that is a different company from the host, and encrypted under a separate key before it leaves the server. Restores are tested rather than assumed: the test takes a fresh dump, fingerprints every row, restores into a throwaway target and compares, and the date of the last test is shown in the console. A full drill has been run, where a dump was restored into an empty database, the application booted against it and new records were written with clean identifiers.
A partner account can order campaigns for their own stores inside the rules head office set, so the exposure is a campaign order, not access to the network. Sign-in attempts are throttled on both the address and the network address. Sessions can be revoked for one person or for everyone at once, and changing a password signs that person out everywhere. Every action carries a name in the audit log, spend limits still apply, and a single switch stops every new push to the ad platforms while the rest of the product keeps working.
Two years by default. The log records who did what and when, with the person's name attached, across campaign packages, launches, payments, user changes, settings changes and anything done by a platform admin acting inside your organisation. Keeping it forever is not a policy, it is the absence of one, so there is a retention period and it is written down.
The controls above exist because of how the platform is shaped. Eg: partners can only order what head office already approved, so there is nothing to review at launch. See how it works.
Control of the brand, the budgets and the reporting, without becoming the bottleneck for every local ad.
How head office can build a quarter of campaign packages with an LLM, as drafts, with every action logged.
What to compare when you are looking at franchise marketing platforms, and the questions worth asking early.
Half an hour with the platform, and straight answers on the parts your review will ask about.
Book a demo