PRODUCT

From policy to proof.

Define policies centrally. Enforce them beside every service. Sync the identity data you already have. Trace every decision back to the rule that produced it.

POLICY Cedar DECISION PATH in-pod sidecar PROTOCOL gRPC + REST ENTITY SYNC SCIM 2.0

Central control plane. Local decision plane.

Two paths, deliberately separate. The hot path — every authorization check — runs entirely in your infrastructure and never leaves the pod. Everything that crosses to ZStrike Cloud — policy sync, entity sync, logging — is asynchronous, out of the request path. ZStrike hosts the control plane: policy authoring, versions, and the audit store.

One local check. No network hop. The control plane is not in the request path.

ARCHITECTURE, LIVEINTERACTIVE
DECISIONS STAY LOCAL REQUEST PATH BACKGROUND

YOUR INFRASTRUCTURE · REQUEST PATH

READY ON CACHED STATE
1 YOUR SERVICE SEND CHECK
2 ZSTRIKE SIDECAR LOCAL POLICY + ENTITY CACHE EVALUATE LOCALLY
3 ALLOW / DENY RETURN TO SERVICE

LOCALHOST · NO NETWORK HOP · LAST-SYNCED STATE

TRUST BOUNDARY
BACKGROUND CHANNELSASYNCHRONOUS · OUT OF THE REQUEST PATH
EVERY SIDECAR CACHE CONTROL PLANE · POLICY + ENTITIES
ENTRA ID · OKTA · ANY IDP · SYSTEMS OF RECORD · SCIM 2.0 / ENTITY AGENT
EVERY DECISION AUDIT STORE · POLICY NAME + VERSION

RESILIENCE BY DESIGN. The sidecar decides from local state, so a cloud outage does not become your application outage.

POLICY LANGUAGE
Cedar — open policy language, deterministic evaluation
DECISION PATH
in-pod sidecar over localhost · gRPC or REST
LATENCY
sub-10ms design target; no network hop in the request path
SDK / PROTOCOL
TypeScript/JavaScript, Python, Java, Ruby, Rust, Go, Elixir · plain gRPC + REST from any other language
ENTITY SYNC
Entra ID, Okta, or any IdP over SCIM 2.0 (beta) · HR systems and databases via the entity agent (REST)
DEPLOYMENT
sidecar container beside each service
OUTAGE BEHAVIOR
decides on last-synced policy; fail mode configurable per resource
AUDIT
every decision recorded with the matched policies, by name and version

Rules in one language, in one place.

Access rules are Cedar policies — short, reviewable, versioned. Write them by hand, or describe the intent in plain English and let AI draft the rule, checked against your description before it saves. Every change is a version; any version rolls back in one click.

POLICY.CEDARCARE-TEAM-ONLY · V14
// care-team-only · v14

permit (
  principal in CarePortal::CareTeam,
  action == Action::"chart.view",
  resource
) when {
  resource.careTeam == principal.careTeam
};

Catch the wrong decision before production.

Run any request against your real schema and entities before it ships. The response names the determining policies — the deny you didn’t expect surfaces here, with the rule that caused it, not in an incident.

SIMULATORSAME ENGINE · YOUR SCHEMA
// simulator — same engine, your schema + entities

request {
  "principal": "CarePortal::Nurse::\"k.moreno\"",
  "action":    "CarePortal::Action::\"chart.view\"",
  "resource":  "CarePortal::Chart::\"pt-88213\"",
  "context":   { "shift": "night" }
}

// decision — with the policies that produced it
response {
  "decision": "DENY",
  "determining_policies": ["care-team-only@v14"],
  "errors": []
}

Know the blast radius before you merge.

Every draft is checked against the live version two ways: a semantic diff that proves when the two can disagree, and a replay of your recent production decisions. Flips are named — who, what, which direction — before the change ships.

SEMANTIC DIFF · DECISION REPLAY

IMPACT ANALYSISCARE-TEAM-ONLY · V14 → V15 (DRAFT)
2 FLIPS 12,400 DECISIONS REPLAYED · LAST 30 DAYS
CHANGEpermit narrowed — adds resource.ward == principal.ward PROOFversions can only disagree when a caregiver is off-ward
FLIPS2 × ALLOW → DENY WHONurse::"d.kim" · Doctor::"a.osei" — chart.view, off-ward VERDICTno unintended grants — flips match the stated intent

One call. One container.

One check per request — six SDKs, or plain gRPC/REST from any language. Deployment is one container in the pod spec, and it keeps deciding on last-synced policy if the control plane is unreachable.

Decision metrics and traces integrate with OpenTelemetry, so denials show up where your engineers already look.

SDKS TypeScript Python Java Ruby Rust Go Elixir

SERVICE.TSTHE WHOLE INTEGRATION
// service.ts — the whole integration

const decision = await zstrike.check({
  principal: 'User::"j.willis"',
  action:    'Action::"chart.edit"',
  resource:  'Chart::"pt-71002"',
});

if (!decision.allowed) throw new Forbidden(decision.reason);
POD SPECADD ONE CONTAINER
# your service's pod — add one container
containers:
  - name: your-service
    image: registry.example.com/care-portal:1.42.0
  - name: zstrike-pdp
    image: zstrike/pdp-sidecar:<version>
    ports:
      - containerPort: 50051   # gRPC · localhost only

Your directory, already there.

Principals, groups, and attributes sync from Entra ID, Okta, or any identity provider over SCIM 2.0 or REST — alongside databases and APIs. Every sidecar keeps a local copy, so decisions don't wait on a directory lookup.

ENTRA ID · OKTA · ANY IDP · REST · SCIM 2.0 BETA

ENTITY SYNCLOCAL REPLICAS
IDENTITY PROVIDER HR SYSTEM DATABASE
ENTITY STORE PRINCIPALS · RESOURCES · ATTRS
SIDECAR · US-EAST SIDECAR · EU-WEST SIDECAR · ON-PREM

Every decision explains itself.

Granted or denied, every decision lands in the audit trail with its full context — who asked, what they tried, which resource — and the exact policies, by name and version, that produced the answer. “Why could she open that chart?” is one query, not an investigation. And when access is denied, engineers see which rule said no — not a mystery 403.

Because policies are versioned, the trail holds up over time: a decision from last quarter traces to the policy text that was live at that moment, not today’s edit.

WHO · WHAT · WHY ON EVERY RECORD

A DECISION RECORD, AS LOGGEDIMMUTABLE
✗ DENIED 0.9MS · 2026-07-10 16:42:11 UTC
PRINCIPALNurse::"k.moreno" ACTIONchart.view RESOURCEChart::"pt-88213" CONTEXTshift="night" · on_care_team=false
POLICYcare-team-only · v14 REASONno permit matched — principal is outside the chart's care team AUDIT IDaud_8997

Built by the people who got paged for it.

ZStrike was founded by engineers who ran access control at scale — and watched every company rebuild the same brittle permission code from scratch. We believe who-can-do-what is infrastructure, not application logic: one governed platform, tested, enforced, and logged.

VIEW OPEN ROLES →

See it on your own access rules.

A 30-minute briefing with our engineering team — your use cases, live.

BOOK AN ENGINEERING BRIEFING