Files
werkator/docs/prs/2026-09-05-PR#000-remote-authenticated-clone.md
T
mhoennig c6e2155485 remote: authenticated clone for private origins (#22)
repo-init/repo-add clone https repos with shared defaults.git
credentials from ~/.werkator.yml via one-shot GIT_ASKPASS
2026-09-05 13:59:09 +02:00

3.7 KiB

WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.

  • ADR 0009 — multi-repo instance: the defaults block carries shared repository-level keys, read by ConfigLoader, never directly by consumers.
  • docs/deployment.md — registry setup: repo-add clones, initialises, and prints the registry entry.

The Problem

tools/remote werkator repo-add <private-https-url> fails on the host with could not read Username. The clone runs anonymously, but the credentials exist only in the instance file's defaults.git block — which the script never consults. Registering a private repository therefore needs a manual SSH session today.

Non-Goals

The script still does not write ~/.werkator.yml: registering stays the operator's decision. No SSH-URL support: the forge is reached over https from the host. No new config keys: defaults.git.account/defaults.git.token already exist.

The Scenarios

Feature: authenticated clone for private origins

Background

  • The shared credentials live in ~/.werkator.yml under defaults.git (ADR 0009).
  • Public origins and instances without shared credentials must keep cloning anonymously.

Scenario#000.01: Private https origin clones with shared credentials

  • Given defaults.git.account/defaults.git.token in ~/.werkator.yml on the host
  • When tools/remote werkator repo-add <private-https-url> runs
  • Then the clone authenticates with those credentials and succeeds.
Verified by
  • Manual stub-git test: URL carries account@, askpass answers the token, GIT_TERMINAL_PROMPT=0.

Scenario#000.02: Public origin clones anonymously

  • Given no shared credentials (or a public repository)
  • When repo-add or repo-init runs
  • Then the clone runs exactly as before, without authentication.
Verified by
  • Local helper test against a file:// origin with and without an instance file.

Scenario#000.03: Token never leaks locally

  • Given an authenticated clone
  • When the command runs from the workstation
  • Then the token appears in neither the local process list nor a repository config.
Verified by
  • Code inspection: the token is read on the host and passed via a one-shot GIT_ASKPASS script.

The Solution

tools/remote gained a clone_repo helper used by both repo-init and repo-add. For https:// URLs it ships a small Python helper (base64-encoded, so no $ is expanded locally) to the host. The helper reads defaults.git.account/defaults.git.token from ~/.werkator.yml, puts the account into the URL, and hands the token to git via a one-shot 0700 GIT_ASKPASS script deleted in finally. Without credentials it falls back to the plain anonymous clone; non-https URLs clone unchanged. docs/deployment.md documents that the shared credentials must exist before cloning a private repository.

Open Questions

  • None.

Attachments

Adding a Gitea repository — example

From the workstation, clone and initialise, then register:

tools/remote --env-file .env.<instance> werkator repo-add https://gitea.example.org/<owner>/<repo>.git [<name>]

Add the printed entry to ~/.werkator.yml under repositories:, then restart the service. A public repository needs nothing else: the clone runs anonymously. A private repository needs shared credentials once on the host, in ~/.werkator.yml of the service user, before cloning (token: Gitea → Settings → Applications → Generate Token, scope read:repository):

defaults:
  git:
    account: <gitea-user>
    token: <token>