ZDDC/zddc/internal/zddc/embedded_neutral_test.go
2026-06-11 13:32:31 -05:00

45 lines
2 KiB
Go

package zddc
import "testing"
// TestEmbeddedDefaults_LosslessUnderSerialization pins the invariant that
// makes it safe for policy.SerializableChain to drop PolicyChain.Embedded on
// the wire (and for policy.InternalDecider.Allow to reconstruct a chain from
// AllowInput without it).
//
// The decision path consults chain.Embedded at two sites:
// - worm.go (WormZoneGrant): folds in a top-level chain.Embedded.Worm.
// - roles.go (lookupRoleMembers / pathRoles): reads chain.Embedded.Roles.
//
// Today both are no-ops only because the baked-in baseline (EmbeddedDefaults,
// the root of every cascade — internal/zddc/defaults/.zddc) declares no
// top-level `worm:` and no role members (WORM is declared via the `paths:`
// tree, which lands in chain.Levels, not chain.Embedded). If a future default
// adds either, those contributions would be SILENTLY ignored by an external
// OPA (it never receives Embedded) and by the InternalDecider over a
// serialized chain — an authz divergence with no error. This test fails loudly
// at that moment so the change is paired with serializing PolicyChain.Embedded
// (one field on SerializableChain) before it ships.
func TestEmbeddedDefaults_LosslessUnderSerialization(t *testing.T) {
e, err := EmbeddedDefaults()
if err != nil {
t.Fatalf("EmbeddedDefaults: %v", err)
}
if e.Worm != nil {
t.Errorf("embedded baseline declares a top-level worm: %v — it is read at "+
"decision time (WormZoneGrant) but dropped by policy.SerializableChain, "+
"so external OPA and the reconstructed InternalDecider chain would "+
"silently ignore it. Declare WORM via paths: (→ chain.Levels) or "+
"serialize PolicyChain.Embedded.", e.Worm)
}
for name, role := range e.Roles {
if len(role.Members) > 0 {
t.Errorf("embedded baseline role %q has members %v — read at decision "+
"time (chain.Embedded.Roles in roles.go) but dropped by "+
"policy.SerializableChain. Keep embedded roles member-less or "+
"serialize PolicyChain.Embedded.", name, role.Members)
}
}
}