Skip to content

Commit 8f7e686

Browse files
committed
fix: credential workaround for go mod download
1 parent 003bbce commit 8f7e686

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Go Mod Credential Fix Rule
2+
3+
When running `go mod` commands (such as `go mod tidy`, `go mod download`, `go mod vendor`, etc.) and encountering HTTP 40x authentication/permission errors, automatically attempt to resolve the issue by extracting credentials from Git's credential helper and writing them to `/root/.netrc`.
4+
5+
## Trigger Conditions
6+
7+
When `go mod` commands fail with errors indicating authentication or permission issues, such as:
8+
9+
- `401 Unauthorized`
10+
- `403 Forbidden`
11+
- `404 Not Found` (for private repositories that return 404 to unauthenticated requests)
12+
- Messages containing `unexpected status` with 40x HTTP codes
13+
14+
## Execution Steps
15+
16+
### 1. Identify the Credential Helper
17+
18+
Read the Git credential helper configuration:
19+
20+
```bash
21+
git config --get credential.helper
22+
```
23+
24+
If a specific host is configured, check for host-specific helpers:
25+
26+
```bash
27+
git config --get-all credential.helper
28+
```
29+
30+
### 2. Extract the Target Host
31+
32+
From the error message, identify the host that requires authentication (e.g., `gitlab.example.com`, `github.com`).
33+
34+
### 3. Invoke the Credential Helper
35+
36+
Use the credential helper to retrieve credentials. The command to execute depends on the value returned by `git config --get credential.helper`:
37+
38+
- If the value is a **built-in short name** (e.g., `store`, `cache`, `osxkeychain`), the actual command is `git credential-<NAME> get`
39+
- If the value is an **absolute path** to an executable (e.g., `/usr/lib/git-core/git-credential-manager`), execute that path directly with `get` as the argument
40+
- If the value contains **arguments** (e.g., `/path/to/helper --arg`), treat the entire value as the command followed by `get`
41+
42+
In the current environment, the most possible credential helper is: `/app/agent/bin/agent git-credential-helper`
43+
44+
Pass `protocol` and `host` via stdin:
45+
46+
```bash
47+
# Read the helper config
48+
HELPER=$(git config --get credential.helper)
49+
50+
# Execute the helper's get command, passing protocol and host via stdin
51+
echo -e "protocol=https\nhost=<TARGET_HOST>\n" | $HELPER get
52+
```
53+
54+
Alternatively, use Git's built-in credential interface which automatically dispatches to the configured helper:
55+
56+
```bash
57+
echo -e "protocol=https\nhost=<TARGET_HOST>\n" | git credential fill
58+
```
59+
60+
The output will contain fields like:
61+
62+
```
63+
protocol=https
64+
host=<TARGET_HOST>
65+
username=<USERNAME>
66+
password=<TOKEN_OR_PASSWORD>
67+
```
68+
69+
### 4. Write Credentials to /root/.netrc
70+
71+
Parse the `username` and `password` from the credential helper output, then write or append to `/root/.netrc`:
72+
73+
```bash
74+
echo "machine <TARGET_HOST> login <USERNAME> password <TOKEN_OR_PASSWORD>" >> /root/.netrc
75+
chmod 600 /root/.netrc
76+
```
77+
78+
If `/root/.netrc` already contains an entry for the same host, update the existing entry instead of appending a duplicate.
79+
80+
### 5. Retry the Go Mod Command
81+
82+
After writing the credentials, retry the original `go mod` command.
83+
84+
## Complete Example
85+
86+
Suppose `go mod tidy` fails with:
87+
88+
```
89+
go: module git.example.com/org/repo: reading https://git.example.com/org/repo?go-get=1: 401 Unauthorized
90+
```
91+
92+
or
93+
94+
```
95+
go: module git.example.com/org/repo: git ls-remote -q --end-of-options origin in /root/go/pkg/mod/cache/vcs/......: exit status 128:
96+
remote: The project you were looking for could not be found or you don't have permission to view it.
97+
fatal: repository 'https://git.example.com/org/repo' not found
98+
```
99+
100+
Execute the following:
101+
102+
```bash
103+
# Step 1: Check credential helper
104+
git config --get credential.helper
105+
# Possible: /app/agent/bin/agent git-credential-helper
106+
# Or: store
107+
108+
# Step 2: Retrieve credentials using the configured helper
109+
echo -e "protocol=https\nhost=git.example.com\n" | git credential fill
110+
# Output:
111+
# protocol=https
112+
# host=git.example.com
113+
# username=oauth2
114+
# password=glpat-xxxxxxxxxxxx
115+
116+
# Step 3: Write to .netrc
117+
echo "machine git.example.com login oauth2 password glpat-xxxxxxxxxxxx" >> /root/.netrc
118+
chmod 600 /root/.netrc
119+
120+
# Step 4: Retry
121+
go mod tidy
122+
```
123+
124+
## Notes
125+
126+
- Always set `/root/.netrc` file permissions to `600` to protect credentials
127+
- Before writing to `.netrc`, check if an entry for the same host already exists to avoid duplicates
128+
- If the credential helper returns empty or fails, inform the user that credentials are not available and ask for manual intervention
129+
- This rule only applies when `go mod` encounters 40x errors; do not preemptively write `.netrc` entries
130+
- If `GONOSUMCHECK` or `GONOSUMDB` environment variables need to be set for private modules, configure them as well based on the host
131+
- **NEVER EXPOSE CREDENTIALS IN MODEL RESPONSE**: Sensitive information such as `username` and `password` obtained from the credential helper must only be used for writing to `/root/.netrc`. Never display credentials in chat responses, log output, or any user-facing text

0 commit comments

Comments
 (0)