A stored login in OpenCode in Docker: check it, use it, make one or remove it

Introduction

This article is part of a larger manual, OpenCode in Docker on Ubuntu 24.04.

The manual shows how to run OpenCode with the --auto option inside a Docker container.

With --auto the agent does not ask you before each command, so the container limits what it can reach: the agent works only in one git worktree, a separate copy of the project.

In this setup a paid model gets its key in one of two ways: from a key file that the launcher passes to one run, or from a stored login.

This article explains what a stored login is, how to find out if you have one, how to use it, and what to do if you have none.

What a stored login is

A stored login is a key that you gave to OpenCode inside the container, with opencode auth login.

OpenCode saves it in its database, opencode.db, in the sessions volume opencode-agent-data.

The launcher mounts this volume into every container, with every image.

So every later run sees the login, and you pass nothing to the launcher.

Key fileStored login
How you set it upa file in ~/.config/opencode-agent on the hostopencode auth login in a container
Where the key isin that filein opencode.db in the sessions volume
Which runs get itonly runs started with --opencode-key or --openrouter-keyevery run, also the runs on the free model
opencode auth list showsenvironmentstored

Every run that has the key can read it, and with a stored login that is every run.

opencode auth export prints the stored keys in plain text.

Tested on a throwaway volume with a dummy key:

opencode auth export

[ { "id": "cred_1a62bc2e7001UPeX228degeY89", "integrationID": "opencode-go", "label": "OpenCode Go", "active": true, "value": { "type": "key", "key": "dummy-test-key-123" } } ]

An agent with --auto can run the same command.

A key file is the safer choice: runs without the option never have the key (keys for one run).

How to find out if there is a stored login

Ask OpenCode in a one-off container on the sessions volume.

You need no worktree for this, and the container ends with the command:

docker run --rm -v opencode-agent-data:/home/agent/.local/share/opencode opencode-agent auth list

With a stored login for OpenCode Go, the line ends with stored:

OpenCode Go OpenCode Go stored

Without any stored login:

No authenticated integrations

In the shell of step 6 (check what the container sees) the command is opencode auth list.

There it also lists the keys that the launcher passed to the run, with environment at the end.

A stored login and a key passed with --opencode-key, both at once:

OpenCode Go OpenCode Go stored OpenCode Go OPENCODE_API_KEY environment OpenCode Console OPENCODE_API_KEY environment

Keep only one of the two for a provider, so you know which key a run uses.

stored does not mean that the key works.

OpenCode does not check the key when it saves it.

A wrong key fails at the first request of a run. Tested with a dummy key:

Error: Upstream request failed: Invalid credential

How to use a stored login

Start the run as usual and pick a model of that provider with -m. You add no key option:

container/tools/ai/opencode-docker.sh ../site-agent-<task> run --title <task> -m opencode-go/deepseek-v4.1-flash "<what to do>"

A long task of this setup ran that way, in the Erlang image and with the task in a file.

It ran on DeepSeek V4.1 Flash through OpenCode Go:

container/tools/ai/opencode-docker.sh --erlang ../site-agent-<task> run --title <task> -m opencode-go/deepseek-v4.1-flash "$(cat ~/tasks/<task>.md)"

To continue a task that stopped at the usage limit of the free model, add -s <id> (when the free model reaches its usage limit).

Which models a provider gives you: in the shell of step 6, opencode models lists them, for example the models of OpenCode Go:

opencode models | grep '^opencode-go/deepseek'

opencode-go/deepseek-v4-pro opencode-go/deepseek-v4.1-flash

What to do if there is no stored login

You have two choices.

1. Pass a key file to each run. This is the safer way: only the runs you start with the option get the key.

To learn how to save the key and pass it, read the section Keys for one run of the launcher article for OpenCode Go, and the section 1. A key for the container of the OpenRouter article for OpenRouter.

container/tools/ai/opencode-docker.sh --opencode-key ~/.config/opencode-agent/opencode.key ../site-agent-<task> run -m opencode-go/deepseek-v4.1-flash "<what to do>"

2. Store a login. Copy the key of your OpenCode Go subscription from the OpenCode console.

Then run the login form in a one-off container on the sessions volume.

-it gives the form a terminal, which it needs:

docker run --rm -it -v opencode-agent-data:/home/agent/.local/share/opencode opencode-agent auth login opencode-go --method key

Paste the key at the prompt. It shows as dots. Press Enter. The end of the output:

◇ Connected to OpenCode Go │ └ Done

Check it with auth list, as in how to find out if there is a stored login.

Tested on a throwaway volume with a dummy key.

Remove a stored login

Give the provider and the label. The label is the second column of auth list:

docker run --rm -v opencode-agent-data:/home/agent/.local/share/opencode opencode-agent auth logout opencode-go "OpenCode Go"

◇ Removed account from OpenCode Go └ Done

Without the label the command opens a picker, which needs -it.

Without a terminal it stops with Pass a credential ID or label when running without an interactive terminal. Tested on a throwaway volume.

Removing the whole volume, docker volume rm opencode-agent-data, also removes the login, together with all sessions.

Article author: Klavdiya Kondakova