docs: simplify GitHub credential guidance (#3630)

This commit is contained in:
Carlos Florêncio
2026-09-12 22:51:06 +01:00
committed by GitHub
parent 56bc954001
commit f150dd32d1
6 changed files with 301 additions and 34 deletions
@@ -0,0 +1,149 @@
---
created: 2026-09-12
status: complete
requirements:
- REQ-INTEGRATIONS-GITHUB-AUTHENTICATION-001
system_design:
- ../../specs/integrations/system-design/github-authentication-01.md
- ../../specs/integrations/system-design/github-authentication-03.md
legacy_specs: []
---
# Fix Plan: Explain GitHub Credential Upgrade Recovery
Issue: [#3071](https://github.com/kdlbs/kandev/issues/3071).
## Overview
The issue remains useful as a documentation repair. Its original runtime proposals need separate treatment.
This package records the historical default change and keeps the public task-access guidance concise.
The upgrade-specific recovery runbook is deferred because it is temporary migration guidance.
It preserves the current policy contract and uses one documentation work order.
## Investigation evidence
Investigation date: 2026-09-12. Local HEAD and remote main both equal
`49df3794bc15d610988acc674637384ce8f1d4be`. Latest stable: v0.94.0, published 2026-09-09.
The issue was opened on 2026-08-26 against v0.91.0+ and contains no attachments or comments.
| Concern | Current evidence | Disposition |
| --- | --- | --- |
| Historical managed default | `github.Store.addTaskGitCredentialsMode` still adds the column with `DEFAULT 'managed'`, including in v0.94.0. | The historical upgrade behavior remains. |
| New workspace default | PR #2156, commit `190eeddbc`, persists executor access. First containing stable tag: v0.84.1. | Already fixed before this issue. |
| Existing workspace policy | `InitializeFreshWorkspaceDefaults` skips existing stores. Missing settings still resolve to managed. | Preserve intentional managed choices. |
| Stale prepared checkout | PR #3077, commit `c2e2b3a43`, reconciles origins before prepared launches. | Fixed in v0.92.0. |
| Host clone protocol | PR #3078, commit `e4d17b3925`, resolves host-specific protocol dynamically. | Fixed in v0.92.0. |
| Preflight | `PreflightManagedGitCredentials` validates persisted repository identity and skips executor mode. | It does not prove SSH or HTTPS authentication. |
| Public recovery guide | The **Choose task Git credentials** section explains the current modes and entry points. | Keep durable task-access guidance concise; defer the temporary upgrade runbook. |
## Confirmed root cause and reproduction
The original column migration supplied managed mode to existing settings rows.
The current new-workspace initializer deliberately excludes existing installations.
The database stores the resulting policy without evidence of whether the user selected it.
A missing settings row also uses the managed compatibility fallback.
The smallest current reproduction uses an existing GitHub store with no workspace settings row.
Run `InitializeFreshWorkspaceDefaults`, then read the workspace settings. The policy remains managed.
`TestInitializeFreshWorkspaceDefaultsSkipsExistingGitHubStore` proves this behavior through the real SQLite store.
The public guide does not connect this behavior to the reported healthy-host-login symptom.
There is no production regression to correct within this package.
The documentation acceptance review currently fails because the historical explanation and recovery procedure are absent.
A code test that expects automatic policy conversion would contradict the current design.
## Scope
### In scope
- Explain the historical managed default and the current new-workspace default.
- Summarize task-access selection and the managed, user-managed, and remote-executor boundaries.
- Keep the public guidance concise and scan-friendly.
- Qualify the existing description of managed access as an opt-in policy for historical workspaces.
### Out of scope
- Automatic conversion of saved or missing policies to executor mode.
- Conditional policy selection based on App presence or temporary credential health.
- A new transport-authentication probe, launch warning, settings UI, or schema migration.
- A temporary upgrade-specific recovery runbook in the public guide.
- Reimplementation of #3069 or #3070.
- Editing generated changelog history or closing the entire issue automatically.
## Technical approach
Update the existing task-access section in `docs/public/integrations.md` with short bullets.
Keep workspace API authentication separate from credentials inside task processes.
Use **Workspace GitHub access**, **Change connection** when an automation connection exists, **Connect GitHub** otherwise, and **Inherit executor Git credentials** as the existing control labels.
Explain saved policy preservation, task-only executor selection, and the need for a new terminal after a launch or resume.
Do not add a temporary upgrade-specific recovery section; keep its investigation evidence in this plan.
Keep the origin, service-user, and preflight findings in this plan as evidence for a possible future
runbook. Do not publish those migration details in the current public guide.
The current specifications intentionally preserve existing policies.
This package follows that boundary and adds only documentation criterion `AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.13`.
No new ADR is necessary because the runtime boundary does not change.
## Tests
Existing source-backed evidence covers the preserved behavior:
- `workspace_defaults_test.go`: existing-store fallback, explicit managed preservation, and new executor defaults.
- `executor_resume_clone_transport_test.go`: policy-driven origins and prepared launch reconciliation.
- `executor_credentials_preflight_test.go`: executor mode skips managed identity admission.
All paths are under `apps/backend/internal/github` or `apps/backend/internal/orchestrator/executor` respectively.
The focused command passed in both packages during this investigation:
```bash
(cd apps/backend && go test -tags fts5 ./internal/github ./internal/orchestrator/executor -run 'TestInitializeFreshWorkspaceDefaultsSkipsExistingGitHubStore|TestInitializeWorkspaceDefaultsPersistsExecutorAndBindsActiveCLI|TestInitializeWorkspaceDefaultsPreservesExistingWorkspaceState|TestLaunchPreparedSession_ExistingWorkspace_ReconcilesGitHubOriginsBeforeAgentStart|TestEnsureRepoLocalPath_ReconcilesGitHubOriginForCredentialPolicy|TestPreflightManagedGitCredentialsSkipsWhenExecutorModePolicy' -count=1)
```
No new unit or browser test is needed for a documentation-only correction.
Task 01 owns the public document validation and manual acceptance checklist.
## Companion packages
The completed packages remain unchanged because this repair changes none of their implementation scope:
- [New workspace defaults](../new-workspace-github-access-defaults/plan.md).
- [Prepared workspace origins](../prepared-workspace-origin-reconciliation/plan.md).
- [Executor clone transport](../github-executor-clone-transport/plan.md).
- [Managed admission](../managed-git-credential-admission-repair/plan.md).
## Work orders
- [x] [Task 01: Document upgrade recovery](task-01-document-upgrade-recovery.md).
## Verification results
Investigation: the focused Go command passed in both packages.
Package validation passed: catalog validation (264 decisions, 818 specifications), specification lint, and `git diff --check`.
Public documentation implementation completed in `docs/public/integrations.md` and
`docs/public/use-kandev.md`. The integration guide now uses short bullets for historical saved
policies, conditional task-access entry points, managed and executor credentials, task-only
executor selection, fresh terminals, and managed, user-managed, and remote-executor boundaries.
The temporary upgrade-specific recovery section was removed from the public guide; its
investigation evidence remains here for a later runbook if needed.
Documentation validation passed: public-doc tests (62), public-doc validation (46 pages), and
the three work-order acceptance conditions.
Build validation passed: `make -C apps/backend build` and
`pnpm --filter @kandev/web build`.
Follow-up source review corrected the disconnected-workspace entry point and the fresh-terminal
recovery instruction; the public upgrade/recovery section was later removed as temporary guidance.
Review follow-up also clarified that historical workspaces may preserve either saved task Git
policy, aligned the plan's control labels with the UI, and completed the work-order touched-file
inventory. Focused post-fixup documentation validation passed: public-doc validation (46 pages),
catalog validation (264 decisions and 818 specifications), specification lint, and
`git diff --check`.
No temporary tests, instances, or database mutations were needed.
## Risks
Saved managed policies cannot distinguish migration defaults from deliberate user choices.
A blanket conversion can change credentials for working automation.
An App-only heuristic also excludes valid PAT and named CLI managed connections.
A host credential check cannot establish credential availability inside a remote executor.
The broader transport preflight proposal remains deferred and requires its own executor-aware design.
Completing this package addresses the documentation gap, not every proposal in #3071.
@@ -0,0 +1,112 @@
---
id: "01-document-upgrade-recovery"
title: "Document GitHub credential upgrade recovery"
status: done
wave: 1
depends_on: []
plan: "plan.md"
requirements:
- REQ-INTEGRATIONS-GITHUB-AUTHENTICATION-001
acceptance_criteria:
- AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.13
system_design:
- ../../specs/integrations/system-design/github-authentication-01.md
- ../../specs/integrations/system-design/github-authentication-03.md
---
# Task 01: Document Upgrade Recovery
## Summary
Keep the public task-access guidance concise and consistent with preserved policies.
Record the upgrade recovery evidence internally for possible later use.
## In scope
- Qualify the managed opt-in description for historical workspaces.
- Keep the existing **Choose task Git credentials** section focused on durable user actions.
- Describe explicit policy selection, task-only executor inheritance, and a fresh terminal after launch or resume.
- Distinguish managed checkouts, user-managed checkouts, and remote executors in short bullets.
- Keep the upgrade investigation evidence in this plan instead of adding a temporary public runbook.
- Include the checklist in Acceptance as a manual documentation review.
## Out of scope
Production code, test code, UI copy, automatic migration, credential probes, a temporary public
upgrade runbook, and generated changelog edits.
## Acceptance
1. The guide explains historical managed defaults, current executor defaults, and preservation of existing workspace policies.
2. Task-access bullets describe explicit executor selection, a fresh terminal after launch or resume,
and the managed, user-managed, and remote-executor boundaries.
3. The guide does not promise automatic policy conversion or comprehensive credential preflight,
and it does not add a temporary upgrade-specific recovery runbook.
## Verification
Run from the repository root:
```bash
node --test scripts/validate-public-docs.test.mjs
node scripts/validate-public-docs.mjs
python3 scripts/list-docs.py validate
python3 scripts/lint-spec-files.py --all
git diff --check
```
Review the three acceptance conditions against the final document and current source.
No new test is required because the correction changes documentation only.
## Files likely touched
- `docs/public/integrations.md`
- `docs/public/use-kandev.md` (cross-page summary)
- `docs/plans/github-credential-upgrade-recovery/plan.md` (status and results)
- `docs/plans/github-credential-upgrade-recovery/task-01-document-upgrade-recovery.md` (status and results)
## Dependencies
None. The origin fixes already exist in current main and v0.94.0.
## Risks
Host `gh` authentication does not establish task Git transport access.
Managed clone worktrees share remote settings. A running agent retains its existing credential environment.
The procedure must not suggest broad manual rewrites, token disclosure, or automatic policy changes.
## Parallelism
`sequential`
## Inputs
- [Requirement](../../specs/integrations/requirements/github-authentication.md), criterion 001.13.
- [Design](../../specs/integrations/system-design/github-authentication-03.md#upgrade-recovery-guidance).
- [Investigation](plan.md#investigation-evidence).
- `apps/backend/internal/github/store.go`: `addTaskGitCredentialsMode`, `defaultWorkspaceSettings`.
- `apps/backend/internal/github/workspace_defaults.go`: existing-installation guard.
- `apps/backend/internal/orchestrator/executor/executor_credentials.go`: managed admission scope.
- `apps/backend/internal/orchestrator/executor/executor_execute.go`: prepared launch ordering.
- Existing **Choose task Git credentials** section in the public guide.
## Results
Implemented concise task-access guidance in
[`docs/public/integrations.md`](../../public/integrations.md). The guide now explains the
historical `managed` compatibility policy, current executor inheritance, preserved saved
policies, conditional **Connect GitHub** and **Change connection** entry points, task-only
executor selection, fresh-terminal requirements, and managed, user-managed, and remote-executor
boundaries. The cross-page summary in
[`docs/public/use-kandev.md`](../../public/use-kandev.md) no longer describes managed access as the
default for new workspaces.
The temporary upgrade-specific recovery section was removed from the public guide; the
investigation evidence remains in the plan for possible later documentation.
All three acceptance conditions pass by manual review. Public-doc tests (62), public-doc
validation (46 pages), catalog validation, specification lint, focused Go tests, both backend and
web builds, and `git diff --check` pass. The final documentation pass removed the temporary
upgrade-specific recovery section, retained concise task-access guidance, and aligned the plan
and work-order scope. Post-fixup focused documentation validation passed: public-doc validation
(46 pages), catalog validation (264 decisions and 818 specifications), specification lint, and
`git diff --check`.
+18 -33
View File
@@ -144,13 +144,24 @@ select **Save changes** once. GitHub App creation, import, and installation rema
GitHub workflows. The help control beside **Task Git access** explains the effective credential
path on desktop hover or focus and in a touch-accessible drawer on mobile.
- **Managed workspace credentials** (an opt-in policy) uses the selected workspace PAT, named GitHub
CLI account, or GitHub App through Kandev's short-lived, task/repository-scoped broker. Kandev
configures `agentctl` as Git's credential helper so an attached repository can redeem its
matching lease on demand; the returned credential is not written to the repository or Git
configuration. A separate broker-aware shim handles `gh`. The task receives neither the stored
PAT nor an App private key. An executor-profile `GH_TOKEN` or `GITHUB_TOKEN` deliberately takes
precedence for that task.
- Existing workspaces keep their saved task-access policy during upgrades. A historical workspace
may still use managed mode. New workspaces default to **Inherit executor Git credentials**.
- Select **Change connection** when the workspace has an automation connection. Select **Connect
GitHub** when it does not. Both entry points show **Task Git access**.
- **Managed workspace credentials** use the selected PAT, named GitHub CLI account, or GitHub App
through Kandev's task/repository-scoped broker. Kandev provides a short-lived Git helper and `gh`
shim; stored PATs and App private keys are not exposed to the task. An executor-profile
`GH_TOKEN` or `GITHUB_TOKEN` takes precedence.
- **Inherit executor Git credentials** does not install Kandev's helper or `gh` shim. Local and
Worktree tasks use host Git credentials. Docker, SSH, and cloud tasks use credentials configured
in the executor.
- A disconnected workspace can select **Inherit executor Git credentials** and save only the
task-access setting. It does not need a PAT or GitHub App.
- The policy applies to newly launched task processes. After a launch or resume, use **New
terminal** to create a fresh shell process. Reopening or reconnecting the same terminal does not
refresh its environment.
- For Kandev-managed GitHub checkouts, Local and Worktree preparation follows the host's current
`gh` clone protocol. A user-managed checkout keeps its existing origin.
For a managed **Improve Kandev** task, Kandev keeps the task attached to the canonical
`kdlbs/kandev` repository. Before the first launch, the workspace automation connection resolves
@@ -161,15 +172,6 @@ connection does not need a fork. An App connection without direct write access c
automatic personal fork, so managed fork preparation fails closed; the Improve Kandev issue-only
option remains available.
- **Inherit executor Git credentials** is the default for newly created workspaces and does not
install Kandev's broker helper or `gh` shim. Local
and Worktree tasks use credentials already visible to the host Git process (including SSH).
Docker, SSH, and cloud tasks use only credentials intentionally configured in that executor.
For Kandev-managed GitHub checkouts, Local and Worktree preparation also updates `origin` to the
host's configured `gh` clone protocol. Selecting SSH therefore lets Git conditional includes that
match `remote.*.url` apply; switching back to managed credentials restores the canonical HTTPS
origin. Repositories you registered from an existing local checkout are never rewritten.
If Git rejects a managed checkout with **detected dubious ownership**, the Kandev service account
and the checkout owner do not match. Repository preparation stops and the session error identifies
the ownership boundary; inspect the service unit and the managed home/repository owner, then
@@ -293,23 +295,6 @@ deletes only the encrypted catalog credential bundle, and does not delete or uni
GitHub. Remove the provider-side App separately only after confirming that no other deployment uses
it.
### Upgrade and recovery
Workspaces that existed when workspace authentication was introduced receive a **Legacy shared** connection so upgrades do not immediately lose GitHub access. It preserves the previous installation-wide resolution behavior while the workspace is migrated. Existing workspaces and their saved task-access policies are not rewritten by the new-workspace defaults. After a legacy workspace selects a PAT, named CLI account, or App installation, it cannot return to legacy mode. Copying a workspace never copies authentication or App installation bindings.
Legacy shared resolution checks an authenticated host `gh` CLI first, then backend `GITHUB_TOKEN`, backend `GH_TOKEN`, and finally the old stored `GITHUB_TOKEN`/`github_token` secret. Those ambient sources are migration compatibility only; configure an explicit workspace connection to make identity and access deterministic.
For recovery:
- Replace an invalid PAT or select the exact CLI account again; validation must succeed before Kandev swaps the connection.
- Run `gh auth status --hostname github.com` as the Kandev service user when a selected CLI login disappears, then sign in that account again if necessary.
- Reconnect **My GitHub identity** after authorization expiry/revocation. App automation remains available while the personal connection is invalid.
- Ask an organization owner to unsuspend or reinstall an App, restore its repository selection, or grant a reported missing permission. Refresh the workspace status afterward.
- Disconnect and repeat **Install GitHub App** when the workspace is bound to the wrong installation. Removing the binding does not uninstall the provider-side App.
- To replace compromised App root credentials, disconnect every binding, delete the catalog
registration, rotate the credentials in GitHub, and add the App again. Kandev does not rotate App
private keys, OAuth client secrets, or webhook secrets automatically.
</details>
### Configure and use the workspace
+2 -1
View File
@@ -196,7 +196,8 @@ See [Sessions and review](sessions-and-review.md) for the workbench and [Tasks a
- **Auto Approve**, permission-skipping flags, and unrestricted passthrough remove human gates inside the agent CLI. They are security decisions.
- Local and worktree sessions run on the Kandev host. Worktree separation does not limit process, filesystem, network, or credential access.
- Containers and remote executors change the boundary, but their mounted files, copied credentials, environment, daemon/socket access, and prepare scripts can reintroduce host or provider access.
- Managed GitHub task access (the default) uses task/repository-bound broker leases from the workspace automation connection. GitHub App tokens are minted for the redeemed repository; PAT and named-CLI bearer tokens retain all provider-granted scopes once delivered to the trusted agent subprocess. Personal tokens and the App private key never enter executors. Choose **Inherit executor Git credentials** in the workspace GitHub settings only when task Git and `gh` should use host-visible credentials for Local/Worktree or intentionally configured credentials for remote executors.
- **Managed GitHub task access** may remain the saved policy for historical workspaces. New workspaces default to **Inherit executor Git credentials**. Managed mode uses task/repository-bound broker leases; stored PATs and App private keys stay out of task processes.
- **Inherit executor Git credentials** uses host-visible credentials for Local and Worktree tasks, or credentials configured in remote executors. See [Choose task Git credentials](integrations.md#choose-task-git-credentials) for the credential paths and entry points.
- A profile-supplied `GITHUB_TOKEN` or `GH_TOKEN` is an explicit unmanaged override and bypasses workspace broker selection. Ambient backend tokens and the host-active `gh` account are used only by migration-only **Legacy shared** workspace connections.
- Repository, executor, and task action scripts are executable configuration. Review them like code.
- Authentication is opt-in. When it is disabled, treat anyone who can reach the backend as an operator. Keep the whole origin on loopback or a trusted network, or put it behind an authenticated TLS proxy.
@@ -32,6 +32,8 @@ GitHub credentials must not silently cross workspace boundaries. A local workspa
- **AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.11:** When a Local or Worktree task launches or resumes, the system shall inspect each attached Kandev-managed GitHub checkout before the agent starts. This behavior includes a prepared workspace that the task reuses.
- **AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.12:** The system shall reconcile each managed checkout to the canonical transport for the current task policy. It shall not rewrite an already-canonical origin or a user-managed local checkout.
- **AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.13:** The public guide shall explain historical managed defaults, preserved upgrade policies, and recovery through explicit task-access selection. It shall distinguish managed checkouts, user-managed checkouts, and remote executors.
## System design
The migrated technical source is split into [part 1](../system-design/github-authentication-01.md), [part 2](../system-design/github-authentication-02.md), [part 3](../system-design/github-authentication-03.md).
@@ -257,3 +257,21 @@ New-workspace defaults are defined by
[ADR-2026-08-02-new-workspace-github-access-defaults](../../../decisions/2026-08-02-new-workspace-github-access-defaults.md).
The system-service ownership boundary is defined by
[ADR-2026-07-31-system-service-user-continuity](../../../decisions/2026-07-31-system-service-user-continuity.md).
## Upgrade recovery guidance
`AC-INTEGRATIONS-GITHUB-AUTHENTICATION-001.13` uses the existing public integration guide.
The guide distinguishes the historical `managed` schema default from the executor default for new workspaces.
An existing policy does not record whether the user selected it or a migration supplied it.
Recovery therefore uses an explicit task-access selection through the existing workspace connection dialog.
The procedure does not infer consent from an absent App registration or current credential health.
PAT and named CLI connections also support managed task access.
Local and Worktree launches reconcile Kandev-managed origins through the existing repository preparation path.
User-managed origins remain under user control. Remote executors require credentials in their own execution environment.
The guide must not promise that host `gh auth status` proves task Git access.
The current managed admission gate validates repository identity, not inherited transport authentication.
The [upgrade recovery fix package](../../../plans/github-credential-upgrade-recovery/plan.md)
owns delivery of this guidance. It changes no runtime or persistence boundary.