Skip to content

Quoted policy conditions with commas: load works, exact batch delete does not remove all rules #1733

@Ravichandran-T-S

Description

@Ravichandran-T-S

Summary

We use Casbin with 6-field p policies where the last field is a condition expression (quoted in CSV). Policies load correctly, but on exact batch delete (RemovePolicies) not all matching rules are removed — we see partial deletes when the condition text contains commas.

Environment

  • github.com/casbin/casbin/v2 v2.77.x
  • Large policy set (~350k p rules)
  • Incremental deletes via RemovePolicies with full 6-field rules (including condition)

What we see

  • Delete event: 14 policies (user, tenant, resource, access, role, condition)
  • Requested: batch delete of 14 exact-match rules
  • Result: only 9 removed from persisted policy data
  • The 5 not removed all have commas inside the condition string
  • Rules with conditions that have no commas (e.g. only && between matchers) delete as expected

When commas appear in conditions (valid ABAC expressions)

Commas are not only in in (...) lists. They can also appear in other matchers, for example:

  • List / enum checks:
    r.attrs.ExceptionAllowed in ('( true','false )')
  • Comma-separated allowed values in a matcher:
    r.attrs.Center =~ '^center1,center2,center3$'
    or similar patterns where the regex/value side lists multiple centers/streams
  • Multiple constraints in one expression:
    (r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$' && ...)

So the condition field is a free-form expression, not a simple scalar — CSV must treat the whole quoted field as one token, including any commas inside it.

Example — removed successfully (no commas in condition)

csv p, aqDsp4Rqe0PqHDJMZDI4P, aUSsW8GI03dyQ0AIFVn92, RESOURCE_STUDENT_MANAGEMENT, ACCESS_LEVEL_FULL, e0bmnxKv9L5AQGUwBtHFN, "(r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$')"

Example - Policies we have trouble removing (commas inside quoted condition)


p, aqDsp4Rqe0PqHDJMZDI4P, aUSsW8GI03dyQ0AIFVn92, RESOURCE_SUPPORT_ID_CARD, ACCESS_LEVEL_FULL, e0bmnxKv9L5AQGUwBtHFN, "(r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$' && r.attrs.CourseType =~ '^.*$' && r.attrs.ExceptionAllowed in ('( true','false )') && r.attrs.DiscountPercent < 100)"

p, aqDsp4Rqe0PqHDJMZDI4P, aUSsW8GI03dyQ0AIFVn92, RESOURCE_SUPPORT_STREAM_CHANGE, ACCESS_LEVEL_FULL, e0bmnxKv9L5AQGUwBtHFN, "(r.attrs.ExceptionAllowed in ('( true','false )') && r.attrs.DiscountPercent < 100 && r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$' && r.attrs.CourseType =~ '^.*$')"

p, aqDsp4Rqe0PqHDJMZDI4P, aUSsW8GI03dyQ0AIFVn92, RESOURCE_SUPPORT_BATCH_CHANGE, ACCESS_LEVEL_FULL, e0bmnxKv9L5AQGUwBtHFN, "(r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$' && r.attrs.CourseType =~ '^.*$' && r.attrs.ExceptionAllowed in ('( true','false )') && r.attrs.DiscountPercent < 100)"

p, aqDsp4Rqe0PqHDJMZDI4P, aUSsW8GI03dyQ0AIFVn92, RESOURCE_SUPPORT_PII_DATA, ACCESS_LEVEL_READ, e0bmnxKv9L5AQGUwBtHFN, "(r.attrs.Center =~ '^.*$' && r.attrs.Stream =~ '^.*$' && r.attrs.CourseType =~ '^.*$' && r.attrs.ExceptionAllowed in ('( true','false )'))"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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