Summary
Registering a private github.com repo as a skill pack fails to authenticate. QM's git clone sends the credential as Authorization: Bearer <token>, but GitHub's git-over-HTTPS transport does not honor the Bearer scheme — it only accepts HTTP Basic. The request therefore authenticates as anonymous and the clone aborts, even with a valid fine-grained PAT.
Version
Observed at pinned commit 7f2c916360f1797a8ff2a77ce2ce40c5fabab087.
Evidence (dummy credentials only — no real secrets)
Endpoint https://github.com/<owner>/<private-repo>/info/refs?service=git-upload-pack:
- No auth →
HTTP 401, WWW-Authenticate: Basic realm="GitHub".
Authorization: Bearer <dummy> → HTTP 401, WWW-Authenticate: Basic realm="GitHub" — byte-identical headers to the anonymous case, so Bearer is not processed on the git transport.
Authorization: Basic base64("x-access-token:<PAT>") → GitHub processes the Basic scheme (a valid PAT returns 200).
Root cause (source)
src/skills/pack-fetcher.ts, resolvePackAuth (~L132-134):
const header = credential.injection?.header?.trim() || "Authorization";
const scheme = credential.injection?.scheme ?? "Bearer ";
return { header, value: `${scheme}${credential.secret}`, ... };
Applied via http.extraHeader in gitEnv. For a github.com git clone, Bearer yields a header GitHub ignores. The blank-slug fallback (connectorHostFor("github.com") → api.github.com, ~L58-61 / L136-139) also returns Bearer ${token} → identical failure on the clone. With GIT_TERMINAL_PROMPT=0, git falls through to credential-fill, cannot prompt, and aborts:
fatal: could not read Username for 'https://github.com': terminal prompts disabled
(exit 128).
Scope note
The Bearer default is correct for the REST API (api.github.com) — see src/api/credential-broker.ts (~L62-63). Only the git-clone path for github.com needs Basic.
Suggested fix
For github.com git-over-HTTPS remotes, authenticate with HTTP Basic — username x-access-token, PAT as password (Authorization: Basic base64("x-access-token:" + PAT)), or inject equivalent URL userinfo. Keep the Bearer default for api.github.com REST calls.
Workaround (no code change, admin API only)
Set the credential's injection.scheme = "Basic " and store the secret pre-encoded as base64("x-access-token:" + PAT), so QM emits a valid Authorization: Basic <base64>. The admin CREATE UI does not expose injection.scheme, so this is API-only.
Filed from a downstream deployment. Internal tracker ref: LAR-989.
Summary
Registering a private github.com repo as a skill pack fails to authenticate. QM's git clone sends the credential as
Authorization: Bearer <token>, but GitHub's git-over-HTTPS transport does not honor the Bearer scheme — it only accepts HTTP Basic. The request therefore authenticates as anonymous and the clone aborts, even with a valid fine-grained PAT.Version
Observed at pinned commit
7f2c916360f1797a8ff2a77ce2ce40c5fabab087.Evidence (dummy credentials only — no real secrets)
Endpoint
https://github.com/<owner>/<private-repo>/info/refs?service=git-upload-pack:HTTP 401,WWW-Authenticate: Basic realm="GitHub".Authorization: Bearer <dummy>→HTTP 401,WWW-Authenticate: Basic realm="GitHub"— byte-identical headers to the anonymous case, so Bearer is not processed on the git transport.Authorization: Basic base64("x-access-token:<PAT>")→ GitHub processes the Basic scheme (a valid PAT returns 200).Root cause (source)
src/skills/pack-fetcher.ts,resolvePackAuth(~L132-134):Applied via
http.extraHeaderingitEnv. For a github.com git clone,Beareryields a header GitHub ignores. The blank-slug fallback (connectorHostFor("github.com")→api.github.com, ~L58-61 / L136-139) also returnsBearer ${token}→ identical failure on the clone. WithGIT_TERMINAL_PROMPT=0, git falls through to credential-fill, cannot prompt, and aborts:(exit 128).
Scope note
The Bearer default is correct for the REST API (
api.github.com) — seesrc/api/credential-broker.ts(~L62-63). Only the git-clone path for github.com needs Basic.Suggested fix
For github.com git-over-HTTPS remotes, authenticate with HTTP Basic — username
x-access-token, PAT as password (Authorization: Basic base64("x-access-token:" + PAT)), or inject equivalent URL userinfo. Keep the Bearer default forapi.github.comREST calls.Workaround (no code change, admin API only)
Set the credential's
injection.scheme = "Basic "and store the secret pre-encoded asbase64("x-access-token:" + PAT), so QM emits a validAuthorization: Basic <base64>. The admin CREATE UI does not exposeinjection.scheme, so this is API-only.Filed from a downstream deployment. Internal tracker ref: LAR-989.