Repository navigation
Commit 97c8c8f
feat(config): read the API key from MCPPROXY_API_KEY_FILE (#1716)
## Description
First of the two PRs for #1706 (the second adds `${file:}` and builds on
this one). Adds `MCPPROXY_API_KEY_FILE`, the `*_FILE` form used by
Docker Compose/Swarm secrets, Kubernetes secret volumes and systemd
`LoadCredential=`, so the proxy's own key need not sit in the process
environment (`docker inspect`, `/proc/<pid>/environ`, crash dumps) or in
`mcp_config.json`.
- **One helper.** `config.ResolveEnvAPIKey` is now the only reader of
the environment's key. The loader (`Validate`), `EnsureAPIKey`, the CLI
client (`resolveAPIKey`), `status`, the tray and the core it launches
all go through it.
- **Hard fail.** A named file that cannot be used (missing, unreadable,
relative path, over 64 KiB, empty after removing the trailing newline)
stops startup with an error naming the variable and path, never the
content. There is no fallback to `MCPPROXY_API_KEY`, the config file or
a generated key, and nothing is saved. A real run with a missing file
exits 4 and leaves the config byte-identical.
- **Never written back.** The key from the file is a process-only
override, like the env key.
- **Tray.** When the key is in a file, the tray does not inject it into
the core as `MCPPROXY_API_KEY` (that would put it back in the core's
environment); the core inherits `MCPPROXY_API_KEY_FILE` and reads the
file itself. The tray exits on an unusable file instead of generating a
key.
- `secret.ReadFile` holds the read rules (absolute path, regular file
after following symlinks, 64 KiB cap, exactly one trailing LF or CRLF
removed, no NUL, errors never include content) so the `${file:}`
provider in the follow-up behaves identically.
- `Config.EnsureAPIKey` now also returns an error (it is internal; the
five callers are updated).
- Spec 111 FR-014, FR-030 and US7 are amended so the spec covers the
proxy's own key. Docs and CHANGELOG updated.
@Dumbris, one question on precedence. When both `MCPPROXY_API_KEY` and
`MCPPROXY_API_KEY_FILE` are set I made the file win and log a warning,
since an explicit file is the more deliberate choice and keeps the key
out of the environment. The alternatives are to prefer the env var (the
order the issue first described) or to refuse to start with both set,
which is what some official images do. Happy to switch; it is one
condition in `ResolveEnvAPIKey` plus its tests.
## Testing
- [x] I have tested these changes locally
- [x] I have added/updated tests that prove my fix is effective or my
feature works
- [x] All existing tests pass
`go test ./internal/config ./internal/secret ./cmd/mcpproxy
./internal/httpapi` pass. By hand with a built binary: key from the file
authenticates (200, no key 401), the key is absent from
`/proc/<pid>/environ` and the config, a missing file exits 4 with the
config unchanged, `mcpproxy status` finds the key.
Not run here: the tray is built only for macOS/Windows. It compiles for
Windows; the new `TestBuildCoreEnvironmentAPIKey` in
`cmd/mcpproxy-tray/main_test.go` is darwin-only and I could not compile
or run it on this Linux host. The macOS native app's
`CoreProcessManager.swift` is untouched (it removes `MCPPROXY_API_KEY`
and passes its own key).
---------
Co-authored-by: Algis Dumbris <a.dumbris@gmail.com>1 parent 81c9206 commit 97c8c8f
20 files changed
Lines changed: 878 additions & 36 deletions
File tree
- cmd
- mcpproxy-tray
- mcpproxy
- docs
- configuration
- getting-started
- internal
- config
- secret
- tray
- specs/111-personal-docker-image
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
| 83 | + | |
82 | 84 | | |
83 | 85 | | |
84 | 86 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
159 | 172 | | |
160 | 173 | | |
161 | 174 | | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
167 | 183 | | |
168 | 184 | | |
169 | 185 | | |
| |||
1935 | 1951 | | |
1936 | 1952 | | |
1937 | 1953 | | |
1938 | | - | |
1939 | | - | |
1940 | | - | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
1941 | 1963 | | |
1942 | 1964 | | |
1943 | 1965 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
425 | 425 | | |
426 | 426 | | |
427 | 427 | | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
33 | | - | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | | - | |
37 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
38 | 49 | | |
39 | 50 | | |
40 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
549 | 549 | | |
550 | 550 | | |
551 | 551 | | |
552 | | - | |
553 | | - | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
554 | 559 | | |
555 | 560 | | |
556 | 561 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
200 | 200 | | |
201 | 201 | | |
202 | 202 | | |
203 | | - | |
| 203 | + | |
| 204 | + | |
204 | 205 | | |
205 | 206 | | |
206 | 207 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
135 | | - | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
136 | 138 | | |
137 | 139 | | |
138 | 140 | | |
| |||
149 | 151 | | |
150 | 152 | | |
151 | 153 | | |
152 | | - | |
153 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
154 | 160 | | |
155 | 161 | | |
156 | 162 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
827 | 827 | | |
828 | 828 | | |
829 | 829 | | |
830 | | - | |
| 830 | + | |
831 | 831 | | |
832 | 832 | | |
833 | 833 | | |
| |||
1858 | 1858 | | |
1859 | 1859 | | |
1860 | 1860 | | |
| 1861 | + | |
1861 | 1862 | | |
1862 | 1863 | | |
1863 | 1864 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
36 | 73 | | |
37 | 74 | | |
38 | 75 | | |
| |||
0 commit comments