Skip to content

fix(github): read app token from mounted secret - #370

Merged
kkroo merged 1 commit into
masterfrom
omar/github-token-fresh-read
Jun 12, 2026
Merged

fix(github): read app token from mounted secret#370
kkroo merged 1 commit into
masterfrom
omar/github-token-fresh-read

Conversation

@kkroo

@kkroo kkroo commented Jun 12, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip orchestrates AI agents for zero-human companies.
  • The Blockcast deployment runs k8s-backed agent jobs through the bundled claude_k8s and opencode_k8s adapters.
  • Those adapters inherit the Paperclip pod env and secret volume mounts into spawned Job pods.
  • The current Blockcast values inject paperclip-github-mcp-token into GITHUB_PERSONAL_ACCESS_TOKEN and GH_TOKEN, so each server or Job pod snapshots a 60-minute GitHub App installation token at pod creation time.
  • Long-running jobs can cross the rotator window and keep using stale GitHub credentials for gh, git, or the GitHub MCP server.
  • This pull request moves GitHub command auth to wrappers that read the mounted token file at process start.
  • The benefit is fresher credentials without broadening RBAC or requiring every agent session to rerun gh auth login.

What Changed

  • Mount paperclip-github-mcp-token as a read-only Secret volume at /paperclip/.secrets/github-token for the Blockcast Paperclip pods.
  • Remove direct GITHUB_PERSONAL_ACCESS_TOKEN / GH_TOKEN env injection from Blockcast values and set PATH plus PAPERCLIP_GITHUB_TOKEN_FILE instead.
  • Seed /paperclip/.local/bin wrappers for gh, git, and github-mcp-server; each wrapper reads the mounted token file at command startup.
  • Add a Git credential helper wrapper for https://github.com so GitHub HTTPS operations can read the same mounted token without putting token material in process args.
  • Point the baseline GitHub MCP entry at /paperclip/.local/bin/github-mcp-server.

Verification

  • helm template paperclip deploy/helm/paperclip -n paperclip -f deploy/helm/paperclip/values.blockcast.yaml > /tmp/paperclip-rendered.yaml
  • kubectl apply --dry-run=client -f /tmp/paperclip-rendered.yaml
  • yq -r '.spec.template.spec.initContainers[]? | select(.name == "seed") | .command[2]' /tmp/paperclip-rendered.yaml > /tmp/paperclip-seed.sh && sh -n /tmp/paperclip-seed.sh
  • helm lint deploy/helm/paperclip -f deploy/helm/paperclip/values.blockcast.yaml
  • Render inspection confirmed the worker and API specs have PATH and PAPERCLIP_GITHUB_TOKEN_FILE, do not render GH_TOKEN / GITHUB_PERSONAL_ACCESS_TOKEN, and mount the github-mcp-token Secret volume.

Risks

  • Existing shells that explicitly call /usr/bin/gh, /usr/bin/git, or /usr/local/bin/github-mcp-server bypass the wrappers; normal PATH-based use and the seeded MCP config use wrappers.
  • If the mounted Secret is absent or empty, GitHub commands fail loudly instead of silently falling back to stale hosts.yml credentials.
  • Nested Secret mount under /paperclip relies on Kubernetes' standard overlapping volume mount behavior; the chart render and client dry-run accept the spec.

ROADMAP.md checked: no overlapping planned core feature item for this Blockcast deployment hardening.

Model Used

  • OpenAI GPT-5 Codex, tool-enabled coding session. Exact context window not exposed in this environment.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • I will address all Greptile and reviewer comments before requesting merge

@kkroo

kkroo commented Jun 12, 2026

Copy link
Copy Markdown
Author

@allyblockcast please review head c8039fa. Focus: GitHub App token freshness path for Paperclip k8s agent jobs; ensure no token is exposed in process args and the Secret mount/wrapper approach is scoped.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
reviewed head: c8039fa

Looks good. I did not find any high-confidence Critical or Important issues in this diff.

Review Notes

  • The token is no longer rendered into GH_TOKEN / GITHUB_PERSONAL_ACCESS_TOKEN on the StatefulSet env, so the pod spec and spawned process command lines avoid carrying the installation token directly.
  • The gh and github-mcp-server wrappers read the mounted Secret file at command startup, then pass token material through environment variables to the child process rather than through process args.
  • The git wrapper scopes the credential helper to https://github.com and returns the token via Git credential-helper stdout, which avoids embedding the token in remote URLs or argv.
  • The Secret volume is mounted read-only at /paperclip/.secrets/github-token, while the wrapper scripts live under the shared /paperclip/.local/bin path that the values file prepends to PATH.

Suggestions (0)

None.

Strengths

  • Removes stale token snapshots from Helm-rendered env while keeping existing tools compatible.
  • Fails loudly when the mounted token file is absent or empty, which is safer than silently falling back to stale cached GitHub credentials.
  • The PR body includes useful Helm render, dry-run, shell syntax, and lint verification.

Recommended Action

  1. Merge after normal CI and deployment-owner review.

@kkroo
kkroo merged commit 962355d into master Jun 12, 2026
13 checks passed
@kkroo
kkroo deleted the omar/github-token-fresh-read branch June 12, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant