Skip to content

data: opencode.db is created world-readable (0644), bypassing service API auth for local users #50673

Closed

Description

@yveming

Summary

~/.local/share/opencode/opencode.db is created mode 0644 (world-readable)
under a 0755 directory on a default umask 0022 system, while the background
service API correctly requires authentication (401). Any local user or process
can read session/message/credential data directly from the SQLite file,
bypassing service authentication entirely.

Environment

  • opencode version: 2.0.14
  • OS: Linux 6.18.33.2-microsoft-standard-WSL2 (applies to any Unix host with umask 0022)
  • Terminal: TERM=xterm-256color
  • Shell: /bin/bash
  • Install/channel: latest
  • Active plugins: none found in config

Reproduction

  1. Run opencode so the background service creates the database.
  2. Inspect permissions:
    $ umask
    0022
    $ ls -ld ~/.local/share/opencode
    drwxr-xr-x 6 <user> <user> 4096 ... ~/.local/share/opencode
    $ ls -l ~/.local/share/opencode/opencode.db
    -rw-r--r-- 1 <user> <user> 15310848 ... opencode.db
    
  3. As any other local user (no service password needed), open it read-only:
    sqlite3 'file:~/.local/share/opencode/opencode.db?mode=ro' '.tables'
    
    (sqlite3 CLI Unavailable in my env — not installed; used Python's sqlite3
    module with a mode=ro URI, no sudo, no service credentials.)
  4. Tables include: message, part, session, session_v2,
    session_message, session_inbox, session_share, credential, ...

Expected Behavior

The database (and any credential storage) should be created 0600, consistent
with ~/.local/state/opencode/service.json and
~/.config/opencode/service.json, which are correctly created 0600. Service
auth should not be the only barrier protecting session content.

Actual Behavior

The db file is 0644 and its parent directory 0755, so any local account can
read it with a plain file read — no 401, no password. Table structure confirms
message/session/credential-class content. (I did not dump row contents; the
finding is permission-level.)

Additional Context

  • Registration/password files verified 0600 — good; the db was likely just
    missed because SQLite creates files with the process umask.
  • OPENCODE_DB can relocate the database; the same restrictive default should
    apply there.
  • Likely fix: chmod 0600 after create (and tighten on startup for existing
    files), or set a restrictive umask around db creation.
  • Frequency: consistent — it follows from umask 0022, the default on most
    distros.

Activity

  1. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report. I reproduced this on 2.0.14: under umask 0022, opencode.db is created 0644. That also happens with a custom OPENCODE_DB path, and an existing 0644 database stays that way after a restart.

    On the latest dev (fa1260d) it no longer happens. #52150 changed this: a new database and its -wal/-shm files are created 0600, and an existing database is tightened to 0600 each time OpenCode opens it, including at an OPENCODE_DB path. That fix first shipped in v2.1.3, so upgrading (opencode upgrade) should fix your existing file the next time OpenCode starts. The script below shows the permissions before and after.

    This looks already fixed, so the bot will close this issue in 1 day unless you reply that it still happens on v2.1.3 or newer.

  2. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

    Closing this as completed, since there's been no reply in the past day. To recap: on 2.0.14, opencode.db was created 0644 under umask 0022. On the latest dev (fa1260d), the database and its -wal/-shm files are 0600, and an existing 0644 file is tightened to 0600 on startup, including at an OPENCODE_DB path. The fix from #52150 is in releases since v2.1.3, so upgrading should take care of your existing file.

    If it still happens on v2.1.3 or newer, please comment here or open a new issue with your version and the ls -l output. Thanks again for the clear report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions