Skip to content

Cedar enforcement-point detection rules + ruleset gaps surfaced by Cedar-adoption corpus #73

@boorad

Description

@boorad

Follow-up from #72 (Cedar engine support). Splits cleanly from Phase A emission and from Phase B abstraction work in docs/CEDAR_SUPPORT.md, so it ships on its own.

Motivation

When zift scans a Cedar-adopting codebase, summary.enforcement_points reads 0 even for projects that have fully externalized authz to Cedar. We have rules/go/opa-rego-eval.toml for OPA, but no Cedar parallel in any language. Result: the externalized_pct metric — the headline "how much have you migrated?" number — is misleading on the exact projects most likely to scan with --engine cedar.

Scope

Add Cedar enforcement-point detection rules across the supported languages, covering the three real-world shapes of Cedar adoption.

Variant 1 — raw Cedar library

Direct use of the Cedar engine in-process.

Language Crate / module Sentinel calls
Rust cedar-policy PolicySet::from_str, Authorizer::is_authorized
Go github.com/cedar-policy/cedar-go cedar.NewPolicySetFromBytes, ps.IsAuthorized
Java com.cedarpolicy:cedar-java AuthorizationEngine.isAuthorized

Variant 2 — AWS Verified Permissions managed service

Language SDK Sentinel calls
JS/TS @aws-sdk/client-verifiedpermissions VerifiedPermissions.isAuthorized, isAuthorizedWithToken
Python boto3 verifiedpermissions client client.is_authorized, is_authorized_with_token
Java software.amazon.awssdk:verifiedpermissions VerifiedPermissionsClient.isAuthorized
Go aws-sdk-go-v2/service/verifiedpermissions IsAuthorized, IsAuthorizedWithToken
C# AWSSDK.VerifiedPermissions IsAuthorizedAsync

Variant 3 — Cedar middleware libraries

Language Library Sentinel pattern
JS/TS Express @cedar-policy/authorization-for-expressjs app.use(authorizationMiddleware(...))

Rust skipped — zift doesn't scan Rust today.

Real-world scan corpus (calibration data)

Already cloned to /tmp/cedar-scan/ for local validation:

Repo Language zift findings Cedar enforcement variant Notes
cedar-policy/cedar-access-control-for-k8s Go (53 files) 0 Variant 1 (cedar-go) Real K8s webhook. 0 inline checks — fully externalized. Should report externalized_pct: 100%, currently reports 0%.
cedar-policy/cedar-examples/tinytodo-go Go (35 files) 0 Variant 1 (cedar-go) Canonical sample. 0 inline checks. Same gap.
cedar-policy/authorization-for-expressjs JS 4 Variant 3 (middleware) Found 4 middleware findings; should also recognize the library as an enforcement point.
permitio/opal-cedar JS 4 Mixed 4 medium-confidence Express route handlers; uses OPAL+Cedar agent.
aws-samples/sample-app-migrate-access-rbac-to-pbac-with-verified-permissions JS (Next.js + Lambda) 0 in both halves Variant 2 (Verified Permissions) Mid-migration target. Repo ships rbac-pet-store-app and pbac-pet-store-app side by side. The pbac side calls verifiedpermissions.isAuthorizedWithToken — should be detected.

Ruleset gap surfaced (separate from the enforcement-point work)

The aws-samples rbac-pet-store-app/backend/cognito-authorizer.js contains this textbook embedded RBAC, which zift currently misses:

```js
const userGroups = parsedToken['cognito:groups'] || [];
if (userGroups.includes('manager')) {
isAllowed = true;
} else if (userGroups.includes('customer')) {
isAllowed = actionId.startsWith('get ');
}
```

rules/typescript/role-includes-check.toml requires a two-level member expression (user.roles.includes(...)) and matches the inner property name against ^(roles|userRoles)$. A bare-identifier collection (userGroups.includes(...)) doesn't match either constraint. AWS Cognito groups are common enough — a sister rule for single-level identifier collections (groups, userGroups, roles, permissions) would catch the petstore migration sample and likely many others. File this as a follow-up rule, separate from the enforcement-point work above.

Acceptance criteria

  • rules/{go,java,javascript,python,csharp}/cedar-eval.toml — Variant 1 (raw library) detection where applicable per language
  • rules/{javascript,python,java,go,csharp}/aws-verified-permissions.toml — Variant 2 detection
  • rules/javascript/cedar-express-middleware.toml — Variant 3 detection
  • Re-scan the corpus above; externalized_pct should be 100% for tinytodo-go and the K8s project
  • (Stretch) enforcement_points count matches the number of isAuthorized* call sites, not just file count

Out of scope (track separately)

  • Rust ruleset (zift doesn't scan Rust today)
  • The userGroups.includes ruleset gap above — own rule, own PR
  • Cedar partial-evaluation patterns (the K8s project's planned Rust rewrite uses these — not yet stable)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions