Skip to content

feat(x2a): git auth credentials#2839

Merged
elai-shalev merged 1 commit intoredhat-developer:mainfrom
eloycoto:AuthIssue
Apr 20, 2026
Merged

feat(x2a): git auth credentials#2839
elai-shalev merged 1 commit intoredhat-developer:mainfrom
eloycoto:AuthIssue

Conversation

@eloycoto
Copy link
Copy Markdown
Contributor

@eloycoto eloycoto commented Apr 20, 2026

The e62d73d added a way to use auth url, but when the token has any illegal character for the URL, it fails to se the auth URL.

This change get the Auth Token, set the username (by backstage) and the token and it uses credentials helper for setting the commit.

image

The e62d73d added a way to use auth url, but when the token has any illegal character for the URL, it fails to se the auth URL.

This change get the Auth Token, set the username (by backstage) and the token and it uses credentials helper for setting the commit.

Signed-off-by: Eloy Coto <eloy.coto@acalustra.com>
@rhdh-gh-app
Copy link
Copy Markdown

rhdh-gh-app Bot commented Apr 20, 2026

Missing Changesets

The following package(s) are changed by this PR but do not have a changeset:

  • @red-hat-developer-hub/backstage-plugin-x2a-backend

See CONTRIBUTING.md for more information about how to add changesets.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-x2a-backend workspaces/x2a/plugins/x2a-backend none v1.4.0

@sonarqubecloud
Copy link
Copy Markdown

@eloycoto eloycoto marked this pull request as ready for review April 20, 2026 13:31
@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge Bot commented Apr 20, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Helper script injection 🐞 Bug ⛨ Security
Description
git_source_repo/git_target_repo embed unescaped username/password directly inside an inline
credential.helper shell snippet and inside a printf format string, so tokens containing quotes,
newlines, backslashes, or % sequences can break authentication or alter helper execution. This is
especially likely given the PR goal is to support tokens with URL-illegal/special characters.
Code

workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[R119-123]

+  local username="${SOURCE_REPO_TOKEN%%:*}"
+  local password="${SOURCE_REPO_TOKEN#*:}"
+
+  git -c "credential.helper=!f() { test \"\$1\" = get && printf 'username=${username}\\npassword=${pa********\n'; }; f" "$@"
}
Relevance

⭐⭐⭐ High

Team previously prioritized secure git auth handling; unescaped token injection in credential.helper
is a real command/format-string risk.

PR-#2745
PR-#2636

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The credential helper command is constructed by interpolating ${username} and ${password} into a
shell snippet that later gets executed by git; the interpolated values are also placed inside a
single-quoted printf *format string*, so characters like ' and % are syntactically/semantically
significant and can break or change behavior. The backend accepts the token as an arbitrary string
(no escaping/encoding/format restriction), so problematic characters are not prevented upstream.

workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-130]
workspaces/x2a/plugins/x2a-backend/src/router/modules.ts[211-260]
workspaces/x2a/plugins/x2a-backend/src/router/projects.ts[130-140]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`git_source_repo()` / `git_target_repo()` build a `credential.helper` shell snippet by directly interpolating the token-derived `username`/`password` into the helper body and into a `printf` format string. Tokens containing `'`, newlines, backslashes, or `%` can break the helper or change what it prints/executes.

### Issue Context
This PR explicitly targets tokens that contain special characters; the current helper construction is brittle precisely for those inputs.

### Fix approach
1. Do **not** inline the secret values into the helper script.
2. Pass credentials via environment variables for that git invocation.
3. Use `printf '%s\n' ...` so the credential content is not treated as a printf format string.

### Fix Focus Areas
- workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-130]

### Example direction (shell)
- Prefix the `git` invocation with environment variables:
 - `GIT_USERNAME="$username" GIT_PASSWORD="$password" git ...`
- Use a *single-quoted* helper so `$GIT_USERNAME/$GIT_PASSWORD` expand only when the helper runs:
 - `git -c 'credential.helper=!f(){ [ "$1" = get ] || exit 0; printf "%s\n" "username=$GIT_USERNAME" "password=$GIT_PASSWORD"; }; f' ...`
- Apply the same change to both source and target wrappers.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Colon-split token regression 🐞 Bug ≡ Correctness
Description
The script now assumes repo tokens are always in "username:password" form and derives the username
via ${TOKEN%%:*}, but the backend API/schema/tests treat token as an unconstrained string, so
plain tokens will produce an incorrect username value. This can break authentication for providers
that require a specific username value (as documented in the script comments for GitLab/Bitbucket).
Code

workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[R119-121]

+  local username="${SOURCE_REPO_TOKEN%%:*}"
+  local password="${SOURCE_REPO_TOKEN#*:}"
+
Relevance

⭐⭐⭐ High

Earlier job script used plain TOKEN in url.insteadOf; new colon-splitting likely breaks existing
callers/tests.

PR-#2745
PR-#2273

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The job script explicitly documents that Backstage tokens are expected in username:password form
and then splits on :. However, the backend routes validate
sourceRepoAuth.token/targetRepoAuth.token as just z.string() and the generated OpenAPI model
describes it as a single token string; tests also use plain values like
source-token/target-token (no colon), demonstrating the system does not enforce the new format
end-to-end.

workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-130]
workspaces/x2a/plugins/x2a-backend/src/router/modules.ts[211-260]
workspaces/x2a/plugins/x2a-backend/src/schema/openapi/generated/models/GitRepoAuth.model.ts[24-29]
workspaces/x2a/plugins/x2a-backend/src/services/JobResourceBuilder.test.ts[391-444]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The job script currently assumes `SOURCE_REPO_TOKEN` / `TARGET_REPO_TOKEN` always contain a colon and encode `username:password`. But the backend treats `token` as an arbitrary string and tests use plain tokens with no colon.

### Issue Context
The script comments state that GitLab/Bitbucket require specific usernames (`oauth2`, `x-token-auth`). If the incoming token is a plain PAT, the derived `username` will be wrong.

### Fix approach
- Accept both formats:
 1. If the token contains `:`, split into `username`/`password`.
 2. Otherwise, treat the entire token as the password and choose the username via a deterministic fallback (e.g., configurable env var like `SOURCE_REPO_USERNAME`/`TARGET_REPO_USERNAME`, or a documented default).

### Fix Focus Areas
- workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-130]

### Concrete change sketch
```sh
if [ "${SOURCE_REPO_TOKEN#*:}" = "$SOURCE_REPO_TOKEN" ]; then
 username="${SOURCE_REPO_USERNAME:-git}"
 password="$SOURCE_REPO_TOKEN"
else
 username="${SOURCE_REPO_TOKEN%%:*}"
 password="${SOURCE_REPO_TOKEN#*:}"
fi
```
Apply similarly for `TARGET_REPO_TOKEN` and document the expected defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@elai-shalev elai-shalev merged commit 6b685ce into redhat-developer:main Apr 20, 2026
12 checks passed
@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Use git credential helper for authenticated repository access

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Replace URL-based auth with credential helper approach
• Support tokens with special characters that break URL format
• Use Backstage-provided "username:password" token format
• Extract username and password from token for git credential helper
Diagram
flowchart LR
  A["Token with special chars"] -->|Previous: URL injection| B["URL parsing fails"]
  A -->|New: Credential helper| C["Parse username:password"]
  C -->|Extract parts| D["Set git credentials"]
  D -->|Supports| E["GitHub/GitLab/Bitbucket"]
Loading

Grey Divider

File Changes

1. workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh 🐞 Bug fix +13/-10

Implement credential helper for git authentication

• Replaced URL-based authentication with git credential helper mechanism
• Changed from injecting token into HTTPS URL to using credential helper callback
• Updated git_source_repo() function to parse "username:password" format and provide credentials
 via helper
• Updated git_target_repo() function with same credential helper approach
• Updated comments to document Backstage token format for GitHub, GitLab, and Bitbucket

workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh


Grey Divider

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added enhancement New feature or request bug_fix labels Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants