fix: attach task token when cloning actions from self-hosted instance on a different host (#1056)

When `DEFAULT_ACTIONS_URL=self`, action clone URLs (`uses: owner/repo@ref`) are
built from the Gitea **AppURL** (`gitea_default_actions_url`), but
`shouldCloneURLUseToken` compared the clone URL host only against the runner's
**registered address** (`GitHubInstance`).

When the runner registers with a different hostname than AppURL — same instance,
different DNS (e.g. `gitea.local` vs `gitea.my-nas.lan`, internal vs external) —
the strict `u1.Host == u2.Host` check returns false, so the task token is **not**
attached and the action clone goes out anonymously. Against an instance with
`REQUIRE_SIGNIN_VIEW=true` this fails with:

```
Unable to clone https://gitea.example/owner/action refs/heads/v1: authentication required
```

The current workaround is to make the runner's registered host exactly match
`AppURL`. This PR removes the need for that.

Refs: https://github.com/go-gitea/gitea/issues/27933

## Change

- `shouldCloneURLUseToken` now trusts the clone URL when its host matches **either**
  the registered instance (`GitHubInstance`) **or** the self-hosted default-actions
  instance (`DefaultActionInstance`). Embedded basic auth is still rejected, and the
  empty-host cases are unchanged.
- A new `Config.DefaultActionInstanceIsSelfHosted` flag gates the second candidate.
  It is set in the daemon layer (`run/runner.go`, `exec.go`), where `github.com` and
  a configured `GithubMirror` are distinguishable, so the token is **never** attached
  for off-instance hosts.Reviewed-on: https://gitea.com/gitea/runner/pulls/1056
Reviewed-by: Zettat123 <39446+zettat123@noreply.gitea.com>
Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni
2026-06-30 16:18:12 +00:00
committed by Nicolas
parent b7f6b6d90a
commit 745b0ab6e4
6 changed files with 125 additions and 49 deletions
+5 -4
View File
@@ -443,10 +443,11 @@ func runExec(ctx context.Context, execArgs *executeArgs) func(cmd *cobra.Command
NoSkipCheckout: execArgs.noSkipCheckout,
// PresetGitHubContext: preset,
// EventJSON: string(eventJSON),
ContainerNamePrefix: "GITEA-ACTIONS-TASK-" + eventName,
ContainerMaxLifetime: maxLifetime,
ContainerNetworkMode: container.NetworkMode(execArgs.network),
DefaultActionInstance: execArgs.defaultActionsURL,
ContainerNamePrefix: "GITEA-ACTIONS-TASK-" + eventName,
ContainerMaxLifetime: maxLifetime,
ContainerNetworkMode: container.NetworkMode(execArgs.network),
DefaultActionInstance: execArgs.defaultActionsURL,
DefaultActionInstanceIsSelfHosted: execArgs.defaultActionsURL != "" && execArgs.defaultActionsURL != "https://github.com",
PlatformPicker: func(_ []string) string {
return execArgs.image
},
+18 -8
View File
@@ -299,6 +299,15 @@ func (r *Runner) getDefaultActionsURL(task *runnerv1.Task) string {
return giteaDefaultActionsURL
}
// isSelfHostedActionsURL reports whether actions resolve to this self-hosted Gitea
// (DEFAULT_ACTIONS_URL=self), i.e. gitea_default_actions_url is AppURL rather than
// github.com (which may be mirror-substituted by getDefaultActionsURL). Only then may the
// task token be attached to action clone URLs on the actions instance host.
func (r *Runner) isSelfHostedActionsURL(task *runnerv1.Task) bool {
giteaDefaultActionsURL := task.Context.Fields["gitea_default_actions_url"].GetStringValue()
return giteaDefaultActionsURL != "" && giteaDefaultActionsURL != "https://github.com"
}
func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.Reporter) (err error) {
defer func() {
if r := recover(); r != nil {
@@ -446,14 +455,15 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
EnableIPv4: r.cfg.Container.NetworkCreateOptions.EnableIPv4,
EnableIPv6: r.cfg.Container.NetworkCreateOptions.EnableIPv6,
},
ContainerOptions: r.cfg.Container.Options,
ContainerDaemonSocket: r.cfg.Container.DockerHost,
Privileged: r.cfg.Container.Privileged,
DefaultActionInstance: r.getDefaultActionsURL(task),
PlatformPicker: r.labels.PickPlatform,
Vars: task.Vars,
ValidVolumes: r.cfg.Container.ValidVolumes,
InsecureSkipTLS: r.cfg.Runner.Insecure,
ContainerOptions: r.cfg.Container.Options,
ContainerDaemonSocket: r.cfg.Container.DockerHost,
Privileged: r.cfg.Container.Privileged,
DefaultActionInstance: r.getDefaultActionsURL(task),
DefaultActionInstanceIsSelfHosted: r.isSelfHostedActionsURL(task),
PlatformPicker: r.labels.PickPlatform,
Vars: task.Vars,
ValidVolumes: r.cfg.Container.ValidVolumes,
InsecureSkipTLS: r.cfg.Runner.Insecure,
}
rr, err := runner.New(runnerConfig)