Summary
The GH_{OWNER} / GH_{OWNER}__{REPO} secret naming convention that enables skill resolution from private GitHub repos does not apply to template or harness-config imports. A user who sets up a GH_ACME_CORP project secret can fetch skills from gh://acme-corp/skills-repo/my-skill but cannot import templates or harness-configs from https://github.com/acme-corp/templates using the same credential.
Additionally, hub-level (global-scope) imports have no auth mechanism at all.
Current State
| Mechanism |
Project: GH_ convention |
Project: GITHUB_TOKEN |
Hub-level auth |
| Skill resolution |
✅ |
✅ |
❌ |
| Template import |
❌ |
✅ |
❌ |
| Harness-config import |
❌ |
✅ |
❌ |
| CLI harness-config install |
❌ |
❌ |
❌ |
How it works for skills (the reference implementation)
pkg/agent/github_skill_resolver.go:155 implements a 5-level cascade:
- Explicit
?token=SECRET_NAME on the gh:// URI
- Repo-specific
GH_{OWNER}__{REPO} from project secrets
- Owner-level
GH_{OWNER} from project secrets
- Default
GITHUB_TOKEN
- Unauthenticated
Key helpers: deriveGitHubTokenKey(owner, repo), deriveGitHubOwnerKey(owner), normalizeGitHubName(name) — all private to the agent package.
Why it doesn't work for templates/harness-configs
All remote imports funnel through fetchRemoteForImport (pkg/hub/resource_import.go:269-296), which only checks for:
- A GitHub App installation token (project scope)
- A single
GITHUB_TOKEN project secret
There is no URL parsing to derive owner/repo, no GH_ convention lookup, and no hub-scope secret query.
CLI harness-config install is entirely unauthenticated
cmd/harness_config_install.go:131 calls FetchRemoteTemplate with no auth token at all. Private repo installs always fail.
Proposed Change
1. Extend fetchRemoteForImport with GH_ convention lookup
- Parse the source URL to extract GitHub owner (and optionally repo)
- Derive
GH_{OWNER}__{REPO} and GH_{OWNER} keys
- Look them up in project secrets before falling back to
GITHUB_TOKEN
- File:
pkg/hub/resource_import.go:269
2. Add hub-scope secret fallback for global imports
- When
projectID == "", look up GH_{OWNER}__{REPO}, GH_{OWNER}, and GITHUB_TOKEN at secret.ScopeHub
- File: same function, add hub-scope branch
3. Fix CLI harness-config install auth
- Accept a
--token flag or read GITHUB_TOKEN from environment
- File:
cmd/harness_config_install.go:131
4. Extract shared token-derivation helpers
- Move
normalizeGitHubName, deriveGitHubTokenKey, deriveGitHubOwnerKey from pkg/agent/github_skill_resolver.go to a shared package (e.g., pkg/ghauth/)
- Files:
pkg/agent/github_skill_resolver.go:125-141 → shared package
Key Code References
| File |
Lines |
What |
pkg/agent/github_skill_resolver.go |
125-189 |
GH_ convention (reference implementation) |
pkg/hub/resource_import.go |
269-296 |
fetchRemoteForImport — the auth gap |
pkg/config/remote_templates.go |
169-211 |
FetchRemoteTemplate — actual fetch |
cmd/harness_config_install.go |
107-150 |
CLI install with no auth |
pkg/hub/httpdispatcher.go |
776-823 |
ProvisionCredentials assembly |
pkg/secret/secret.go |
199-201 |
ScopeHub constant |
Sizing
Small if only fetchRemoteForImport gets the GH_ lookup (one function, ~20 lines). Medium if hub-level auth, CLI auth, and shared helper extraction are included.
Summary
The
GH_{OWNER}/GH_{OWNER}__{REPO}secret naming convention that enables skill resolution from private GitHub repos does not apply to template or harness-config imports. A user who sets up aGH_ACME_CORPproject secret can fetch skills fromgh://acme-corp/skills-repo/my-skillbut cannot import templates or harness-configs fromhttps://github.com/acme-corp/templatesusing the same credential.Additionally, hub-level (global-scope) imports have no auth mechanism at all.
Current State
How it works for skills (the reference implementation)
pkg/agent/github_skill_resolver.go:155implements a 5-level cascade:?token=SECRET_NAMEon thegh://URIGH_{OWNER}__{REPO}from project secretsGH_{OWNER}from project secretsGITHUB_TOKENKey helpers:
deriveGitHubTokenKey(owner, repo),deriveGitHubOwnerKey(owner),normalizeGitHubName(name)— all private to theagentpackage.Why it doesn't work for templates/harness-configs
All remote imports funnel through
fetchRemoteForImport(pkg/hub/resource_import.go:269-296), which only checks for:GITHUB_TOKENproject secretThere is no URL parsing to derive owner/repo, no
GH_convention lookup, and no hub-scope secret query.CLI harness-config install is entirely unauthenticated
cmd/harness_config_install.go:131callsFetchRemoteTemplatewith no auth token at all. Private repo installs always fail.Proposed Change
1. Extend
fetchRemoteForImportwith GH_ convention lookupGH_{OWNER}__{REPO}andGH_{OWNER}keysGITHUB_TOKENpkg/hub/resource_import.go:2692. Add hub-scope secret fallback for global imports
projectID == "", look upGH_{OWNER}__{REPO},GH_{OWNER}, andGITHUB_TOKENatsecret.ScopeHub3. Fix CLI harness-config install auth
--tokenflag or readGITHUB_TOKENfrom environmentcmd/harness_config_install.go:1314. Extract shared token-derivation helpers
normalizeGitHubName,deriveGitHubTokenKey,deriveGitHubOwnerKeyfrompkg/agent/github_skill_resolver.goto a shared package (e.g.,pkg/ghauth/)pkg/agent/github_skill_resolver.go:125-141→ shared packageKey Code References
pkg/agent/github_skill_resolver.gopkg/hub/resource_import.gofetchRemoteForImport— the auth gappkg/config/remote_templates.goFetchRemoteTemplate— actual fetchcmd/harness_config_install.gopkg/hub/httpdispatcher.gopkg/secret/secret.goSizing
Small if only
fetchRemoteForImportgets the GH_ lookup (one function, ~20 lines). Medium if hub-level auth, CLI auth, and shared helper extraction are included.