Skip to content

GuardSQL v0.4.0

Released: 2026-10-23

This is a security release. A policy compiled from an authorization decision that allows nothing now denies every query instead of leaving the query unrestricted, and joined entities are checked against the entity allowlist.

Security

  • authz.PolicyFromDecision copied a decision's allowlists into a Policy, where an empty AllowedEntities or Fields means "no restriction". A decision that granted a principal nothing therefore produced a policy that allowed every entity and field the schema exposes. The policy now sets StrictAllowlists, so nothing granted means nothing allowed.
  • CheckPolicy checked only the FROM entity against AllowedEntities, so a query could join an entity the policy did not allow. Joined entities are now checked the same way. CheckAnalysisPolicy already covered them.

Added

  • Policy.StrictAllowlists makes AllowedEntities and Fields strict allowlists even when empty: an unlisted entity is refused, and an entity without a Fields entry has no usable fields.

Upgrade Notes

  • Policies built with authz.PolicyFromDecision are strict. A decision must list every entity, and the fields of each, that the principal may use.
  • A Policy built by hand keeps the previous meaning of empty allowlists; set StrictAllowlists when it comes from an authorization result.
  • Queries joining an entity outside a non-empty AllowedEntities are now refused by CheckPolicy.

Documentation

  • The policy guide explains empty allowlists and StrictAllowlists.
  • The authorization guide points to SystemForge's authzguardsql adapter.