feat(dev): propagate INSECURE_INTERNAL=1 to compose services Maestro starts in dev mode

This commit is contained in:
2026-08-16 15:08:18 +01:00
parent 420768318c
commit e569466dc3
2 changed files with 85 additions and 0 deletions
+27
View File
@@ -18,6 +18,7 @@ package containers
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -69,6 +70,15 @@ func StartContainer(ctx context.Context, item types.RegistryContainer) error {
return err return err
} }
// Dev escape hatch (M2 §2): when Maestro itself runs with
// INSECURE_INTERNAL=1, start services the dev way too — propagate the flag
// into the compose services so infra auto-started by Maestro (e.g. a
// resurrected dcntrlized-auth, see infra.go) keeps a plaintext listener
// instead of coming up as mTLS against the plaintext dev fleet.
if os.Getenv("INSECURE_INTERNAL") == "1" {
propagateInsecureInternal(project)
}
// The compose file may reference the image by a short name (e.g. // The compose file may reference the image by a short name (e.g.
// "testservice") while install pulled it under its full registry reference. // "testservice") while install pulled it under its full registry reference.
// Make sure those short names exist so Up() can find them. // Make sure those short names exist so Up() can find them.
@@ -161,6 +171,23 @@ func injectServiceIdentity(ctx context.Context, project *composetypes.Project, s
return nil return nil
} }
// propagateInsecureInternal injects INSECURE_INTERNAL=1 into every non-oneoff
// compose service when Maestro itself runs in dev mode (the same flag the dev
// debug composes set). Mirroring those composes keeps peer edges plaintext, so
// a service auto-installed and started by Maestro (e.g. a resurrected
// dcntrlized-auth) matches the compose-managed plaintext dev fleet instead of
// binding an mTLS listener the satellites cannot reach.
func propagateInsecureInternal(project *composetypes.Project) {
for name, s := range project.Services {
if isOneoff(s) {
continue
}
s.Environment = mergeEnv(s.Environment, map[string]string{"INSECURE_INTERNAL": "1"})
project.Services[name] = s
}
logger.Info("Dev mode (INSECURE_INTERNAL=1): propagated plaintext escape hatch to %d service(s)", len(project.Services))
}
// pinAuthFingerprint returns the service's pinned auth fingerprint, fetching // pinAuthFingerprint returns the service's pinned auth fingerprint, fetching
// and persisting it when the install record does not have one yet (M2 §5). // and persisting it when the install record does not have one yet (M2 §5).
// Best-effort: when the auth service is unreachable, it returns "" and the // Best-effort: when the auth service is unreachable, it returns "" and the
+58
View File
@@ -0,0 +1,58 @@
// Copyright (C) 2026 Dcntrlized
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package containers
import (
"testing"
composetypes "github.com/compose-spec/compose-go/v2/types"
)
// TestPropagateInsecureInternal verifies the dev escape hatch is propagated to
// every non-oneoff compose service (and only those), mirroring what the dev
// debug composes set so Maestro-started services keep plaintext peer edges.
func TestPropagateInsecureInternal(t *testing.T) {
project := &composetypes.Project{
Services: composetypes.Services{
"app": {
Environment: map[string]*string{"PORT": strptr("8080")},
},
"worker": {
Environment: nil,
},
"migrate": {
CustomLabels: map[string]string{"org.dcntrlized.oneoff": "true"},
},
},
}
propagateInsecureInternal(project)
for _, name := range []string{"app", "worker"} {
s := project.Services[name]
v, ok := s.Environment["INSECURE_INTERNAL"]
if !ok || v == nil || *v != "1" {
t.Errorf("service %s: expected INSECURE_INTERNAL=1, got %v", name, v)
}
}
s := project.Services["migrate"]
if _, ok := s.Environment["INSECURE_INTERNAL"]; ok {
t.Error("oneoff migrate service must not receive the plaintext escape hatch")
}
}
func strptr(s string) *string { return &s }