From 2140e56aa5bc3878602f05effb62af440cc54a02 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Tue, 3 Nov 2026 22:38:56 +0000 Subject: [PATCH] fix(addons): keep grants made under a deployment blanket as the install's own The document validator requires a blanket grant to name a revision of the switch in the document. A deployment-fixed mode is never written there, so its grants have no revision to name. Record them as the grant of the install or upgrade that made them; the audit line still carries the blanket tag. Assisted-by: Claude:claude-sonnet-5-5 go --- core/application/addon_hostgrants.go | 9 +++++++-- core/services/addons/hostgrants/document.go | 4 +--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/application/addon_hostgrants.go b/core/application/addon_hostgrants.go index b5ee04275a..20faf5c0f9 100644 --- a/core/application/addon_hostgrants.go +++ b/core/application/addon_hostgrants.go @@ -363,7 +363,12 @@ func (g *addonHostGrants) Stage(ctx context.Context, s addons.GrantStage) error } blanketMode = m[1] blanketRev, _ = strconv.ParseUint(m[2], 10, 64) - source = hostgrants.SourceBlanket + // Revision 0 means the switch was never set in the document: the + // deployment fixed the mode. Those grants stay the install's own, since + // a blanket grant must name a revision of the document. + if blanketRev != 0 { + source = hostgrants.SourceBlanket + } } for range 3 { snap, err := g.store.Snapshot(ctx) @@ -414,7 +419,7 @@ func (g *addonHostGrants) Stage(ctx context.Context, s addons.GrantStage) error patch.Addons = map[string]*hostgrants.AddonGrants{s.AddonID: &entry} ev := hostgrants.AuditGrant tag := "" - if source == hostgrants.SourceBlanket { + if s.Blanket != "" { ev, tag = hostgrants.AuditBlanketGrant, blanketMode+"@rev"+strconv.FormatUint(blanketRev, 10) } _, err = g.store.UpdateAudited(ctx, patch, snap.Revision, "stage-"+s.OperationID+"-r"+strconv.FormatUint(snap.Revision, 10), func(n hostgrants.Snapshot) error { diff --git a/core/services/addons/hostgrants/document.go b/core/services/addons/hostgrants/document.go index 0a0451bba0..6a5ba7522f 100644 --- a/core/services/addons/hostgrants/document.go +++ b/core/services/addons/hostgrants/document.go @@ -357,9 +357,7 @@ func validate(s Snapshot) error { if !validText(op.By) || !validText(op.Version) || !validTime(op.At) { return invalid("metadata of %q for %q", op.Name, id) } - // Revision 0 on a blanket grant means the deployment fixed the mode and - // the document never held it. - if (op.Source != SourceBlanket && op.BlanketRevision != 0) || op.BlanketRevision > s.Blanket.Revision { + if (op.Source == SourceBlanket) != (op.BlanketRevision != 0) || op.BlanketRevision > s.Blanket.Revision { return invalid("blanket revision of %q for %q", op.Name, id) } }