How BadgerQuest is built
We sell security training, so the one thing we should not ask you to do is take our word for it. This is how sign-in, tenant separation, keys, webhooks and logging actually work, and a plain list of what we do not have.
Signing in
Passwords are hashed with bcrypt at cost 12 and never stored or logged in any recoverable form. A sign-in attempt against an address that has no account still runs a full hash comparison against a fixed dummy value, so nobody can time the responses to work out which email addresses have accounts here.
| Method | How it works |
|---|---|
| Password | bcrypt, cost 12. Reset links are single-use and time-limited. |
| Two-factor (TOTP) | The standard authenticator-app code. The shared secret is encrypted with AES-256-GCM before it is stored, not merely hashed, because verifying a code requires reading it back. |
| Passkey | WebAuthn, so there is no shared secret to steal or phish. A passkey sign-in satisfies two-factor on its own, because the device already proved possession. |
| Single sign-on | OIDC against your own identity provider. See below. |
An owner can require two-factor or a passkey for everyone in the company. Somebody who does not yet meet it is sent to set it up when they open the app or the admin console, rather than being able to carry on without it.
Sessions can be revoked, and revocation is immediate. Each account carries a counter that every issued session is stamped with. Changing a password, completing a password reset, recovering an account with a new passkey, an administrator clearing somebody’s two-factor, and suspending an account all raise that counter, and every existing session on every device stops being recognised on its next request. There is no window where an old session keeps working until it expires.
Password reset and email verification links are single-use and time-limited, and a reset also removes every passkey on the account, because a reset means the account may have been compromised and a passkey an attacker planted must not survive it.
Keeping companies apart
One person belongs to one company, and every record that belongs to a company carries that company’s id. The interesting question is not whether that rule exists, it is whether any query has ever forgotten to apply it, because a missing filter looks like perfectly ordinary code and reads as correct.
So we check it by machine rather than by eye, before the code ships. A tool reads our own source files, finds every place the code queries the database, and works out from the query itself whether it is confined to one company or one person. If any is neither, the check fails and the change does not ship.
To be plain about what that tool touches: our source code, and nothing else. It reads the text of our own files on a build machine. It does not connect to a database, it is not part of the running service, and it never sees a single customer record. It is closer to a spell checker for queries than to anything that inspects your data.
The reads that are legitimately platform-wide, our own staff console and the shared training catalogue, are listed explicitly with a written reason for each, so the set of deliberate exceptions stays a short reviewed list rather than an unknown. Adding one is a decision somebody has to write down.
It is a strong check rather than a proof. It reads the shape of a query, so a filter passed in through a variable it cannot follow has to be reviewed by a person and recorded in that same exception list. What it reliably catches is the failure mode we care about: a query that names no company at all.
API keys
Keys are shown once, at creation. We store a SHA-256 hash and a short display prefix, so a key you have lost cannot be recovered from us, only replaced. That is deliberate: a key we could read back to you is a key anyone who got into our systems could read too.
| Property | Detail |
|---|---|
| Read-only | A customer key can only ever read. There is no version of it that can write, change or delete anything. |
| Bound to one company | Every query is filtered by the company the key belongs to. A key cannot be widened after creation and cannot reach another company's data. |
| Scoped per endpoint | A request whose scope the key lacks is refused with 403, so an integration gets exactly the access it needs. |
| Plan checked per request | Not just at creation. If a plan lapses, the key stops serving data on the next call rather than at some later tidy-up. |
| Rate limited | 240 reads per minute, per key. |
Full details in the API reference.
Outgoing webhooks
A webhook is the one place where our server makes a request to an address you chose, rather than only answering requests. That direction is a classic weak point in any product, so it carries the most protection.
| Control | Why |
|---|---|
| Signed with HMAC-SHA256 | Over the exact raw request body, so you can prove a delivery came from us. The signing secret is encrypted at rest on our side. |
| Private addresses refused | We look up where the address actually points before every single delivery, not just once when it was saved. If it points anywhere inside a private network rather than the open internet, we do not send. |
| Redirects refused outright | Your endpoint has to answer us directly. Following a redirect would mean the request we finally made was to an address the check above never got to see, which would undo it. |
| Five second timeout | A slow or unresponsive endpoint cannot tie up our servers. |
The last response status is recorded against the hook in your console, so a silently broken integration is visible rather than merely quiet.
Single sign-on
Signing in through your own identity provider means it vouches for who somebody is and we take its word. The risk people expect is a forged or broken sign-in. The one that actually matters is a perfectly valid sign-in from the wrong company.
We trust an identity provider only for domains you have verified by DNS, never by email. An inbox is not evidence of owning a domain, because every employee has an inbox and only your IT department can publish a DNS record. Without that rule, anyone who could configure a connection could assert addresses on a domain they do not own and walk into the company that does.
A new person arriving this way gets the role you set as the default. For somebody already on your roster, signing in this way leaves their role exactly as it is, up or down, so a sign-in can never quietly hand out or take away administrator access. If your identity provider is unreachable, people land on the normal sign-in page and use a password rather than being locked out.
The audit log
Every privileged action writes a record: who did it, to whom, and when. Administrators can read and export it themselves rather than asking us for it. It covers the ordinary things (inviting someone, changing a role, issuing an API key) and, importantly, the ones that are easy to leave out: erasing a person at their own request still writes a record that the erasure happened, because a deletion that leaves no trace is impossible to tell apart from data that was never there.
Your data
| Question | Answer |
|---|---|
| Where is it hosted? | North America, outside Canada. If you have a Canadian data residency requirement, tell us early, because this is the answer that most often decides a deal and we would rather say it now than at signature. Our Privacy Policy names the exact country and the providers involved. |
| In transit | HTTPS everywhere. The site is served over TLS with a strict content security policy. |
| At rest | Two layers. Everything we store, the database included, sits on storage our hosting provider encrypts at rest, so data cannot be read off the disks it lives on. On top of that, the application encrypts the most sensitive items itself before storing them, using AES-256-GCM: two-factor seeds, single sign-on client secrets, webhook signing keys and payment provider credentials. Anything that never needs to be read back, passwords, API keys and the tokens inside emailed links, is stored only as a hash. To be precise about the limit: ordinary records such as names and training results rely on the storage-layer encryption rather than carrying their own, which is the arrangement nearly every service has, and we would rather tell you that than let the paragraph above imply more. |
| Can people get their data out? | Anyone can export their own data from their own settings, at any time, without asking their administrator or us. |
| Can they delete it themselves? | Someone with no company can, from the same place. Someone in a company asks an administrator, who has an erase button that satisfies a deletion request. That is deliberate: the training record belongs to the company that required it, and one employee should not be able to remove their employer's proof that they were trained. The administrator's console spells this out, and so does the message the employee sees. |
| What happens to your figures when someone leaves? | The person is removed and your aggregate compliance history is kept without them. |
We do not send simulated phishing to real inboxes, phone numbers or messaging accounts. All practice happens inside the product and is labelled as practice, including in the event stream a security team consumes, so a rule in your own monitoring tools cannot mistake a training click for a real attack. This is a stance rather than a missing feature, and it has a compliance consequence worth knowing before you buy: see the phishing simulation question.
Keeping the software current
BadgerQuest is built on open-source components, and keeping them current is three layers, because any one alone goes stale. New versions are raised for us automatically as they are published. Every build refuses to finish if any component has a known serious vulnerability, so an insecure one cannot ship by being overlooked. And a weekly check reports anything that has fallen behind or stopped being maintained, which is the slower problem the first two miss.
The database server itself is patched for published vulnerabilities by our hosting provider, who notifies us when it happens.
What we do not have
Stated plainly, because you will be asked and a vague answer is worse than a short one.
| Not held | What that means for you |
|---|---|
| SOC 2 | No Type I or Type II report exists. If your procurement process requires one, we cannot satisfy it today. |
| ISO 27001 | Not certified. |
| Third-party penetration test | We have not commissioned one. We do attack our own work before we ship it, but that is not the same as an outside firm testing us, and we will not describe it as though it were. |
| Data residency in Canada | Hosting is in North America but not in Canada, and we have no Canadian region option at present. |
We do not claim any of these anywhere on this site, and we will not imply them on a form. If one of them is a hard requirement for you, say so early and we will tell you honestly whether it is on our plan, rather than letting it surface at signature.
What we can give you today: this page, a Privacy Policy that lists our security measures, a Data Processing Agreement, and prepared answers to the questions security questionnaires actually ask, in the company guide.
Checking us out, without taking our word for it
We are new. There is no customer list on this site because we do not yet have customers who have agreed to be named, and we would rather say that than show you a wall of logos you cannot verify. So here is what you can check for yourself today, none of which requires speaking to us.
| What you can check | How |
|---|---|
| Whether our claims are true | Every statistic on our sector pages links to the primary source it came from, with what the number counts and its denominator. Click one and check our arithmetic. If a number cannot be sourced, we do not use it. |
| Whether the evidence actually works | Certificates carry a serial anyone can verify at badgerquest.ca/certificate, with no account and no login. Try it with a certificate you generate during a trial. |
| Whether the product suits you | Run the whole paid plan free for 30 days, for up to 50 people, without giving us a card and without booking a call. If you do nothing when it ends you keep everything your people did. |
| What you would be signing | The Terms, the Privacy Policy and a Data Processing Agreement are all published and readable before you commit to anything, not sent after a call. |
| What we cannot do | The table above. We keep it current, and it is the first thing we would want to read about a supplier. |
If a named reference customer is a hard requirement for you, tell us and we will say plainly whether we have one yet rather than manage the question. When that changes, this section gets replaced by the names.
Reporting something
If you find a weakness in BadgerQuest, tell us and we will fix it. Use the contact form and say it is a security issue, and it will reach a person rather than a queue. We will not take legal action against you for reporting one in good faith, and we are glad to credit you if you would like us to.
Tell us what you found, the steps to reproduce it, and what somebody could do with it. That is enough for us to act on.
Please do not test against another customer’s company or another person’s account. Create your own free account and test against that. There is no reward programme yet, which we would rather say than let you assume otherwise.