Getting Copilot to work in Docker Sandboxes
When I learned about Docker Sandboxes, I wanted to try them out and see how well an agent can be used from inside the isolated environment. Unfortunately, by simply following the documentation, GitHub Copilot failed to work. It took me a non-trivial amount of time and effort to find the reason and fix it.
According to the documentation, the setup process should be simple enough:
- Install Docker Sandboxes. On my Linux machine, I chose to install the
docker-sbx-binUAR package. - Store the GitHub token as a secret. Since I already had GitHub CLI installed and authenticated, the suggested command to store its token as a secrets should be all that's needed:
sbx secret set github --command 'gh auth token' Now I could start Docker Sandboxes with Copilot template in a project folder:
sbx run copilot ~/my-project
However, Copilot initialization inside the sandbox failed because of authentication issues:
Model catalog failed to load: Error: 401 "unauthorized: token authentication failed\n"
My first thought was that for some reason credential injection for GitHub Copilot didn't work as expected. So, I checked the following:
- Did I have a secret stored for GitHub? I did, as the following command listed it:
❯ sbx secret ls SCOPE TYPE NAME SECRET (global) service github (stored) - Was the stored secret a valid GitHub token? I interactively ran the command previously used to get the GitHub CLI token and confirmed that the output was a GitHub token (I masked it for the purpose of this post):
❯ gh auth token gho_**** - Did this token grant GitHub Copilot access? I tried installing GitHub Copilot CLI locally and it worked without any additional configuration or authentication. This could only be explained by it falling back to GitHub CLI token which I stored as a secret.
Now I was starting to wonder why wasn't my secret injected into the Copilot authentication header. Fortunately, Docker Sandboxes provides a way to monitor traffic (I trimmed the output below and kept only relevant rows and columns):
❯ sbx policy log
ALLOWED REQUESTS
SANDBOX TYPE HOST PROXY
backvault network api.individual.githubcopilot.com:443 forward-bypass
backvault network api.github.com:443 forward
Here's the explanation of the proxy values from the documentation:
| Value | Description |
|---|---|
forward |
Routed through the forward proxy. Supports credential injection. |
forward-bypass |
Routed through the forward proxy without credential injection. |
So credential injection was performed for api.github.com, but not for api.individual.githubcopilot.com. I couldn't explain that with what I read from the documentation.
Eventually I managed to find the repository with the source code for the Copilot template I was using. The documentation there explained the behavior I was seeing. I've only stored a secret for github service which is used for api.github.com, but I haven't stored one for copilot service which is used for api.individual.githubcopilot.com. The two secrets have been split in mid-August.
The documentation also states that the same token can't work with both services, but it looks like this is only true for personal access tokens. The token from GitHub CLI started with gho_ and that's supposedly an OAuth app access token. Since the GitHub Copilot CLI on my host machine successfully uses this token, I tried to also set it for the copilot service:
sbx secret set copilot --command 'gh auth token'
Once I did that, Copilot inside the sandbox started working without any issues I could identify. Even if that changes eventually, I should be able to resolve the issue much faster thanks to all I've learned about the Docker Sandboxes internals.
The real value of the whole ordeal I went through is not in the specific solution for the issue I encountered. It's in the troubleshooting process I learned. It's very likely that I'm going to use it again some time in the future.
