Skip to content

fix(identity): reject non-GitHub origins in RepoId::parse - #245

Merged
getappz merged 2 commits into
masterfrom
task/224
Jul 18, 2026
Merged

fix(identity): reject non-GitHub origins in RepoId::parse#245
getappz merged 2 commits into
masterfrom
task/224

Conversation

@getappz

@getappz getappz commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Closes flare_git: reject non-GitHub origins in RepoId::resolve_from_remote #224: a GitLab/Bitbucket origin remote previously resolved to a same-named GitHub repo via normalize_repo, so write ops (claims, PR ops) could target GitHub with a GitHub token under the wrong repo identity.
  • RepoId::parse now gates on confirmed_github_host: extracts the remote's host, resolves SSH aliases via ssh -G (handles this repo's own git@github-appzdev:... alias), and requires the resolved host match an allowed GitHub host (default github.com, override via AGENTFLARE_GITHUB_HOSTS).
  • claims::resolve_repo is rerouted through RepoId::parse so a non-GitHub origin returns None, forcing callers to pass an explicit --repo instead of silently guessing.
  • Review fix on top of the original implementation: skip the ssh alias-resolution spawn when the host is already an allowed GitHub host (perf), and reject dash-prefixed hosts before they ever reach ssh -G <host> as an argument (ssh argument-injection guard).

Test plan

  • cargo test -p agentflare identity:: / claims:: — new + existing tests pass, including the guarded SSH-alias test (passes on this machine's real ~/.ssh/config alias)
  • cargo test --workspace — 613 passed, 0 failed
  • cargo fmt --check clean
  • cargo clippy --locked --workspace --all-targets --all-features -- -D warnings -A unsafe_code -A clippy::pedantic — only pre-existing unrelated failure (agent_launch.rs unused import on Windows, tracked separately as handoff: assign items + attach versioned assets instead of raw artifacts #169), confirmed present on master via git stash

Summary by CodeRabbit

  • Bug Fixes
    • Improved repository detection to accept only confirmed GitHub remotes, avoiding incorrect association with non-GitHub repositories.
    • GitHub remotes are now recognized consistently across common HTTPS, SSH, and configured host URL formats.
    • Non-GitHub remotes are no longer auto-normalized; provide an explicit repository value instead.

Issue #224: a GitLab/Bitbucket origin previously resolved to a
same-named GitHub repo, so flare_git write ops could target GitHub
with a GitHub token under the wrong repo identity. RepoId::parse now
resolves the remote host (including SSH aliases via `ssh -G`) and
requires it match an allowed GitHub host (default github.com,
override via AGENTFLARE_GITHUB_HOSTS). claims::resolve_repo is
rerouted through RepoId::parse so a non-GitHub origin forces an
explicit --repo instead of silently guessing.

Also guards against ssh argument injection: a dash-prefixed host is
rejected before ever reaching `ssh -G <host>`, and a host that's
already an allowed GitHub host skips the ssh alias-resolution spawn
entirely.
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b301419e-64f0-455d-9f0a-99090d921538

📥 Commits

Reviewing files that changed from the base of the PR and between d15a33c and 5725a1f.

📒 Files selected for processing (1)
  • src/github/identity.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/github/identity.rs

📝 Walkthrough

Walkthrough

Repository resolution now accepts only confirmed GitHub origins. Remote parsing supports configured GitHub hosts and SSH aliases resolved through ssh -G, while claims resolution returns no key for non-GitHub remotes.

Changes

GitHub origin validation

Layer / File(s) Summary
Validate GitHub remote origins
src/github/identity.rs
RepoId::parse validates extracted hosts against AGENTFLARE_GITHUB_HOSTS, resolves SSH aliases, rejects unsafe or non-GitHub hosts, and expands coverage for remote URL forms and environment overrides.
Apply validated repository keys
src/claims.rs
resolve_repo derives claim keys through RepoId::parse, returning None for non-GitHub origins, with tests for accepted and rejected remotes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant resolve_repo
  participant RepoId.parse
  participant confirmed_github_host
  participant ssh
  resolve_repo->>RepoId.parse: parse remote URL
  RepoId.parse->>confirmed_github_host: validate remote host
  confirmed_github_host->>ssh: resolve SSH alias with ssh -G
  ssh-->>confirmed_github_host: resolved hostname
  confirmed_github_host-->>RepoId.parse: accept or reject origin
  RepoId.parse-->>resolve_repo: owner/repo key or None
Loading

Possibly related PRs

  • getappz/agentflare#141: Modifies claims repository resolution and URL normalization in the same code path.
  • getappz/agentflare#221: Modifies the repository URL parsing pipeline and normalization used by this GitHub-origin gate.

Suggested labels: rust

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately describes the main change: rejecting non-GitHub origins in RepoId::parse.
Description check ✅ Passed The description covers the summary and test plan; the optional reviewer notes section is missing but the template is mostly satisfied.
Linked Issues check ✅ Passed The implementation matches #224 by validating GitHub hosts, resolving SSH aliases, and preserving explicit bare owner/repo inputs.
Out of Scope Changes check ✅ Passed The extra SSH fast-path and host-safety tweaks are supporting changes for the same GitHub-origin validation goal, not unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/224

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/github/identity.rs (1)

180-218: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Make SSH alias validation deterministic.

This test silently passes without testing anything on typical CI machines. Inject or wrap alias resolution so tests can deterministically cover aliases resolving both to GitHub and to a rejected host.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/github/identity.rs` around lines 180 - 218, Make repo_id SSH-alias
validation testable without invoking the environment’s SSH configuration:
extract or inject the resolution behavior used by ssh_alias_resolves_to_github,
then add deterministic tests covering both a github.com resolution and a
non-GitHub resolution. Update
repo_id_accepts_ssh_alias_only_when_resolvable_to_github to use the injected or
wrapped resolver, while preserving rejection when the alias resolves elsewhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/github/identity.rs`:
- Around line 21-24: Update the identity resolution flow around
confirmed_github_host to validate only remote URL inputs, allowing explicit
two-segment owner/repo identifiers such as getappz/agentflare to bypass host
validation. Strictly accept that owner/repo form while preserving rejection of
invalid identifiers and non-GitHub remote URLs.
- Around line 301-311: Update allowed_github_hosts_honors_env to acquire the
shared environment-test lock before mutating AGENTFLARE_GITHUB_HOSTS, capture
its original value, and restore that value afterward instead of unconditionally
removing the variable. Ensure the guard remains held for the entire test.
- Around line 133-154: Update confirmed_github_host and the repo_host flow to
preserve the remote transport, and only call resolve_ssh_alias for SSH-shaped
remotes. After the direct allowlist check, immediately reject non-SSH hosts
instead of spawning ssh; retain the existing option-injection guard and alias
resolution for SSH remotes.

---

Nitpick comments:
In `@src/github/identity.rs`:
- Around line 180-218: Make repo_id SSH-alias validation testable without
invoking the environment’s SSH configuration: extract or inject the resolution
behavior used by ssh_alias_resolves_to_github, then add deterministic tests
covering both a github.com resolution and a non-GitHub resolution. Update
repo_id_accepts_ssh_alias_only_when_resolvable_to_github to use the injected or
wrapped resolver, while preserving rejection when the alias resolves elsewhere.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7012b68-acb1-471c-87b7-2638b81cbfa4

📥 Commits

Reviewing files that changed from the base of the PR and between 8d9692f and d15a33c.

📒 Files selected for processing (2)
  • src/claims.rs
  • src/github/identity.rs

Comment thread src/github/identity.rs
Comment thread src/github/identity.rs
Comment thread src/github/identity.rs
- Preserve the explicit owner/repo bypass: RepoId::parse now accepts a
  bare owner/repo identifier (flare_git's --repo format) directly,
  since it has no host to validate. Previously the host gate rejected
  it outright, breaking the fallback path the #224 fix depends on.
- Only spawn `ssh -G` for SSH-shaped remotes; an HTTPS host that isn't
  already allowed is rejected immediately.
- allowed_github_hosts_honors_env now serializes on the shared
  PATH_LOCK and restores the prior env value instead of unconditionally
  removing it.
@getappz
getappz merged commit aa50358 into master Jul 18, 2026
17 checks passed
@getappz
getappz deleted the task/224 branch July 18, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

flare_git: reject non-GitHub origins in RepoId::resolve_from_remote

1 participant