Architecture
Policy bundles and device compromise
Your rules reach each browser as one signed file, a policy bundle. This page explains what’s in it, how a browser decides to trust it, and what someone who controls a laptop, or breaks into LayerT, can and can’t do with it.

Describes LayerT as built on 19 September 2026. Anything not built is labelled.
In plain words
When your IT team publishes rules in the admin console, LayerT packs your organisation’s whole rulebook into one file, called a policy bundle, and signs it. Every LayerT extension has the matching public key built in, so a browser can tell a genuine bundle from a forged or altered one. It refuses anything that doesn’t check out.
Why it’s signed. The bundle travels over the internet and sits on laptops nobody watches every minute. The signature means nobody between LayerT and the browser can change a rule, add an exception or switch enforcement off. Nobody can hand a browser another organisation’s rules, or an older version of yours, either.
Why it expires. Every bundle is good for 7 days, and LayerT re-signs it automatically well before then. Expiry stops a laptop living forever on old rules: a bundle that nobody can refresh eventually stops counting as current.
What happens offline. A browser that can’t reach LayerT keeps using its last genuine bundle. New rules, new approvals, revoked devices and the emergency stop can’t reach it until it reconnects. If it stays offline until its bundle expires, it doesn’t quietly fall back to allowing everything. On the sites your blocking rules cover, it stops form submissions and asks the person to reconnect.
What’s never in it. Passwords and one-time codes for shared accounts never travel in a bundle. They’re sent separately, for one sign-in at a time. A bundle does hold work email addresses and the exceptions your approvers granted, so treat it as company data.
What’s inside a bundle
A bundle is one JSON document for your whole organisation. Here’s a shortened example with fictional values:
{
"bundleVersion": 57,
"issuedAt": "2026-09-18T09:00:00.000Z",
"expiresAt": "2026-09-25T09:00:00.000Z",
"tenantId": "3f1c2a9e-7b44-4d2e-9a51-0c6e1d2b8f10",
"tenantDisplayName": "Example Trading Ltd",
"killSwitch": false,
"critical_update": false,
"revoked_devices": ["b7e0c1d2-5a6f-4e3b-8c9d-1a2b3c4d5e6f"],
"classifiers": [
{ "id": "corp_email", "type": "email_domain", "value": "example-trading.test" }
],
"rules": [
{
"id": "rule_postbox_work_only",
"name": "Sign in to Postbox with a work account only",
"enabled": true,
"event": "form_submit",
"urlMatch": { "type": "glob", "patterns": ["https://*.postbox.example/*"] },
"selectors": [{ "css": "input[name=login]" }],
"valueMatch": { "op": "not", "operand": { "type": "matches_user_attribute", "field": "allowed_postbox_accounts" } },
"action": {
"type": "block_with_request_bypass",
"message": "Use your Example Trading account here.",
"bypass": { "mode": "request_bypass", "justificationRequired": true }
},
"audit": { "include": ["url", "value"], "redact": "partial" }
}
],
"exceptions": [
{
"id": "0b9c8d7e-1111-4222-8333-944455566677",
"ruleId": "rule_postbox_work_only",
"subject": { "userId": "jc_alice_chen" },
"matchedValue": "[email protected]",
"expiresAt": "2026-10-01T00:00:00.000Z",
"grantedBy": "[email protected]",
"grantedAt": "2026-09-17T08:12:00.000Z",
"justification": "Monthly upload to the Vendor Reports portal"
}
],
"groups": {
"grp_finance": ["user:[email protected]", "user:[email protected]"]
},
"user_attributes": {
"[email protected]": { "allowed_postbox_accounts": ["[email protected]"] },
"[email protected]": { "allowed_postbox_accounts": ["[email protected]"] }
},
"signature": "ed25519:q8Vd…(64 bytes, base64)…",
"signatureKeyId": "prod-v1"
}
Field by field:
| Field | What it holds |
|---|---|
tenantId, tenantDisplayName | Your organisation’s id, which ties the bundle to your organisation, and the name LayerT shows in its prompts |
bundleVersion | A number that goes up by one with every new bundle. A browser accepts only a higher number than the one it holds |
issuedAt, expiresAt | When the bundle was signed, and when it stops being current: 7 days later |
rules | Every rule: where it applies (site patterns), which fields it watches (CSS selectors), which values trigger it, what happens, the message people see, and what the audit log records |
classifiers | Named value tests that rules can share, such as “an address at our email domain” |
exceptions | Every live approved exception: the rule, the person’s directory id, the exact value that was approved, when it expires, who approved it and when, and the reason the person gave |
groups | For each directory group a rule refers to, the work email addresses of its active members |
user_attributes | Each active person’s own lists, such as the accounts they’re allowed to sign in with |
killSwitch | The emergency stop. When it’s on, the browser enforces no rules |
revoked_devices | The ids of browsers an admin has revoked |
critical_update | Marks an urgent version: an emergency stop, a rollback or a revocation. Today the extension doesn’t fetch these any sooner (see “Emergency stop and rollback” below) |
gateways | Only if you use gateways Early access: each gateway’s name, region, host name and port. No IP addresses |
signature, signatureKeyId | The Ed25519 signature over everything above, and which key made it |
What’s never inside
- Shared-account passwords, authenticator setup keys or one-time codes. When someone signs in to a shared account, the browser fetches a separate, single-use grant for that one sign-in and keeps it in memory only. It’s never part of a bundle and never saved to disk.
- Sign-in recipes. The steps LayerT follows to fill a vendor’s sign-in form travel with that grant, and are signature-checked separately.
- Device tokens, refresh credentials or signing keys. The bundle names the key that signed it. It never contains a key.
- What people type as they browse. Rules carry patterns, and what a rule matched goes to the audit log, separately. The only typed values a bundle carries are the approved values in live exceptions.
- Gateway IP addresses.
Inside, and personal
The life of a bundle
Publish
Every change that affects what browsers enforce produces a new bundle:
- an Owner or IT Admin publishes pending drafts (optionally after a second author reviews them),
- an approver grants access, which adds an exception,
- someone revokes an exception, or switches a rule on or off,
- an Owner or IT Admin revokes a browser, or restores one,
- the Owner pulls or releases the emergency stop,
- an Owner or IT Admin rolls back,
- your directory changes (people join, leave or change groups), picked up by an hourly job.
Each new bundle takes the next version number for your organisation under a lock, so two changes at once can’t produce the same version. The signed document is stored with a fingerprint of its contents and a link to the version before it.
Compile and sign
LayerT assembles the bundle, then writes it out in a canonical form: keys sorted, signature fields left out, so the same content always produces the same bytes. Those bytes are signed with Ed25519.
In production, the private signing key lives in Google Cloud KMS, configured for hardware-backed (HSM) protection, and it can’t be exported. LayerT’s servers send KMS the bytes and get a signature back. Production configuration refuses to start with a local key file. This is built, and it switches on with LayerT’s first production deploy. Until then, development and test builds sign with a local key, and a production build of the extension refuses to trust it.
The same key signs bundles for every organisation. It also signs two other things: the identity a browser is bound to when it enrols, and sign-in recipes. Each kind is written in its own format, so one can’t be passed off as another.
Several public keys can be built into the extension at once. To replace the signing key, LayerT ships an extension that trusts both the old and new keys, waits for it to roll out, switches signing to the new key, and removes the old one in a later release.
Deliver
The browser asks for the latest bundle:
- every 15 minutes,
- when the browser starts and when the extension is installed or updated,
- when the person moves to a new page (at most every few seconds),
- when someone presses Sync now on LayerT’s options page,
- and every 30 seconds while a page is showing the “Connectivity required” card.
It asks over HTTPS with its own device token, which says which organisation it belongs to. The request is conditional: if nothing has changed, LayerT answers “not modified” and nothing is downloaded. LayerT only ever serves your organisation’s latest bundle.
Verify in the browser
Before the browser uses a new bundle, it runs these checks, in this order, with the browser’s own Web Crypto implementation:
- Version. It must be higher than the version already stored. This stops an old bundle being replayed.
- Organisation. It must belong to the organisation this browser is bound to. The browser binds to its organisation when it accepts its first genuine bundle.
- Key. It must name a signing key built into the extension.
- Format. The signature must be a well-formed Ed25519 signature.
- Signature. The signature must verify over the canonical bytes.
- Expiry. It must not have expired, judged by the laptop’s clock.
If any check fails, the new bundle is thrown away and the browser keeps the one it had. Only a bundle that passes every check is saved.
Store on the device
The bundle is saved in Chrome’s extension storage inside the person’s browser profile, as plain JSON. LayerT doesn’t encrypt it: at rest, it’s protected by the laptop’s disk encryption. The same storage holds the browser’s enrolment (its device token and refresh credential) and any audit events not yet sent, which can include values people typed.
Enforce
On each page, LayerT’s content script asks the extension for the rules that match the page’s address, then acts on form submissions and pastes into the fields those rules name, before the site’s own code sees them. An exception applies only to a “block with a request” rule, and only when the rule, the person and the value all match exactly and the exception hasn’t expired. How rules behave in the page is on Signed policy and enforcement.
Expire and fail closed
A bundle lasts 7 days. An hourly job re-signs your organisation’s bundle, as a new, higher version with the same content, once 48 hours or less remain. LayerT’s monitoring flags any organisation whose newest bundle comes within 24 hours of expiring.
If a browser’s bundle does expire, because it couldn’t reach LayerT for days:
- on pages covered by a block or force sign-out rule, every form submission, and every paste into the rule’s fields, is stopped with a “Connectivity required” card that offers no way round it,
- warn and monitor rules keep working,
- the last bundle’s emergency stop and revoked-device list still apply,
- the card clears by itself within about 30 seconds of a fresh bundle arriving.
Emergency stop and rollback
The emergency stop is for when a rule is wrong and needs to be off everywhere now. Only the Owner can use it. It publishes a new bundle with enforcement switched off: every page then passes through, and audit logging carries on. Owners and IT Admins are told it happened. It switches enforcement off. There’s no switch that locks everything instead. A bundle that pulls or releases the stop lasts 24 hours rather than 7 days, and the hourly job keeps it re-signed.
A rollback publishes an earlier version’s rules, value tests and emergency-stop setting as a new, higher version. It keeps today’s exceptions (dropping any the restored rules no longer allow), groups, lists and revoked devices. Rolling back to a version from before an emergency stop lifts the stop, and the audit log records that. Because browsers only accept higher versions, no browser ever goes backwards.
Device takeover and breach
The signature and the expiry protect a bundle on the network and against the page. They weren’t designed to protect it from someone who already controls the laptop, and nothing running inside a browser can be. Here is each case: what an attacker can do, what they can’t, and what closes the gap.
Reading, changing and forging a bundle
- They can
- Anyone who can read the person’s browser profile can read the whole bundle as plain text. That’s the person, software running as them, an administrator, or anyone holding the disk of a laptop without disk encryption. They learn every rule, the email addresses in referenced groups, everyone’s allowlists, and every live exception with its value, approver and reason. The same storage holds the browser’s device credentials and any audit events not yet sent.
- They can’t
- Get shared-account passwords, authenticator setup keys or codes, or the signing key. None of them are there.
- What to do
- Full-disk encryption (FileVault, BitLocker) enforced by your MDM, and a short screen lock. Keep reasons for access requests plain. Bundles scoped to one person aren’t built.
- They can
- Someone who can write to the profile’s extension storage can change the stored bundle: switch the emergency stop on, delete rules, add exceptions, stop genuine updates from replacing it, or change which person the browser thinks it belongs to. The browser doesn’t check the signature again on what it reads back. Those who can write there are software running as the person (for example while Chrome is closed), an administrator, and anyone using developer tools on the extension where they’re allowed.
- They can’t
- Affect any other laptop, change anything on LayerT’s servers, or approve anything in the console. The change stays on that one browser.
- What to do
- No local administrator rights for staff. Block developer tools for extensions and Chrome’s developer mode through policy. Run endpoint protection, and use your MDM’s compliance checks. Checking the stored bundle’s signature on every read isn’t built, and it wouldn’t stop an administrator, who can replace the extension itself.
- They can
- Nothing useful without the signing key.
- They can’t
- Get a browser to accept a bundle they made or changed. It fails the signature check, and a bundle signed with any other key is refused because the key isn’t built into the extension.
- What to do
- Nothing extra. This is what the signature is for.
- They can
- Only in a narrow case: if the stored bundle is gone (for example, the browser re-enrolled or someone deleted it) and they control the connection, such as with an interception certificate an administrator installed, they could deliver a genuine, unexpired bundle from your organisation’s last 7 days.
- They can’t
- Replace a stored bundle with an older one. The version must go up. LayerT’s servers only ever serve the latest bundle.
- What to do
- No local administrator rights, and control over which root certificates your laptops trust.
- They can’t
- Get it accepted. Every bundle’s organisation id is covered by its signature, and the browser refuses one that isn’t its own. The same check stops a genuine bundle from another LayerT customer.
- What to do
- Nothing extra.
- They can
- Keep an expired bundle current by setting the laptop’s clock back, because expiry is judged by the laptop’s clock.
- They can’t
- Deliver an expired bundle to a browser with a correct clock. It’s refused on arrival, and once the stored one expires, blocking rules fail closed.
- What to do
- Managed laptops don’t let staff change the clock. Keep it that way, and keep time synchronisation on.
The network and the web page
- They can
- Keep the browser on its last genuine bundle for up to 7 days, which delays new rules, new revocations and the emergency stop.
- They can’t
- Make the bundle more permissive, or avoid failing closed. When it expires, blocking rules stop submissions on the pages they cover until the browser reconnects.
- What to do
- The console’s coverage view flags browsers that haven’t been in touch for 3 days. It shows the version LayerT last sent to each browser, which isn’t proof the browser accepted it, so treat a silent browser as one to follow up.
- They can
- Run its own scripts on its own pages, as any site can. Enforcement inside a page has limits of its own, listed on the Limits and open work page.
- They can’t
- Read or change the bundle or the extension’s storage, or send messages to the extension: it accepts none from websites. LayerT’s content script runs in an isolated world the page can’t reach, and its prompts are drawn in closed shadow roots.
- What to do
- Nothing extra for the bundle itself.
People and software on the laptop
- They can
- Everything in reading and changing the bundle. It can also copy the browser’s device credentials and act as that browser towards LayerT: download your organisation’s bundle, send audit events, and fetch sign-in grants for that person’s own active shared-account sessions on that device.
- They can’t
- Fetch grants for other people or other devices, sign a bundle, or change anything in the console.
- What to do
- Endpoint protection, application control and your MDM’s compliance checks. When you suspect it, revoke the browser in the console and suspend the person in your identity provider.
- They can
- Everything above, plus remove Chrome’s policies, uninstall or replace the extension, install a certificate that lets them read HTTPS traffic, and change the clock. A determined administrator on a laptop defeats LayerT on that laptop. No control running inside a browser can prevent that.
- They can’t
- Reach other laptops or LayerT’s signing key.
- What to do
- No local administrator rights for staff, and MDM with tamper protection. This is the most important control on this page.
- They can
- Whatever the person could do: use their access within your rules, and read the bundle from their profile without administrator rights.
- They can’t
- Do more than the person could, unless they also have administrator rights or can load modified extensions.
- What to do
- Revoke the browser in the console, suspend the person in your identity provider (their exceptions drop out of the next bundle), and lock or wipe the laptop through your MDM. A short screen lock keeps this case rare.
- They can’t
- Read or change anything in the browser profile. The device token stops working within an hour. The refresh credential lasts up to 30 days, and stops working as soon as you revoke the browser.
- What to do
- Revoke the browser anyway. Without disk encryption, whoever holds the disk can read everything in the profile, including the refresh credential, so revoke promptly.
- They can
- On a browser where LayerT wasn’t force-installed, a person can switch it off or remove it. Other browsers, and Chrome profiles your MDM doesn’t manage, are outside LayerT altogether.
- They can’t
- Switch off or remove a force-installed extension through Chrome’s settings.
- What to do
- Force-install LayerT with your MDM. LayerT’s Chrome policy templates force-install and pin it, and turn off Incognito, Guest mode and Chrome’s own password manager. The signed extension package for force-install is built and ships with LayerT’s first production release. We also recommend setting Chrome’s developer-tools and developer-mode policies so nobody can load a modified copy. The console’s coverage view shows browsers where LayerT can be switched off, browsers that have gone silent, and browsers where it was removed.
Enrolment, revocation and LayerT itself
- They can
- Act as that browser towards LayerT until the credential stops working: download the organisation’s bundle, send audit events, and fetch grants for that person’s own active sessions on that device. The device token lasts an hour. The refresh credential lasts up to 30 days and changes each time it’s used, so a copy and the real browser can’t both keep going: whichever refreshes second is cut off.
- They can’t
- Enrol a browser as somebody else. The identity a browser is bound to is signed by LayerT and checked when it enrols.
- What to do
- Revoke the browser. Disk encryption keeps the credentials off a stolen disk.
- They can
- Keep working as an ordinary browser. When you revoke it, LayerT publishes a bundle listing it. On its next sync, it stops enforcing rules and stops reporting. Its current device token works until it expires, within an hour, and then its refresh is refused and it’s unenrolled.
- They can’t
- Receive policy, sign in to shared accounts or report to LayerT once it’s cut off.
- What to do
- Revoking cuts a browser off from LayerT. It doesn’t lock the browser, and a revoked browser enforces nothing. To stop a person, suspend them in your identity provider as well, and lock or wipe the laptop through your MDM.
- They can
- An attacker who controls LayerT’s application servers can ask Cloud KMS to sign, for as long as they keep that access. They could publish a permissive or hostile bundle for any organisation, and browsers would accept it. Someone with only the database can read every organisation’s bundles, which aren’t encrypted there, and can stop serving them.
- They can’t
- Copy the signing key out of Cloud KMS. With only the database, they can’t sign anything, and browsers refuse older versions, so withholding bundles leads to failing closed, not to old rules.
- What to do
- On LayerT’s side: only LayerT’s own services may use the key, and Cloud KMS logs every signing request. Removing the attacker’s access ends the window. Bundles already accepted stay until they’re replaced or expire, within 7 days. The same key signs for every organisation, so this case affects all of them.
- They can
- In production the key can’t be exported, so this means misusing it through Cloud KMS, as above. If the key ever had to be replaced, anyone who could sign with it and deliver a bundle could make any browser accept that bundle until the replacement reached them.
- They can’t
- Use the key once LayerT has shipped an extension release without it.
- What to do
- Replacing the key needs a new extension release with the old key removed. Chrome usually rolls an update out within hours, or when the browser restarts.
What your IT team should set up
The bundle is only as trustworthy as the laptop it’s stored on. These are standard device-management controls, and LayerT relies on them:
- Full-disk encryption, enforced by your MDM, and a short screen lock.
- No local administrator rights for staff.
- Force-install LayerT through your MDM, and use LayerT’s Chrome policy templates.
- Block extension developer tools and developer mode through Chrome policy.
- Keep other browsers and unmanaged Chrome profiles off work laptops, or accept that LayerT doesn’t see them.
- Keep the clock synchronised and out of staff’s control.
- Endpoint protection that can spot software tampering with browser profiles.
- A leaver or lost-laptop routine that does three things together: revoke the browser in LayerT, suspend the person in your identity provider, and lock or wipe the laptop.
- Watch the coverage view for browsers that have gone silent or can be switched off.
The limits, in one list
- A bundle is checked when it arrives, not each time it’s read. Anyone who can write to the browser profile’s extension storage, or has administrator rights, can defeat enforcement on that laptop.
- Every browser holds the whole organisation’s bundle, including other people’s allowlists and every live exception with its value, approver and reason. Bundles scoped to one person aren’t built.
- The bundle is stored as plain JSON. At rest, only the laptop’s disk encryption protects it.
- Expiry is judged by the laptop’s clock.
- Urgent bundles (emergency stop, rollback, revocation) arrive on the next page change or within 15 minutes, like any other.
- Revoking a browser stops it enforcing and reporting. It doesn’t lock it.
- The console shows the version LayerT last sent a browser, not proof the browser accepted it.
- One signing key signs for every organisation. Replacing it needs an extension release.
- Cloud KMS signing is built and switches on with LayerT’s first production deploy. Today’s development builds sign with a local key.
Related: Signed policy and enforcement · Limits and open work · Fail-closed by design