From 2bd6201f753143040eb1a86f3eea1d1d7be804e8 Mon Sep 17 00:00:00 2001 From: Aly Raffauf Date: Sun, 9 Aug 2026 20:26:11 -0400 Subject: [PATCH] refactor: centralize secret-mode policy and portable overlap --- internal/deployment/file.go | 23 +++++++++++++++++++++++ internal/deployment/scope.go | 12 ++++++++++++ internal/pathsafe/protected.go | 4 ++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/internal/deployment/file.go b/internal/deployment/file.go index 5b15b97..5f029c3 100644 --- a/internal/deployment/file.go +++ b/internal/deployment/file.go @@ -73,3 +73,26 @@ func validateFile(file ManagedFile) error { } return nil } + +// ExecutableBitMask is the POSIX executable-bit mask (PLAN.md Section 7.1). +// Source and target modes preserve read/write bits and reconcile only these bits. +const ExecutableBitMask fs.FileMode = 0o111 + +// SecretMode and SecretExecutableMode are the exact modes enforced on every +// secret target (Section 4.5): non-executable secrets are 0600, executable +// secrets are 0700. These are POSIX guarantees only. +const ( + SecretMode fs.FileMode = 0o600 + SecretExecutableMode fs.FileMode = 0o700 +) + +// SecretTargetMode returns the exact mode a secret target must hold: SecretMode, +// or SecretExecutableMode when any executable bit is set (Section 4.5). This is +// the single source of truth for secret-target mode policy; upper layers +// (filesystem, reconcile) delegate here so the rule cannot drift between them. +func SecretTargetMode(sourceExec fs.FileMode) fs.FileMode { + if sourceExec&ExecutableBitMask != 0 { + return SecretExecutableMode + } + return SecretMode +} diff --git a/internal/deployment/scope.go b/internal/deployment/scope.go index 793822f..39d5183 100644 --- a/internal/deployment/scope.go +++ b/internal/deployment/scope.go @@ -47,3 +47,15 @@ func (l Layer) Valid() bool { } return false } + +// InactiveOn reports whether layer targets a platform other than platform. The +// base layer applies on every runtime so it is never inactive; a named platform +// layer is inactive when it does not equal the runtime platform. This replaces +// ad-hoc string comparisons so the file-layer "base" and alias-layer "all" +// rules cannot be conflated. +func (l Layer) InactiveOn(platform string) bool { + if l == LayerBase { + return false + } + return string(l) != platform +} diff --git a/internal/pathsafe/protected.go b/internal/pathsafe/protected.go index cf35d51..8960e93 100644 --- a/internal/pathsafe/protected.go +++ b/internal/pathsafe/protected.go @@ -17,7 +17,7 @@ func ProtectedTree(target, protected string) bool { targetSegments := segmentsOf(target) protectedSegments := segmentsOf(protected) return nativeOverlap(targetSegments, protectedSegments) || - portableOverlap(targetSegments, protectedSegments) + PortableOverlap(targetSegments, protectedSegments) } // Equal reports whether two canonical absolute paths name the same native @@ -43,7 +43,7 @@ func nativeOverlap(target, protected []string) bool { // portableOverlap reports a collision when the two segment lists are portably // equivalent or one is a strict portable prefix of the other. -func portableOverlap(target, protected []string) bool { +func PortableOverlap(target, protected []string) bool { return PathsEquivalent(target, protected) || IsParentEquivalent(protected, target) || IsParentEquivalent(target, protected) -- 2.51.2