Skip to content

Skill-pack git clone sends Authorization: Bearer to github.com git transport (needs Basic) → private-repo clones fail with a valid PAT #318

Description

@DrDriftwood

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions