Skip to content

permissions: allow-always is durable and project-scoped with no opt-out or TUI reset #50600

Open

Description

@NikonP

Summary

In V2, choosing Allow always on a permission prompt persists a durable, project-scoped allow rule that survives sessions and restarts. V1 reset approvals when the session ended. There is no config option to opt out of persistence and no TUI surface to review or reset saved approvals, so a single "always" click is effectively irreversible without dropping to the HTTP API or editing the database.

Environment

  • opencode version: v2.0.12
  • OS: Linux 6.12.104-1-MANJARO (linux x64)
  • Terminal: ghostty (TERM_PROGRAM=ghostty, TERM=xterm-256color, COLORTERM=truecolor)
  • Shell: /usr/bin/fish
  • Install/channel: release (latest)
  • Active plugins: none configured (opencode.jsonc has no plugins entry, no local plugin files)

Reproduction

  1. Configure a broad ask rule, e.g. { "action": "shell", "resource": "*", "effect": "ask" } in opencode.jsonc.
  2. Ask the agent to run a shell command and pick Allow always.
  3. Quit opencode and start a new session in the same project.
  4. Run the same command: it executes without prompting.

Expected Behavior

At least one of:

  • Approvals are scoped to the session (the V1 behavior), i.e. they reset on session exit; or
  • A configuration option to choose between session-scoped and durable approvals; or
  • A documented way in the TUI to list and revoke saved approvals for the project.

Actual Behavior

Saved approvals are durable and project-scoped. They are stored in the permission table of ~/.local/share/opencode/opencode.db (project_id, action, resource) and are reloaded on every session in that project.

There is no TUI command or dialog to list/remove them. The only exposed mechanism is the HTTP API:

GET    /api/permission/saved          # optional ?projectID=
DELETE /api/permission/saved/{id}

Additionally, a configured ask rule cannot bring the prompt back, because saved approvals are applied after config rules and resolve to allow; only a configured deny overrides a saved approval. So once Allow always is chosen, the only way to return to asking is to delete the saved approval row.

The documented Permissions page only says "Review broad approvals and remove those no longer needed" without describing how to do so.

Additional Context

  • The Permissions docs state: "Saved approvals are durable, project-scoped allow rules." This appears to be intentional in V2, but it is a behavioral regression from V1 with no opt-out.
  • GET /api/permission/saved returned {"data":[]} even though the project has a saved row (verified directly in the DB), so even the API-based review path appears unreliable. DELETE /api/permission/saved/{id} with a non-existent id returned no error, suggesting deletion is idempotent and does not validate the id.
  • Requested change: either restore session-scoped approvals, add a config switch for approval durability, or add a first-class TUI flow to reset saved permissions per project.

Activity

  1. github-actions commented on Sep 22, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Your issue adds the angle of no TUI mechanism to list/revoke saved approvals and the unreliable GET /api/permission/saved response, which are not covered in #48456, so it may be worth linking the two rather than closing this one outright.

    Related issues that may be of interest:

  2. digital-spinner commented on Oct 18, 2026

    @digital-spinner

    this issue should be top 5 to be fixed right away along with the option to clear the opencode db for security and privacy reasons, leaving only maybe usage data and nothing more..

  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed write-up, @NikonP!

    In V2, Allow always saves a durable, project-scoped allow rule on purpose (this is described on the Permissions docs page). What's missing is a way to manage those rules. You're asking for one of:

    • session-scoped approvals, as in V1;
    • a config option to choose between session-scoped and durable approvals; or
    • a TUI flow to list and revoke saved approvals for a project.

    I've filed this as a feature request, and maintainers will consider it.

    For now, you can manage saved approvals through the HTTP API you found: GET /api/permission/saved (optionally ?projectID=), PATCH /api/permission/saved/{id} and DELETE /api/permission/saved/{id}. A configured deny rule also overrides a saved approval.

    About the empty GET result: without projectID, the endpoint returns every saved row and doesn't filter them, so an empty list usually means the request went to a different server or database than the one you checked. If you can still reproduce it against the same instance, please share the exact request and how the server was started.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions