mirror of
https://github.com/mudler/LocalAI.git
synced 2026-10-28 09:08:54 -04:00
fix(mcp): redact credentials in JSON logs
JSON log handlers bypass String and serialize exported credentials. Implement LogValue so remote server entries use the same redacted representation in text and JSON logs. Extend the regression test to cover both handlers. Assisted-by: Codex:GPT-6
This commit is contained in:
1 parent
a849e872ec
commit
f93781c307
3 files changed
+9
-2
No files matched your search
@@ -67,6 +67,7 @@ var _ = Describe("MCP remote server OAuth2 configuration", func() {
|
||||
OAuth2: &MCPOAuth2Config{TokenURL: "https://idp", ClientID: "id", ClientSecret: "oauth-secret"},
|
||||
}
|
||||
logger.Info("cfg", "a", withToken, "b", withOAuth2)
|
||||
slog.New(slog.NewJSONHandler(&buf, nil)).Info("cfg", "a", withToken, "b", withOAuth2)
|
||||
out := buf.String() + fmt.Sprintf("%v %+v", withToken, MCPRemoteServers{"s": withOAuth2})
|
||||
Expect(out).To(ContainSubstring("https://x"))
|
||||
Expect(out).To(ContainSubstring("https://idp"))
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -850,8 +851,7 @@ func exactlyOne(field, literal, env string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// String keeps credentials out of logs: the MCP code logs whole server
|
||||
// entries at debug level, and both xlog and slog format structs via fmt.
|
||||
// String redacts credentials when server entries are formatted as text.
|
||||
func (s MCPRemoteServer) String() string {
|
||||
auth := "none"
|
||||
switch {
|
||||
@@ -863,6 +863,11 @@ func (s MCPRemoteServer) String() string {
|
||||
return fmt.Sprintf("{url: %s, auth: %s}", s.URL, auth)
|
||||
}
|
||||
|
||||
// LogValue also redacts credentials in structured JSON logs, which bypass String.
|
||||
func (s MCPRemoteServer) LogValue() slog.Value {
|
||||
return slog.StringValue(s.String())
|
||||
}
|
||||
|
||||
// @Description MCP STDIO server configuration
|
||||
type MCPSTDIOServer struct {
|
||||
Args []string `json:"args,omitempty"`
|
||||
|
||||
@@ -135,6 +135,7 @@ Behaviour:
|
||||
- It is refreshed proactively once **half** of its lifetime (`expires_in`) has elapsed. If the provider omits `expires_in`, a lifetime of 5 minutes is assumed.
|
||||
- If a refresh fails, the current token keeps being used until 30 seconds before it expires (retries wait at least 5 seconds after a failed fetch, including the first fetch). After that, requests to the MCP server fail with an error; LocalAI never falls back to an unauthenticated request.
|
||||
- Configuring both `token` and `oauth2` for the same server is rejected when the model configuration is loaded, as are missing or duplicated `client_id`/`client_secret` sources. An environment variable named in `*_env` that is unset or empty makes the connection to that server fail, and the server is reported with an error in the server listing.
|
||||
- Debug logs of remote server entries redact static tokens and OAuth2 client secrets in both text and JSON formats.
|
||||
- Token caches and retry timers are local to each connection-owning process. Workers obtain and refresh their own tokens; this cache is not shared across the cluster.
|
||||
- The environment variables are read by the process that connects to the MCP server. In distributed mode that is the agent worker, so set them there.
|
||||
|
||||
|
||||
Reference in new issue
Block a user