Architecture
Signed policy and enforcement
Rules are written in the console, published as one signed version, verified by every browser, and enforced in the page before a form is sent. If a browser can’t prove its policy is current, it fails closed.
Describes LayerT as built on 3 October 2026. Anything not built is labelled.
The life of a policy
- ConsoleDraftIT writes or changes rules as drafts. Nothing reaches a browser yet.
- ConsolePublishPublishing applies every pending draft as one new version. Optional two-author review stops people publishing their own drafts.
- LayerT cloudSignThe version is serialised as canonical JSON and signed with Ed25519.
- BrowserFetchEvery 15 minutes, at start-up and after navigation, with conditional requests.
- BrowserVerifySignature, key, organisation, version and expiry are all checked before a single rule is used.
- The pageEnforceRules act on form submissions and pastes before the site’s own code runs. Rules for files and typed text act in the page too.
What a rule is
A rule says when it acts, where it applies, which fields it watches, what value triggers it and what happens.
| Part | Options |
|---|---|
| When | One of five triggers, listed in the next table |
| Where | A site pattern: exact URL, a glob such as https://*.postbox.example/*, or a regular expression |
| Which fields | CSS selectors for the fields on that page. Admins can build them by pointing at the page with the extension’s picker |
| What value | Conditions on the value the trigger reads: equals, matches a pattern, email domain, in a list, and combinations with and/or/not. Conditions can also compare against the person’s own directory identity, such as “only their own work address” |
| Who it applies to | A condition can be about the person instead of the value: it’s true when the person signed in to LayerT in that browser is in a directory group you name, whatever they typed. Under “not”, it’s true for everyone outside the group |
| What happens | Monitor (log only), block, block with a request (the person can ask for access), or force sign-out (clears the site’s cookies and storage, then shows a signed-out page) |
For a form or paste rule there is one more action, block, people can continue with a reason. It’s described under Continuing with a reason.
LayerT watches nothing on a page until a rule names it. The five triggers, and what each one reads:
| Trigger | What LayerT reads |
|---|---|
| Submitting a form (the submit event, a submit button, Enter in a field) | The text boxes and multi-line boxes the rule names |
| Pasting | Single-line text boxes the rule names |
| Typing in a field | Text boxes, multi-line boxes and rich-text editors the rule names. LayerT reads the field a moment after the person stops typing, and again when the text is about to be sent |
| Uploading a file, by its name | The file’s name, when a file is given to the page through a file box, a drop or a paste |
| Uploading a file, by its text | The text inside a plain-text file of up to 1 MB, read in the browser |
A file that a blocking rule matches never reaches the page. A rule about a file’s text also stops a file LayerT can’t read (an image, a PDF, an Office document, an archive, a folder, anything over 1 MB) and says it couldn’t check it.
Built-in rules cover personal Google sign-ins, Telegram Web and WhatsApp Web. The rule editor offers only the triggers, checks and actions the extension carries out, and a stored rule that uses anything else says so on its page.
What a rule can’t see
- A site’s own background uploads. Data a page sends by itself, without a form, a paste, a typed field or a file given through a file box, a drop or a paste, is outside every rule.
- Inside files that aren’t plain text. LayerT doesn’t look inside PDFs, Office files or images. A rule about file text stops them; it doesn’t read them.
- Text that has already left. Typed text is in the page from the first keystroke, and a page that sends as you type (search suggestions, autosaved drafts) already has it. A typing rule tells the person and stops the text being sent with a form, a submit button or Enter. It can’t take the text back.
- The clipboard. Paste rules act on pastes into the single-line text boxes a rule names. LayerT doesn’t read or control the clipboard.
- A password or code LayerT filled. No rule, on any trigger, reads a password, a one-time code or a secret sign-in field that LayerT filled, so a shared account’s password can’t reach a rule’s record.
- For a typing rule: any password box. A typing rule never reads a password box, a one-time-code box or a field LayerT filled. A form or paste rule reads the fields it names, and that can include a password box a person typed into themselves.
- Ready-made detectors. There’s no library of checks for card numbers or ID numbers. Rules use the patterns an administrator writes.
Rules about files and typing are plain blocks, warnings or monitors: asking for an exception and continuing with a reason aren’t offered on them.
Signing
Each published version is serialised deterministically (keys sorted, signature fields excluded) and signed with Ed25519. The policy carries a version number, the organisation it belongs to, when it was issued and when it expires.
- Versions only go up. Each publish takes the next number for your organisation under a lock, so two admins can’t publish the same version.
- Rolling back publishes the old rules as a new, higher version. Approved exceptions made since then are kept, unless the restored rules no longer allow them.
- The signing key is held in a key service and can’t be exported: LayerT’s servers ask the service for each signature. The key is software-protected. The service offers this type of key (Ed25519) in software only, so it isn’t held in a hardware security module. This is built and in use in LayerT’s test environment. Production, which will hold the key in Google Cloud KMS, is not deployed. Development builds sign with a local key, which production builds of the extension don’t trust.
The signed version your browsers receive is called a policy bundle. What’s in it (including other people’s allowlists and approved exceptions), where it’s stored on the laptop, and what someone who controls the laptop can do to it are on Policy bundles and device compromise.
Verification in the browser
The extension checks every policy with the browser’s own Web Crypto implementation before using it. In order, it refuses a policy if:
- its version isn’t newer than the one it already has,
- it belongs to a different organisation,
- it was signed with a key the extension doesn’t know,
- the signature doesn’t verify against the public key built into the extension, or
- it has expired, by the laptop’s clock.
A refused policy is thrown away and the browser keeps the one it had. Several public keys can be built in at once, so a signing key can be rotated without a gap.
Failing closed
A browser that can’t get a current, genuine policy doesn’t quietly stop enforcing it.
- Policy expires 7 days after it’s issued, and LayerT re-signs it automatically 48 hours before that. A browser only sees an expired policy if it has been unable to reach LayerT for days.
- On a page covered by a block or force sign-out rule, an expired policy stops every form submission and every paste into the rule’s fields, with a “Connectivity required” card. It explains what happened and offers only Back.
- It also stops a file given to a file rule’s fields, and Enter in a field a typing rule watches, without reading anything.
- Monitor rules keep logging.
- Unknown group membership fails closed too. Each browser gets a signed answer about its own person’s directory groups, valid for 24 hours. A browser without a current answer stops the action on pages where a blocking rule names a group, as it does when its policy is out of date, and asks LayerT again at once.
- When the browser reconnects, the card clears by itself within about 30 seconds, without a reload.
The emergency stop
The Owner can switch all enforcement off for the whole organisation. The stop is itself a signed policy version, so nobody can send a browser a fake one. It’s logged, and Owners and IT Admins are told. It only ever switches enforcement off: there’s no switch that locks everything instead.
Browsers pick it up on their next sync: within 15 minutes, sooner if the person navigates. A stop is marked urgent in the policy, but today the extension doesn’t fetch it any sooner than other changes. Revoking a browser and rolling back arrive the same way.
Enforcing in the page
LayerT’s content script listens for submissions and pastes before the site’s own code sees them. When a rule matches, LayerT cancels the event, so the site’s request is never sent. The end-to-end tests check that it isn’t.
A file is handled the same way: LayerT stops the file box, drop or paste before the page’s own code sees it, and a file that a blocking rule matches never reaches the page. Typing is different, because the text is already in the page. There LayerT shows the block and stops the text being sent with a form, a submit button or Enter.
LayerT’s prompts are built so that a page can’t interfere with them:
- They’re drawn in closed shadow roots, which the page’s scripts can’t reach.
- Their buttons respond only to real clicks and key presses, not to events a script creates.
- They never show the rule’s internal name. They show the message the admin wrote.
- They never ask for a password, and never contain a password field. A test checks every prompt.
- While a prompt is on the page, the LayerT toolbar icon shows an amber dot that the page can’t forge.
Asking for access
A blocked person can ask for access, if the rule allows it.
- BrowserAskThe person explains why. The request has a deadline, 30 minutes by default.
- Console or popupDecideAn approver chooses: a single attempt (five minutes), 15 minutes, 1, 8 or 24 hours, or permanent.
- LayerT cloudApplyThe approval becomes an exception in a newly signed policy, in one atomic step.
- BrowserRetryThe prompt updates by itself. If the person left, a desktop notification tells them.
- Nobody can approve their own request. The server refuses it.
- Permanent exceptions can be granted only by the Compliance Officer or the Owner, never by IT.
- A request that nobody decides expires automatically.
- Approvers hear about requests in the console Inbox, in the extension, and by email, Slack or a browser notification, as each person chooses. They can decide in the console or straight from Slack, and a Slack decision is logged as such.
Continuing with a reason
For a form or paste rule, an administrator can choose Block (people can continue with a reason). The person sees the block with a box for their reason. LayerT lets the action through only after the server has recorded the reason.
- No record, no way on. If the reason can’t be recorded, because the browser is offline or LayerT can’t be reached, the action stays blocked and the card keeps what was typed.
- No approver is involved, and nobody is notified. The reason is recorded with the person’s name before anything proceeds. It shows in Rule matches under Reason given, in the audit log and in exports.
- It isn’t offered on file or typing rules. While a browser’s policy is out of date, the rule fails closed like any other block, with no reason box.
What gets logged
Each block, warning, monitor match and use of an exception creates an audit event with the rule, the page’s address, the field, the matched value and the person. When a rule matches, LayerT records what matched, and for a typing rule the text of the field, so an auditor can check the decision. A rule can mask or hide its values.
- A form or paste rule records the text of the field, or the pasted text.
- A typing rule records the whole field as it was when the rule matched, not only the part that matched, up to 10,000 characters. Longer text is cut there, and the record says so.
- A file rule records the file’s name, type and size, how it was given to the page, and whether LayerT could read it. A file’s text is read in the browser to decide. It’s never sent and never stored.
- A reason given to continue past a block is recorded in the person’s own words. If they typed the blocked value into their reason and the rule hides or masks values, it’s hidden or masked there too.
- A password or code LayerT filled is never read by any rule, so nothing is recorded. A typing rule never reads a password box or a one-time-code box at all.
- A password a person typed themselves is read by a form or paste rule that names its box, and is recorded readable unless the rule is set to mask or hide its values.
- The user name LayerT fills for a shared account is still judged by a sign-in rule that covers the page. The rule lets the sign-in through and records that as an exception, with the user name. If the person replaces it with an address of their own, that is their text, and a form rule reads it.
Values are kept readable by default, so an auditor can see that the blocked sign-in was a personal address. Each rule chooses what the audit log keeps of its values: as typed, partly masked, or nothing. The browser always sends the value, and the rule’s setting is applied on the server before anything is stored. Audit events are kept for 365 days by default, and each organisation can change that.