Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 38 additions & 139 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,161 +28,60 @@ The naive solutions both have drawbacks:

The write token never appears in agent context or logs — it is encrypted at rest using AES-256-GCM with a key derived from machine-specific identifiers (machine ID, hostname, username).

## Installation
## Installation and agent setup

```bash
pipx install ghsudo
```

Or with pip:

```bash
pip install ghsudo
```
**Requirement:** Python 3.10+

Or install from source:
Install with `pipx` (recommended), `pip`, or from source:

```bash
git clone https://github.com/lklimek/ghsudo
cd ghsudo
pip install .
pipx install ghsudo
# or: pip install ghsudo
# or:
# git clone https://github.com/lklimek/ghsudo
# cd ghsudo
# pip install .
```

> **Note:** For `git push`/`pull` to work with `ghsudo`'s elevated token, your remotes need `https://` URLs (not SSH). `ghsudo` injects `GH_TOKEN`/`GITHUB_TOKEN` which the `gh` credential helper uses for HTTPS Git operations. (`ghsudo gh ...` commands work regardless of remote URL scheme.)
> To configure `gh` as the Git credential helper, run:
> **Note:** For `git push`/`pull` to work with `ghsudo`'s elevated token, use `https://` remotes (not SSH), then configure `gh` as the Git credential helper:
> ```bash
> gh auth setup-git
> ```

**Requirement:** Python 3.10+

> **Note:** Only **Linux** is actively tested. macOS and Windows have basic support (GUI dialogs, path handling) but are **not tested** — contributions welcome.

## Quick Start

```bash
# 1. Install
pipx install ghsudo

# 2. Create a write-access GitHub PAT at https://github.com/settings/tokens
# (classic PAT with 'repo' scope, or fine-grained with the permissions you need)

# 3. Store the write token — <org> is the GitHub organization or user account
# that owns the repo (e.g. 'mycompany' for mycompany/myapp, or your username)
ghsudo --setup <org>

# 4. Give the agent a read-only token — log in with a separate read-only PAT
# so the agent's gh commands are restricted by default
echo "<your-read-only-token>" | gh auth login --hostname github.com --with-token
# Alternatively, use an environment variable (session-scoped):
# export GH_TOKEN=<your-read-only-token>

# 5. Add CLAUDE.md / AGENTS.md to your repo (see below)
```

> **⚠️ Important:** Run the agent in a **dedicated terminal** (or subshell) where
> your `gh` is authenticated with the read-only token above. Do **not** launch the agent
> in a session where your real, writable `gh auth login` is active — this would give
> the agent full write access and bypass ghsudo's read-only restriction.

When the agent needs to perform a write operation, it calls:
> `ghsudo gh ...` commands work regardless of remote URL scheme.
>
> **Platform note:** Only **Linux** is actively tested. macOS and Windows have basic support but are untested.

Set up once per GitHub owner (`<org>` = the owner in `owner/repo`):

1. Create a write PAT at [GitHub token settings](https://github.com/settings/tokens) and store it:
```bash
ghsudo --setup <org>
```
2. Configure your coding agent to use a separate read-only token:
```bash
echo "<your-read-only-token>" | gh auth login --hostname github.com --with-token
# or (session-scoped): export GH_TOKEN=<your-read-only-token>
```
3. Add agent instructions in each target repository:
- Claude Code: copy [`CLAUDE-example.md`](CLAUDE-example.md) to `CLAUDE.md`
- OpenAI Codex: copy [`AGENTS-example.md`](AGENTS-example.md) to `AGENTS.md`
Comment on lines +60 to +67
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

The instructions point users to copy CLAUDE-example.md / AGENTS-example.md, but those templates currently state the agent has a read-only GH_TOKEN. Since this section also recommends gh auth login (which doesn’t set GH_TOKEN), this can be confusing. Consider adjusting the README wording here to say the agent may be configured via GH_TOKEN/GITHUB_TOKEN or gh auth login, and that the templates’ “GH_TOKEN” wording is shorthand for the read-only gh authentication context.

Suggested change
2. Configure your coding agent to use a separate read-only token:
```bash
echo "<your-read-only-token>" | gh auth login --hostname github.com --with-token
# or (session-scoped): export GH_TOKEN=<your-read-only-token>
```
3. Add agent instructions in each target repository:
- Claude Code: copy [`CLAUDE-example.md`](CLAUDE-example.md) to `CLAUDE.md`
- OpenAI Codex: copy [`AGENTS-example.md`](AGENTS-example.md) to `AGENTS.md`
2. Configure your coding agent to use a separate read-only token (either via `gh auth login` or an environment variable):
```bash
# Option A: configure `gh` with a read-only token (preferred)
echo "<your-read-only-token>" | gh auth login --hostname github.com --with-token
#
# Option B: session-scoped environment variable for tools that read GH_TOKEN/GITHUB_TOKEN directly
export GH_TOKEN=<your-read-only-token> # or: export GITHUB_TOKEN=<your-read-only-token>
  1. Add agent instructions in each target repository:

    In these templates, references to GH_TOKEN mean the agent's read-only GitHub authentication context. You can provide this either by exporting GH_TOKEN/GITHUB_TOKEN or by authenticating gh with gh auth login using the read-only token above.

Copilot uses AI. Check for mistakes.
4. Verify:
```bash
ghsudo --verify <org>
ghsudo --list
```

> **⚠️ Important:** Run the agent in a dedicated terminal/subshell where `gh` is authenticated with the read-only token. Otherwise the agent may inherit your writable `gh` credentials and bypass `ghsudo`.
Comment on lines +60 to +74
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

The recommended read-only setup uses gh auth login, but that authentication is persisted in gh’s global config (it’s not limited to a single terminal). The current “dedicated terminal/subshell” warning reads like terminal isolation is sufficient, which isn’t true unless you instead use GH_TOKEN/GITHUB_TOKEN env vars or a separate GH_CONFIG_DIR for the agent. Consider clarifying the persistence/restore steps (or recommending env-var / separate config dir for agent sessions) so users don’t accidentally overwrite their normal gh login or get a false sense of isolation.

Copilot uses AI. Check for mistakes.

For write operations, the agent must use:

```bash
ghsudo gh pr merge 123 --merge
ghsudo gh issue comment 42 --body "Done!"
ghsudo gh pr review 7 --approve
```

A dialog appears asking you to approve. Only after you click **Allow** does the command run.

See [Setting up with your agent](#setting-up-with-your-agent) for a detailed walk-through.

## Setting up with your agent

The key idea: give the agent a read-only token, and instruct it to use `ghsudo` for write operations. A `CLAUDE.md` / `AGENTS.md` file in the target repository carries those instructions into the agent's context automatically.

### Step-by-step

#### 1. Install ghsudo on your machine

```bash
pipx install ghsudo
```

#### 2. Create a write-access GitHub PAT and store it

Go to [GitHub Settings → Developer Settings → Personal access tokens](https://github.com/settings/tokens) and generate a new token with the write scopes you need (e.g. the `repo` scope for a classic PAT, or the relevant fine-grained permissions).

Then store it with `ghsudo`:

```bash
ghsudo --setup <org>
```

`<org>` is the GitHub organization or personal user account name that owns the repositories you work with — the owner part of an `owner/repo` pair. For example, for `mycompany/myapp` use `mycompany`; for your own repos use your GitHub username.

You will be prompted to paste your [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). The token is validated and stored encrypted under `~/.config/ghsudo/tokens/<org>.enc`.

#### 3. Give the agent a read-only token

Create a separate PAT with **only read scopes** (fine-grained PAT with read-only permissions, or classic PAT with only `read:org` / `public_repo`), then configure it for the agent.

**Recommended — `gh auth login` (persistent across all gh commands in the session):**

```bash
echo "<your-read-only-token>" | gh auth login --hostname github.com --with-token
```

This stores the token as the active GitHub credential for the `gh` CLI. All `gh` read operations in that session will use it, and write operations will fail (prompting the agent to use `ghsudo`).

**Alternative — environment variable (session-scoped):**

```bash
export GH_TOKEN=<your-read-only-token>
```

`GH_TOKEN` takes precedence over `gh auth login` credentials, so setting it achieves the same restriction for the duration of the shell session.

> **⚠️ Warning:** Do **not** launch the agent in a terminal where your real, writable
> `gh auth login` is active without setting `GH_TOKEN`. If no `GH_TOKEN` or
> `GITHUB_TOKEN` is set, the agent inherits your personal GitHub credentials (which
> may have full write access), bypassing ghsudo's read-only restriction. Use a dedicated
> terminal or subshell for the agent session.

#### 4. Add agent instructions to your repository

Copy the provided template files into the root of each repository where the agent will work:

**For Claude Code** — copy [`CLAUDE-example.md`](CLAUDE-example.md) as `CLAUDE.md` in your repo (or append its contents to an existing `CLAUDE.md`):

```markdown
# GitHub access — two-token model

You have been given a **read-only** GitHub token via `GH_TOKEN` / `GITHUB_TOKEN`.
Use it freely for all read operations.

For any GitHub operation that **modifies** state (merge, push, comment, label,
close, approve, request review, etc.), prefix the command with `ghsudo`:

ghsudo gh pr merge 123 --merge
ghsudo gh issue comment 42 --body "Done!"
ghsudo gh pr review 7 --approve

`ghsudo` will show the user a dialog and wait for explicit approval before running
the command with elevated permissions. If denied (exit code 2), stop and report
to the user. Never bypass ghsudo or ask the user for the write token directly.
```

**For OpenAI Codex** — copy [`AGENTS-example.md`](AGENTS-example.md) as `AGENTS.md` in your repo (the file name `AGENTS.md` is the convention Codex uses).

The [`CLAUDE-example.md`](CLAUDE-example.md) and [`AGENTS-example.md`](AGENTS-example.md) files in *this* repository serve as ready-to-copy templates.

#### 5. Verify the setup

```bash
ghsudo --verify <org> # confirms the token decrypts and is accepted by GitHub
ghsudo --list # shows all orgs with stored tokens
```
`ghsudo` shows a GUI approval dialog and only runs the command after you click **Allow**.

## Usage

Expand Down