Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f67f77c
feat: proxy pre-agent gh CLI calls through DIFC gateway
lpcox Mar 21, 2026
6ce8196
chore: bump mcpg container image to v0.1.22
lpcox Mar 21, 2026
caf23b9
fix: use /health endpoint and avoid repeated update-ca-certificates
lpcox Mar 21, 2026
e321543
fix: add git remote for proxy so gh CLI can resolve repo context
lpcox Mar 21, 2026
c80f390
fix: use -R flag on gh commands to bypass remote resolution
lpcox Mar 22, 2026
f95d9e0
fix: recognize /api/graphql path in proxy for GHES-style gh CLI
lpcox Mar 22, 2026
ac96d69
debug: build local container for proxy to pick up /api/graphql fix
lpcox Mar 22, 2026
72c5809
fix: extract WASM guard from published image before local build
lpcox Mar 22, 2026
d349859
fix: build WASM guard from source instead of extracting from image
lpcox Mar 22, 2026
bbb6d4b
debug: log blocked GraphQL query body and dump proxy logs
lpcox Mar 22, 2026
2098dd8
debug: add DEBUG=* to proxy container and fix log file path
lpcox Mar 22, 2026
2a3b84f
fix: passthrough GraphQL introspection queries (__type, __schema)
lpcox Mar 22, 2026
f8a5c2b
fix: preserve original GraphQL response format in proxy DIFC pipeline
lpcox Mar 22, 2026
b8e8c6d
fix: return valid empty GraphQL response when DIFC filters all items
lpcox Mar 22, 2026
aaa75d0
fix: graceful fallback when DIFC proxy filters gh CLI data
lpcox Mar 22, 2026
3a8f178
chore: change min-integrity from merged to approved
lpcox Mar 22, 2026
8382d71
fix: add 'github-actions' (without [bot]) to trusted first-party bots
lpcox Mar 22, 2026
6825f68
fix: add 'app/github-actions' to trusted first-party bots
lpcox Mar 22, 2026
f348b3b
chore: remove local container build, bump to mcpg v0.1.23
lpcox Mar 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 69 additions & 4 deletions .github/workflows/repo-assist.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions guards/github-guard/rust-guard/src/labels/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1034,12 +1034,16 @@ pub fn commit_integrity(
/// Trusted bots:
/// - dependabot[bot]: GitHub dependency updater
/// - github-actions[bot]: GitHub Actions workflow actor (GITHUB_TOKEN)
/// - github-actions: GitHub Actions workflow actor (without [bot] suffix, as returned by some APIs)
/// - app/github-actions: GitHub Actions workflow actor (with app/ prefix, as returned by gh CLI)
/// - github-merge-queue[bot]: GitHub merge queue automation
/// - copilot: GitHub Copilot AI assistant
pub fn is_trusted_first_party_bot(username: &str) -> bool {
let lower = username.to_lowercase();
lower == "dependabot[bot]"
|| lower == "github-actions[bot]"
|| lower == "github-actions"
|| lower == "app/github-actions"
|| lower == "github-merge-queue[bot]"
|| lower == "copilot"
}
Expand Down
13 changes: 12 additions & 1 deletion guards/github-guard/rust-guard/src/labels/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,8 @@ mod tests {
// Not bots
assert!(!is_trusted_first_party_bot("octocat"));
assert!(!is_trusted_first_party_bot("dependabot"));
assert!(!is_trusted_first_party_bot("github-actions"));
assert!(is_trusted_first_party_bot("github-actions"));
assert!(is_trusted_first_party_bot("app/github-actions"));
assert!(!is_trusted_first_party_bot(""));
}

Expand Down Expand Up @@ -893,6 +894,16 @@ mod tests {
writer_integrity(repo, &ctx)
);

// github-actions without [bot] suffix (as returned by some APIs)
let actions_no_bot_issue = json!({
"user": {"login": "github-actions"},
"author_association": "NONE"
});
assert_eq!(
issue_integrity(&actions_no_bot_issue, repo, false, &ctx),
writer_integrity(repo, &ctx)
);

// Non-trusted bot still gets none integrity on public repo
let renovate_issue = json!({
"user": {"login": "renovate[bot]"},
Expand Down
8 changes: 7 additions & 1 deletion internal/proxy/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ type graphqlPattern struct {

// graphqlPatterns is the ordered list of GraphQL operation → tool name mappings.
var graphqlPatterns = []graphqlPattern{
// Schema introspection queries (safe read-only metadata, no repo data)
{queryPattern: regexp.MustCompile(`(?i)__type\s*\(`), toolName: "graphql_introspection"},
{queryPattern: regexp.MustCompile(`(?i)__schema\b`), toolName: "graphql_introspection"},

// Issue operations (singular before plural — more specific first)
{queryPattern: regexp.MustCompile(`(?i)repository\s*\([^)]*\)\s*\{[^}]*\bissue\s*\(`), toolName: "issue_read"},
{queryPattern: regexp.MustCompile(`(?i)repository\s*\([^)]*\)\s*\{[^}]*\bissues\s*[\({]`), toolName: "list_issues"},
Expand Down Expand Up @@ -170,7 +174,9 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s
}

// IsGraphQLPath returns true if the request path is the GraphQL endpoint.
// Accepts /graphql (after prefix strip), /api/v3/graphql (before strip),
// and /api/graphql (GHES-style path used by gh CLI with GH_HOST).
func IsGraphQLPath(path string) bool {
cleaned := strings.TrimSuffix(path, "/")
return cleaned == "/graphql" || cleaned == "/api/v3/graphql"
return cleaned == "/graphql" || cleaned == "/api/v3/graphql" || cleaned == "/api/graphql"
}
Loading
Loading