07 / 12Prism Systems · Cloud-Native & Developer Infrastructure
Zero-trust access that checks every request, not just the login
A zero-trust network access proxy: a readable policy language with deny-overrides, device posture scoring, device-bound HS256 session tokens with key rotation, step-up MFA, continuous verification that revokes sessions when posture drops, an anycast PoP mesh with outbound-only app connectors, and a hash-chained audit log.
Six users, five PoPs, six private apps
Every dot is a request decided at the nearest PoP. Compromise a laptop and watch its session get revoked, log in from a sanctioned country, kill a PoP to see traffic re-route, rotate keys, or edit the policy live and apply it.
What's inside the engine
Real algorithms, not mock-ups. The simulator above runs the exact same code you import.
Policy language
Declare apps with tags, then allow / deny rules with targets (*, names, tag:prod) and conditions using and or not == != < >= in matches, durations like 15m, and require mfa within 15m.
Deny overrides, default deny
All matching deny rules are checked first, then the first matching allow wins. Anything else is denied, with the failed conditions of every candidate rule in the reason.
Explainable decisions
The evaluator records each comparison with the value it saw, so every decision shows which rule fired and why (device.score >= 80 ← 77).
Device posture
Weighted checks for disk encryption, EDR, patch age (with partial credit), jailbreak, firewall, screen lock and MDM produce a 0–100 score and a trusted / limited / untrusted tier.
Device-bound tokens
HS256 tokens carry a cnf.dev thumbprint, audience and expiry, use constant-time signature checks and reject alg: none. Key rotation keeps the previous key for a grace period.
Continuous verification
Posture is re-evaluated on every request. If a device drops below the floor its sessions are revoked immediately, not at the next login.
PoP mesh
Users anycast to the nearest healthy PoP, traffic crosses a private backbone (Dijkstra on RTT), and app connectors dial out to two PoPs, so private networks need no inbound ports.
Hash-chained audit
Every login, decision, step-up and revocation commits to the previous entry with SHA-256. Editing any entry breaks the chain at that sequence number.
From request to result
Authenticate
The IdP verifies the user. The broker scores the device and refuses login below the posture floor, then signs a token bound to that device.
Verify
Each request presents the token and device id. Signature, audience, expiry, key id and device binding are checked, and the session must still exist.
Re-check posture
Device signals are scored again. A compromised device loses its sessions on its next request.
Decide
The policy sees user, device, geo, time and MFA age. Deny rules first, then allows, then default deny. Step-up rules return a challenge instead of an allow.
Route + audit
Allowed traffic goes ingress PoP → backbone → egress PoP → connector → app with identity headers. Every outcome lands in the audit chain.
System design
Every box is a module in src/. Data flows left to right.
Ship it in your own stack
Zero dependencies. Works in Node.js 18+ and modern browsers.
import { Broker, Mesh, Policy, posture } from "prism-ztna";
const policy = `
app prod-db host "10.0.4.12:5432" tags [prod]
deny "geo" * when geo.country in ["KP", "IR"]
deny "posture" tag:prod when device.tier != "trusted"
allow "sre" tag:prod when "sre" in user.groups and device.score >= 80 require mfa within 15m`;
const zt = new Broker({ policy, directory, mesh: new Mesh({ connectors }) });
const { token, sid } = zt.login("riya", "mbp-riya"); // posture-checked, device-bound token
const d = zt.access(token, "prod-db", { deviceId: "mbp-riya" });
d.effect; // "allow" | "deny" | "challenge"
d.rule; // "sre"
d.trace; // every rule and comparison, with the values it saw
d.route; // { path: ["bom"], rtt: 1.1 }
zt.stepUp(sid); // after WebAuthn / TOTP
zt.revokeDevice("mbp-riya", "lost"); // kill every session on a device
zt.verifyAudit(); // { ok: true, entries, head }
new Policy(policy).lint(); // unknown targets, unreachable apps, unconditional rules$ npx github:krishyaa06/prism-ztna demo
$ npx github:krishyaa06/prism-ztna lint examples/policy.ztna
$ npx github:krishyaa06/prism-ztna eval --user arjun --app prod-db
$ npx github:krishyaa06/prism-ztna posture
$ npx github:krishyaa06/prism-ztna route --user riya --app gitlab --down fra
$ npx github:krishyaa06/prism-ztna serve --port 8080# use the CLI without installing
$ npx github:krishyaa06/prism-ztna --help
# or add the engine to your project
$ npm install github:krishyaa06/prism-ztna
# run the simulator locally
$ git clone https://github.com/krishyaa06/prism-ztna.git && cd prism-ztna
$ npx serve . # then open http://localhost:3000