deriveSafeOutputsGuardPolicyFromGitHub generates a safeoutputs guard-policy from GitHub guard-policy. When the GitHub MCP server has a guard-policy with repos, the safeoutputs MCP must also have a linked guard-policy with accept field derived from repos according to these rules: Rules by repos valu
(githubTool map[string]any)
| 450 | // This allows the gateway to read data from the GitHub MCP server and still write to safeoutputs. |
| 451 | // Returns nil if no GitHub guard policies are configured. |
| 452 | func deriveSafeOutputsGuardPolicyFromGitHub(githubTool map[string]any) map[string]any { |
| 453 | githubPolicies := getGitHubGuardPolicies(githubTool) |
| 454 | if githubPolicies == nil { |
| 455 | return nil |
| 456 | } |
| 457 | |
| 458 | // Extract the allow-only policy from GitHub guard policies |
| 459 | allowOnly, ok := githubPolicies["allow-only"].(map[string]any) |
| 460 | if !ok || allowOnly == nil { |
| 461 | return nil |
| 462 | } |
| 463 | |
| 464 | // Extract repos from the allow-only policy |
| 465 | repos, hasRepos := allowOnly["repos"] |
| 466 | if !hasRepos { |
| 467 | return nil |
| 468 | } |
| 469 | |
| 470 | // Convert repos to accept list according to the specification |
| 471 | var acceptList []string |
| 472 | |
| 473 | switch r := repos.(type) { |
| 474 | case string: |
| 475 | // Single string value (e.g., "all", "public", or a pattern) |
| 476 | switch r { |
| 477 | case "all", "public": |
| 478 | // For "all" or "public", accept all safe output operations |
| 479 | acceptList = []string{"*"} |
| 480 | default: |
| 481 | // Single pattern - transform according to rules |
| 482 | acceptList = []string{transformRepoPattern(r)} |
| 483 | } |
| 484 | case []any: |
| 485 | // Array of patterns |
| 486 | acceptList = make([]string, 0, len(r)) |
| 487 | for _, item := range r { |
| 488 | if pattern, ok := item.(string); ok { |
| 489 | acceptList = append(acceptList, transformRepoPattern(pattern)) |
| 490 | } |
| 491 | } |
| 492 | case []string: |
| 493 | // Array of patterns (already strings) |
| 494 | acceptList = make([]string, 0, len(r)) |
| 495 | for _, pattern := range r { |
| 496 | acceptList = append(acceptList, transformRepoPattern(pattern)) |
| 497 | } |
| 498 | default: |
| 499 | // Unknown type, return nil |
| 500 | githubConfigLog.Printf("Unknown repos type in guard-policy: %T", repos) |
| 501 | return nil |
| 502 | } |
| 503 | |
| 504 | // Build the write-sink policy for safeoutputs |
| 505 | return map[string]any{ |
| 506 | "write-sink": map[string]any{ |
| 507 | "accept": acceptList, |
| 508 | }, |
| 509 | } |