Skip to content

Permissions and the Workspace

Permission policy

When an agent asks permission to run a tool (session/request_permission), Spring AI ACP Harness Client (SAAHC) answers on your behalf, since a server-side application has no human at the keyboard. Every request gets an answer, so no turn stalls. The exception is ask, for an application someone is sitting at.

spring:
  ai:
    acp:
      harness:
        permissions:
          policy: allowlist          # deny (default) | allowlist | auto-approve | ask
          allowed-tools:
            - developer__text_editor
            - inventory__lookup_part
Policy Behaviour
deny Rejects everything. The agent degrades to answering from context.
allowlist Approves exactly the named tools (case-insensitive) and rejects the rest, including any request whose tool name cannot be determined.
auto-approve Approves everything. Only in a sandbox, or when the gate that matters is elsewhere (see acp-meridian's AGENTS.md).
ask Puts each request to a person through the application's PermissionPrompt bean. spring-ai-acp-harness-client-console provides one (see the console); without one, the application fails to start rather than guess. If the turn ends before the person answers, the agent is told cancelled straight away and the thread asking is interrupted; an answer given after that is discarded.

To find the names an agent reports, run once with logging.level.org.springaicommunity.acp.harness: DEBUG and read them off the permission requests.

Mode decides whether the question is asked

Warning

policy: deny alone does not stop an agent writing files. In their default modes, Goose, Codex and OpenCode all edit files with their own tools without asking at all. The mode decides whether permission is requested; the policy decides the answer. For a read-only reviewer, set both:

spring:
  ai:
    acp:
      harness:
        mode: plan            # goose: approve
        permissions:
          policy: deny

Codex's read-only mode still writes inside the workspace without asking; use plan.

Lending the client's filesystem and terminal

ACP lets an agent borrow the client's file and terminal access. A server-side application rarely needs either, so both are off, and are declared unsupported to the agent:

spring:
  ai:
    acp:
      harness:
        filesystem:
          enabled: false        # answer fs/read_text_file
          write: false          # also answer fs/write_text_file (implies enabled)
        terminal:
          enabled: false        # answer terminal/*: arbitrary execution as this JVM's user
          allowed-commands: []  # empty allows any; matched by file name
          output-limit: 1MB
          command-timeout: 5m
          max-concurrent: 8

When enabled, every path is confined to the workspace by its real path, with symlinks followed, so neither .. nor a planted symlink escapes. This governs only what the agent asks this client to do. Its own process's file access is the operating system's to restrict: run the agent as a user, or in a container, that can reach only what it should.

Where adapters write

Adapters write agent config files (config.toml, opencode.json) to spring.ai.acp.harness.runtime-home, never to the workspace. It defaults to a directory under the JVM's temp directory named for the runtime. The only thing SAAHC writes into the workspace is .agents/skills/.