Skip to content

GitHub auth for containerized runs: fine-grained PAT, secrets injection, multi-tenant identity #732

Description

@mfittko

Problem

Containerized dev-loop runs need GitHub authentication for git operations, gh CLI, PR comments, and push. No dedicated token contract exists — only scattered GH_TOKEN mentions.

Decisions (concrete)

# Decision Resolution
1 Token type Fine-grained PAT (not classic PAT, not GitHub App — MVP)
2 Required scopes Contents: Read & Write, Pull requests: Read & Write, Metadata: Read — no org/admin/delete
3 Injection mechanism docker run -e GH_TOKEN=$GH_TOKEN — no Docker secrets, no mounted credential files for MVP
4 Identity model Single bot PAT shared across all containers on one host
5 Host-side storage Operator chooses one: macOS Keychain → loaded into shell env, .env file (gitignored), or plain env var — injected at docker run time
6 Token lifetime Fine-grained PATs support 1-year max; operator sets expiry; rotation is manual for MVP
7 Stale-token detection Container startup validates GH_TOKEN present + calls gh auth status --hostname github.com before any git/gh op
8 Multi-container parallel Same token re-used; fine-grained PATs support concurrent requests without contention

Scope

  • Token specification: type, required scopes, lifetime window
  • Injection contract: GH_TOKEN env var via docker run -e — no alternatives for MVP
  • Host-side storage: documented options (keychain, .env, env var) with security guidance
  • Startup validation: GH_TOKEN present + gh auth status check before first operation
  • Error surfaces: missing token → non-zero exit with clear message; expired/invalid → same
  • Rotation strategy: documented manual rotation steps; automated rotation is out of scope

Non-goals

  • GitHub App installation tokens (post-MVP upgrade path)
  • OAuth flow or interactive browser login inside container
  • Docker secrets or mounted credential files
  • Automated token renewal / refresh flows
  • Multi-node token distribution (single-machine only)
  • Replacing host gh auth — container concern only
  • Per-run ephemeral tokens

Acceptance Criteria

  • AC1 — Container startup fails with a human-readable error if GH_TOKEN is absent
  • AC2 — Container startup fails with a human-readable error if GH_TOKEN is invalid or expired (gh auth status non-zero)
  • AC3 — git push, gh pr comment, and gh pr create all succeed inside container when a valid fine-grained PAT with required scopes is injected via docker run -e GH_TOKEN=...
  • AC4 — README section documents required PAT scopes, how to create the token, and all three host-side storage options
  • AC5 — Two containers run in parallel sharing the same token without auth failures
  • AC6 — Container does not write or cache GH_TOKEN to disk inside the container image or filesystem
  • AC7 — Missing or invalid token produces an exit code ≠ 0 so calling orchestration can detect and surface the failure

Definition of Done

  • Startup validation script/code exists and is covered by at least one integration test with a missing-token case
  • docker run -e GH_TOKEN pattern is used in all container invocation examples in docs and code
  • Host-side storage options documented in the Docker environment README section (parent Docker image for pi-dev-loops: deterministic build, smoke test, CI parity #716)
  • Parallel-container test or documented manual verification shows no token contention
  • All ACs above are checked green in the PR that closes this issue

AC / DoD Matrix

AC DoD gate Notes
AC1 Startup validation script Exit ≠ 0 + message on missing token
AC2 Startup validation script + integration test gh auth status non-zero path
AC3 Integration test (or manual smoke) All three gh/git ops verified
AC4 Docs PR merged README section in parent #716
AC5 Parallel-container test / manual log No 401/403 under shared PAT
AC6 Image inspection / Dockerfile review No secret leak in layers
AC7 Startup script + CI check Orchestration can catch failure

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions