Skip to content

feat: support GH_-prefixed token convention for template and harness-config imports from private repos #1419

Description

@ptone

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:

  1. Explicit ?token=SECRET_NAME on the gh:// URI
  2. Repo-specific GH_{OWNER}__{REPO} from project secrets
  3. Owner-level GH_{OWNER} from project secrets
  4. Default GITHUB_TOKEN
  5. 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:

  1. A GitHub App installation token (project scope)
  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig & settings: schema, precedence, env-var mapping, storage & migrationtype:featureNew feature or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions