carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package activator
2
3import (
4 "log"
5 "os"
6 "path/filepath"
7 "strings"
8 "testing"
9 "time"
10)
11
12func TestEnsureAdminTokenMintsOnce(t *testing.T) {
13 p := filepath.Join(t.TempDir(), "h.env")
14 if err := EnsureAdminToken(p); err != nil {
15 t.Fatal(err)
16 }
17 st, _ := os.Stat(p)
18 if st.Mode().Perm() != 0o600 {
19 t.Fatalf("mode = %o", st.Mode().Perm())
20 }
21 env, _ := readEnvFile(p)
22 tok := env["CARLOS_ADMIN_TOKEN"]
23 if len(tok) != 64 {
24 t.Fatalf("token = %q", tok)
25 }
26 if err := EnsureAdminToken(p); err != nil {
27 t.Fatal(err)
28 }
29 env, _ = readEnvFile(p)
30 if env["CARLOS_ADMIN_TOKEN"] != tok {
31 t.Fatal("token rotated on second call")
32 }
33}
34
35func TestEnsureAdminTokenPreservesOtherVars(t *testing.T) {
36 p := filepath.Join(t.TempDir(), "h.env")
37 os.WriteFile(p, []byte("DATABASE_URL=sqlite\n# comment\n"), 0o600)
38 if err := EnsureAdminToken(p); err != nil {
39 t.Fatal(err)
40 }
41 raw, _ := os.ReadFile(p)
42 if !strings.HasPrefix(string(raw), "DATABASE_URL=sqlite\n# comment\n") || !strings.Contains(string(raw), "CARLOS_ADMIN_TOKEN=") {
43 t.Fatalf("file = %q", raw)
44 }
45 env, _ := readEnvFile(p)
46 if env["DATABASE_URL"] != "sqlite" {
47 t.Fatal("other var lost")
48 }
49}
50
51// A looser-mode file that already exists is tightened by the mint: O_CREATE's
52// 0600 only ever applied to a file created here, and a 0644 file now holds a
53// secret every other UNIX user on the box could read.
54func TestEnsureAdminTokenTightensAnExistingFile(t *testing.T) {
55 p := filepath.Join(t.TempDir(), "h.env")
56 os.WriteFile(p, []byte("DATABASE_URL=sqlite\n"), 0o644)
57 if err := EnsureAdminToken(p); err != nil {
58 t.Fatal(err)
59 }
60 st, _ := os.Stat(p)
61 if st.Mode().Perm() != 0o600 {
62 t.Fatalf("mode after mint = %o, want 600", st.Mode().Perm())
63 }
64}
65
66// The tightening is not the minting path's alone. A file that ALREADY held a
67// token took an early return that skipped the chmod entirely, so a 0644 env
68// file written by hand (or by an older tool) kept holding the instance's
69// secret at world-readable mode for as long as the instance lived — the mode
70// only ever converged for files this function itself created.
71func TestEnsureAdminTokenTightensAFileThatAlreadyHoldsAToken(t *testing.T) {
72 p := filepath.Join(t.TempDir(), "h.env")
73 tok := strings.Repeat("ab", 32)
74 if err := os.WriteFile(p, []byte("CARLOS_ADMIN_TOKEN="+tok+"\n"), 0o644); err != nil {
75 t.Fatal(err)
76 }
77 if err := EnsureAdminToken(p); err != nil {
78 t.Fatal(err)
79 }
80 st, err := os.Stat(p)
81 if err != nil {
82 t.Fatal(err)
83 }
84 if st.Mode().Perm() != 0o600 {
85 t.Fatalf("mode of a pre-existing token file after ensure = %o, want 600", st.Mode().Perm())
86 }
87 env, _ := readEnvFile(p)
88 if env["CARLOS_ADMIN_TOKEN"] != tok {
89 t.Fatalf("token = %q, want the pre-existing %q — tightening must not rewrite the secret", env["CARLOS_ADMIN_TOKEN"], tok)
90 }
91}
92
93// captureLog redirects the standard logger for the duration of one test and
94// returns what was written to it. Assertions below count a marker substring
95// rather than compare whole buffers: a goroutine left running by an earlier
96// test in this package (the activator's sweeper logs) can drop a line in
97// here at any moment, and a test that fails on someone else's log line is a
98// flake, not a finding.
99func captureLog(t *testing.T) *strings.Builder {
100 t.Helper()
101 var buf strings.Builder
102 flags := log.Flags()
103 log.SetOutput(&buf)
104 log.SetFlags(0)
105 t.Cleanup(func() {
106 log.SetOutput(os.Stderr)
107 log.SetFlags(flags)
108 })
109 return &buf
110}
111
112// The ruling (2026-08-24): a malformed existing token is WARNED about and
113// LEFT IN PLACE — never rotated. The running instance was handed this same
114// value at spawn, so file and process agree and its ticks authenticate;
115// re-minting behind its back would 401 a live instance to repair a string.
116// The warning carries the operator's own repair instead.
117func TestEnsureAdminTokenWarnsAboutAMalformedTokenAndLeavesIt(t *testing.T) {
118 p := filepath.Join(t.TempDir(), "h.env")
119 const body = "DATABASE_URL=sqlite\nCARLOS_ADMIN_TOKEN=deadbe\n"
120 if err := os.WriteFile(p, []byte(body), 0o600); err != nil {
121 t.Fatal(err)
122 }
123 buf := captureLog(t)
124 if err := EnsureAdminToken(p); err != nil {
125 t.Fatal(err)
126 }
127 raw, err := os.ReadFile(p)
128 if err != nil {
129 t.Fatal(err)
130 }
131 if string(raw) != body {
132 t.Fatalf("file after ensure = %q, want it byte-identical to %q — a malformed token is never rotated", raw, body)
133 }
134 got := buf.String()
135 if !strings.Contains(got, "CARLOS_ADMIN_TOKEN") || !strings.Contains(got, p) {
136 t.Fatalf("log = %q, want a warning naming the variable and the file", got)
137 }
138 if !strings.Contains(got, "left in place") {
139 t.Fatalf("log = %q, want it to say the value was left in place", got)
140 }
141 if n := strings.Count(got, "not the shape"); n != 1 {
142 t.Fatalf("warning appeared %d times, want 1: %q", n, got)
143 }
144 // Sticky condition, repeated caller: the runner ensures the token on every
145 // tick for the host. One line per file per process, not one per tick.
146 if err := EnsureAdminToken(p); err != nil {
147 t.Fatal(err)
148 }
149 if n := strings.Count(buf.String(), "not the shape"); n != 1 {
150 t.Fatalf("warning appeared %d times across two ensures, want 1: %q", n, buf.String())
151 }
152}
153
154// The other half of the same contract: a well-formed token is silent. A
155// warning that fired on healthy files would be noise on every box, and the
156// shape check exists to be believed.
157func TestEnsureAdminTokenIsSilentForAWellFormedToken(t *testing.T) {
158 p := filepath.Join(t.TempDir(), "h.env")
159 if err := EnsureAdminToken(p); err != nil { // mint one, so the shape is by construction ours
160 t.Fatal(err)
161 }
162 before, err := os.ReadFile(p)
163 if err != nil {
164 t.Fatal(err)
165 }
166 buf := captureLog(t)
167 if err := EnsureAdminToken(p); err != nil {
168 t.Fatal(err)
169 }
170 after, err := os.ReadFile(p)
171 if err != nil {
172 t.Fatal(err)
173 }
174 if string(after) != string(before) {
175 t.Fatalf("file changed under a well-formed token: %q → %q", before, after)
176 }
177 if strings.Contains(buf.String(), "CARLOS_ADMIN_TOKEN") || strings.Contains(buf.String(), "not the shape") {
178 t.Fatalf("log = %q, want nothing said about a healthy token", buf.String())
179 }
180}
181
182// The shape is the minting format, exactly: 64 lowercase hex characters.
183func TestWellFormedAdminToken(t *testing.T) {
184 good := strings.Repeat("0f", 32)
185 for _, c := range []struct {
186 name string
187 tok string
188 want bool
189 }{
190 {"minted shape", good, true},
191 {"empty", "", false},
192 {"short", good[:63], false},
193 {"long", good + "0", false},
194 {"uppercase hex", strings.ToUpper(good), false},
195 {"non-hex", strings.Repeat("z", 64), false},
196 {"quoted", `"` + good[:62] + `"`, false},
197 } {
198 if got := wellFormedAdminToken(c.tok); got != c.want {
199 t.Errorf("%s: wellFormedAdminToken(%q) = %v, want %v", c.name, c.tok, got, c.want)
200 }
201 }
202}
203
204// os.Chmod is path-based chmod(2) and follows symlinks, and this now runs on
205// every tick for the host rather than once per instance lifetime. A same-uid
206// sibling — the residual spec §7.2 documents — that swaps <host>.env for a
207// link must not turn the agent's tightening into a mode change somewhere
208// else on the box. Same guard backend_exec.go puts in front of the instance
209// socket's normalization, for the same reason.
210func TestEnsureAdminTokenRefusesToChmodThroughASymlink(t *testing.T) {
211 dir := t.TempDir()
212 target := filepath.Join(dir, "someone-elses-file")
213 if err := os.WriteFile(target, []byte("CARLOS_ADMIN_TOKEN="+strings.Repeat("ab", 32)+"\n"), 0o644); err != nil {
214 t.Fatal(err)
215 }
216 link := filepath.Join(dir, "h.env")
217 if err := os.Symlink(target, link); err != nil {
218 t.Skipf("this filesystem will not make symlinks: %v", err)
219 }
220 buf := captureLog(t)
221 if err := EnsureAdminToken(link); err != nil {
222 t.Fatal(err)
223 }
224 st, err := os.Stat(target)
225 if err != nil {
226 t.Fatal(err)
227 }
228 if st.Mode().Perm() != 0o644 {
229 t.Fatalf("mode of the symlink's TARGET = %o, want the untouched 644 — the agent must not chmod through a link", st.Mode().Perm())
230 }
231 if !strings.Contains(buf.String(), "SYMLINK") {
232 t.Fatalf("log = %q, want the refusal named", buf.String())
233 }
234}
235
236// The throttle is a clock, not a latch: the chmod is retried every tick, so
237// the condition can come back (an operator fixes a 0644 file, something
238// re-widens it weeks later) and a once-per-process bool would keep the agent
239// silent about a world-readable secret until the next binary roll.
240func TestEnsureAdminTokenComplaintIsThrottledNotSilenced(t *testing.T) {
241 p := filepath.Join(t.TempDir(), "h.env")
242 if err := os.WriteFile(p, []byte("CARLOS_ADMIN_TOKEN=deadbe\n"), 0o600); err != nil {
243 t.Fatal(err)
244 }
245 buf := captureLog(t)
246 for i := 0; i < 3; i++ {
247 if err := EnsureAdminToken(p); err != nil {
248 t.Fatal(err)
249 }
250 }
251 if n := strings.Count(buf.String(), "not the shape"); n != 1 {
252 t.Fatalf("warning appeared %d times inside the throttle window, want 1", n)
253 }
254 // Age the memory past the window — what a real recurrence looks like.
255 adminTokenMu.Lock()
256 for k := range adminTokenLogged {
257 adminTokenLogged[k] = time.Now().Add(-adminTokenLogRepeat - time.Minute)
258 }
259 adminTokenMu.Unlock()
260 if err := EnsureAdminToken(p); err != nil {
261 t.Fatal(err)
262 }
263 if n := strings.Count(buf.String(), "not the shape"); n != 2 {
264 t.Fatalf("warning appeared %d times after the window elapsed, want it said again (2)", n)
265 }
266}
267