Exception Security Private offensive security The platform

Architecture

How a private bug bounty platform is actually built

Most descriptions of this category stop at the promise. This is the mechanism: what has to exist before anyone touches your systems, what is re-checked on every single request, what each side is allowed to see, and how money moves. Where a guarantee is enforced by software we say so, and where it is only a policy we say that too.

1. The shape: managed engagements, not a marketplace

The first decision determines everything after it. This is not a venue where clients and researchers meet. A client contracts with the platform; researchers are engaged by the platform. The two parties have no relationship with each other and are not able to form one.

Client Names the scope Sets the reward Approves publication Exception Security Verifies identity Issues authorisation Triages every finding SEES BOTH SIDES Researcher Identity verified Works the scope Paid per finding scope invitation findings triaged organisation, officers and contacts do not cross
Exception Security holds both relationships because that is the only arrangement in which both guarantees hold at once. If either side could identify the other, the arrangement would have no function.

That separation protects both parties, and the client half is the one people miss. A researcher who knows precisely which company is exposed, and for how long, is holding something over that company. Removing the identity removes the leverage.

2. Before anything is touched: the activation gate

An engagement cannot be activated until three things exist simultaneously: a named scope, a signed NDA, and a written testing authorisation. Each blocks independently, and there is no override in the interface — an operator who wants to skip one cannot.

The authorisation is the part with legal weight. Testing a system without written permission is, in most jurisdictions, an offence regardless of intent. A platform that treats that as paperwork to be chased afterwards is exposing the researcher personally and the client contractually.

3. On every request: six conditions

Not at login. Not when the engagement was set up. On every single request a researcher makes, all six are re-evaluated and the first failure ends it — each with a distinct reason code, so the researcher is told which one and not simply refused.

  1. The account is active A suspended or closed researcher stops working immediately, everywhere, without anyone editing an engagement.
  2. Identity is verified kycStatus must be VERIFIED — a government document checked by a person, not a confirmed email address.
  3. The invitation was accepted Being invited is not being admitted. An operator cannot confer access unilaterally.
  4. This engagement's NDA is signed Per engagement, per researcher. Signing one grants nothing on the next.
  5. The engagement is active Paused or closed means access ends now, not at renewal.
  6. The moment is inside the authorised window Outside it, access is refused by the authorisation check — not discouraged by policy.

The reason this is per-request rather than per-session is mundane and important: a session issued at 09:00 on the last day of a window is still valid at 23:59 unless something re-checks. Revocation that only takes effect at next login is not revocation.

4. What each side can see

Redaction happens on the way out of the API, not in the browser. A client-side transform is cosmetic — whatever the server sent is already in the network log.

 Client seesResearcher sees
The other partyA stable pseudonymNothing — organisation, officers and contacts are deleted
The scopeTheirs, they wrote itYes — released on NDA signature, never before
FindingsTriaged and severity-scoredTheir own
The platform's marginNoNo
The audit logNo — it names both sidesNo

The pseudonym is stable per researcher, so a client can follow one contributor across a thread, a retest and a payment without ever learning who they are. It is derived by HMAC rather than by truncating an internal id, because a substring of an id is reversible by anyone holding the list.

The honest limit: the scope is released to the researcher, and a scope naming a public domain identifies the client on sight. It must, because someone who does not know what they may test cannot test it. So the enforced guarantee is precise — the organisation, its officers and its contacts are removed; the scope is not. Any platform claiming the researcher "never learns who the client is" is describing something stronger than a named scope permits.

5. Publication is a decision, not a countdown

A finding can be published only after it is closed and the client has approved the exact wording. The platform stores a digest of the text that was approved; change the text afterwards and the consent is void, and publication is refused rather than proceeding on the old approval.

That last detail is the difference between a consent step and a consent checkbox. Approval that survives an edit to the thing approved is not approval.

6. Money: funded before release

The reward for each finding is agreed with the client before testing begins, and the client is invoiced for accepted findings only. The researcher is paid what the platform owes them for that finding, and is shown that figure plainly before and after it is released.

Finding accepted reward set by client Invoice issued not yet money Invoice settled funds received Payout released researcher paid no path from an unsettled invoice to a payout
A draft invoice is not money and an issued invoice is not money. The platform will not release a payout against either — which is a constraint on the operator, not only on the client.

The payout statement shows what was awarded, what tax was withheld and what was transferred, so nothing has to be reconstructed at year end.

7. The record: a hash chain, not a log file

Every access, decision and artefact is written into a tamper-evident chain. Each entry hashes the previous entry's hash together with its own content, so altering an old entry invalidates every entry after it. Entries cannot be inserted, corrected or backdated — that is the point of the structure, and it is also the reason a mistake in it stays visible.

ENGAGEMENT_ACTIVATED hash(prev + content) SCOPE_RELEASED hash(prev + content) FINDING_ACCEPTED hash(prev + content) change any entry and every entry after it stops verifying
Writes take a database advisory lock so two concurrent entries cannot both claim the same predecessor and fork the chain. Entries are additionally signed, so a chain that verifies internally can also be shown to have come from this platform.

8. What is not claimed

Architecture pages tend to omit this section, which is why they are hard to trust. Stated plainly:

Exception Security runs this as a private, invitation-only service. There is no subscription, setup fee or retainer — you are billed only for a finding you have accepted, at a reward you set. Enquiries are answered individually: support@exceptionsecurity.com. If you are earlier than this, start by publishing a way to receive reports — it is free and it is the prerequisite.