Skip to content

Commit ee20e61

Browse files
charlesfryeopencodeModal JazzOpenCode
authored
Add GitHub credentials to Sandbox (#1487)
* Document gh auth token pattern in opencode_server example Add guidance for using shell command substitution with $(gh auth token) to pass GitHub credentials when launching the sandbox, enabling access to private repositories without manually creating a PAT. Co-authored-by: Modal Jazz <modal-jazz@modal.com> * update formatting, adjust prose * Pass GH_TOKEN to sandbox via Modal Secret Allows authenticated gh commands inside the sandbox, not just repo cloning. * Apply suggestion from @charlesfrye --------- Co-authored-by: opencode <opencode@test.com> Co-authored-by: Modal Jazz <modal-jazz@modal.com> Co-authored-by: OpenCode <opencode@modal.com>
1 parent 5fe215c commit ee20e61

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

13_sandboxes/opencode_server.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
def define_base_image() -> modal.Image:
4141
image = (
4242
modal.Image.debian_slim()
43-
.apt_install("curl", "git")
43+
.apt_install("curl", "git", "gh")
4444
.run_commands("curl -fsSL https://opencode.ai/install | bash")
4545
.env({"PATH": "/root/.opencode/bin:${PATH}"})
4646
)
@@ -127,7 +127,7 @@ def create_sandbox(
127127
image: modal.Image,
128128
timeout: int,
129129
app: modal.App,
130-
password_secret: modal.Secret,
130+
secrets: list[modal.Secret],
131131
working_dir: str | None = None,
132132
) -> modal.Sandbox:
133133
print("🏖️ Creating sandbox")
@@ -141,7 +141,7 @@ def create_sandbox(
141141
"--log-level=DEBUG",
142142
"--print-logs",
143143
encrypted_ports=[OPENCODE_PORT],
144-
secrets=[password_secret],
144+
secrets=secrets,
145145
timeout=timeout,
146146
image=image,
147147
app=app,
@@ -204,8 +204,12 @@ def main(
204204

205205
password = secrets.token_urlsafe(13)
206206
password_secret = modal.Secret.from_dict({"OPENCODE_SERVER_PASSWORD": password})
207+
sandbox_secrets = [password_secret]
207208

208-
sandbox = create_sandbox(image, timeout, app, password_secret, "/root/code")
209+
if github_token:
210+
sandbox_secrets.append(modal.Secret.from_dict({"GH_TOKEN": github_token}))
211+
212+
sandbox = create_sandbox(image, timeout, app, sandbox_secrets, "/root/code")
209213
print_access_info(sandbox, password)
210214

211215

@@ -214,6 +218,13 @@ def main(
214218
# This script supports configuration via command-line arguments.
215219
# Run with `--help` to see all options.
216220

221+
# To grant the agent the same GitHub permissions you have, you can pass a GitHub personal access token.
222+
# If you use the `gh` CLI, you can use shell command substitution to pass your current auth:
223+
224+
# ```bash
225+
# python 13_sandboxes/opencode_server.py --github-token $(gh auth token)
226+
# ```
227+
217228

218229
def parse_timeout(timeout_str: str) -> int:
219230
if timeout_str.endswith("h"):
@@ -267,7 +278,7 @@ def parse_timeout(timeout_str: str) -> int:
267278
"--github-token",
268279
type=str,
269280
default=None,
270-
help="GitHub PAT for private repositories",
281+
help="GitHub PAT for private repos and gh CLI auth. Tip: use $(gh auth token)",
271282
)
272283

273284
args = parser.parse_args()

0 commit comments

Comments
 (0)