Intelligence

The Subagent Listed One Allowed Command. The Platform Default Still Allowed Every Other One.

GitHub issue 47819 against anomalyco/opencode, opened 7 September 2026, reports that a custom agent's own frontmatter permission block is merged on top of the platform's own permissive defaults rather than replacing them. A subagent whose Bash allowlist names only one command still ran a command the operator never listed, because the platform's own catch all allow rule was never removed, only added to. This record independently fetched the pinned source at commit 57ef382843 and confirms the composition mechanism directly rather than from the issue's own account of it.

Event analysed: . This analysis was published on 8 September 2026.

When an operator writes a custom OpenCode agent's own frontmatter permission block naming only the commands they intend to allow, does that block become the agent's complete, closed authority, or is it added on top of whatever the platform already allows by default?

It is added on top. Issue 47819, opened 7 September 2026 against anomalyco/opencode and reporting version 1.18.29 on Linux, describes a subagent configured with a Bash allowlist and no explicit wildcard deny rule that still executed a stat command the operator never listed, with the platform's own permission log naming the matching rule as the wildcard catch all rather than the operator's own narrower list. This record independently fetched the pinned source at commit 57ef382843, packages/opencode/src/agent/agent.ts, and confirms directly that the platform's own defaults object is built with a wildcard allow rule among its entries, that a newly defined custom agent's permission is composed as Permission.merge of those defaults together with the operator's own frontmatter block, and that Permission.merge is the same function used everywhere else agent permission is composed in that file, giving no indication anywhere in the composition call that a later argument is meant to replace an earlier one rather than add to it. This record separately confirms that the platform's own built in explore agent takes a different, explicit path: its own permission block opens with a wildcard deny rule before naming the narrower operations it allows, the same composition function applied to a first argument that closes the space rather than one that leaves it open. No merged fix exists on the issue as of this record's own verification, no CVE has been assigned, and the reporter's own further claim, that placing an explicit wildcard deny as the first rule in a custom agent's own permission block would close the space the same way, is stated in the issue as a reading of the evaluator's own matching order rather than as a reproduction the reporter separately ran, a distinction this record preserves rather than treating the claim as independently demonstrated.

An operator writing a custom agent for OpenCode who lists a handful of allowed Bash commands in that agent's own frontmatter is doing what looks, on its face, like defining the agent's complete authority. Issue anomalyco/opencode#47819, opened 7 September 2026 and reporting version 1.18.29 on Linux, states plainly that this is not what happens. The frontmatter block is not the agent's authority. It is one input merged into a wider composition that already includes the platform's own defaults, and nothing about writing a narrower list removes what the wider defaults already allow.

What this record independently confirmed by fetching the pinned source directly, rather than by reading the issue's own account of it: the platform's own defaults object is built with a wildcard allow rule among its entries, a custom agent's permission is composed by calling the same merge function against those defaults and the operator's own frontmatter block, and nothing in that call distinguishes a later, narrower argument as one meant to replace an earlier, wider one.

What the reporter's own reproduction describes

The issue's own reproduction steps, quoted directly, are: configure a subagent with a Bash allowlist and no explicit wildcard deny rule; run a stat command outside the agent's intended working directory; watch it execute; and read the platform's own permission log line naming the matching rule as the wildcard catch all rather than anything the operator's own allowlist named. The issue separately states that adding an explicit wildcard deny rule as the first entry in the same allowlist should close the space, on the reporter's own reading of the evaluator's matching order, while the allowlist's own narrower allow entries would continue to pass. This record treats those two statements differently: the first is the reporter's own executed reproduction, complete with the platform's own logged rule name; the second is the reporter's own account of what the source should do, offered without a second, separately executed reproduction alongside it in the issue. Both readings are consistent with what this record's own independent fetch of the pinned source confirms below, and this record does not treat the absence of a second executed reproduction as a reason to doubt the second claim, only as a reason to state plainly which of the two claims carries a runtime log and which does not.

What the pinned source actually does

This record fetched packages/opencode/src/agent/agent.ts directly at the pinned commit, 57ef382843, rather than accepting the issue's own description of it. The platform's own defaults object is constructed with a wildcard entry set to allow, alongside a handful of more specific rules governing particular operations. When a newly defined custom agent's permission is built, it is composed by calling the platform's own merge function against those defaults together with the operator's own frontmatter block, converted through the same conversion function used for every other agent. A separately defined built agent composes its own permission the same way, merging the defaults, a small set of built in additions, and the operator's own configuration, again through the identical merge call. Nothing in either call site marks the operator's own later argument as a replacement for the defaults that precede it; the same function is used whether the intent is to add a narrow allowance on top of a wide default or to remove a wide default entirely, and the call site alone does not distinguish which the operator meant.

The clearest evidence that OpenCode's own maintainers already understand this distinction, whether or not it is documented for operators writing their own custom agents, is the platform's own built in explore agent. This record confirmed directly that its own permission block opens with a wildcard deny rule before naming the specific read only operations it allows, composed through the identical merge function applied to every custom agent. An agent meant to hold a genuinely closed set of permissions is given an explicit instruction to close the space first, and only then told what narrower operations to reopen inside it. A custom agent's own frontmatter block that skips that first instruction and goes straight to naming allowed operations is not given the same treatment, and nothing in the merge call itself supplies it silently.

A ceiling only holds if the composition proves it

The distinction the issue is describing is not really about Bash, or about stat, or about OpenCode's own frontmatter syntax specifically. It is the same distinction this desk keeps finding missing wherever one policy is supposed to narrow another: an operator who writes a smaller list is not thereby writing a ceiling, unless whatever combines that list with what came before it is built to treat the smaller list as the ceiling rather than as one more thing to add. A merge that unions two rule sets together produces a result that is, at minimum, as wide as the wider of the two inputs, no matter how narrow the other input reads on its own. Reading a narrow allowlist and concluding that everything else must be forbidden requires the composition to actually behave that way, and the platform's own defaults, still carrying a wildcard allow rule that nothing about the operator's own narrower list removes, are direct evidence that in this composition it does not, absent the explicit wildcard deny rule the platform's own explore agent demonstrates as the pattern that does work.

What this does not show

This record does not claim a merged fix exists; it found none on the issue as of its own verification, no CVE assigned, and no maintainer comment on the issue itself. It does not claim the reporter's own second statement, that an explicit wildcard deny placed first in a custom agent's own permission block closes the space, is unconfirmed as a matter of source behavior; this record's own reading of the built in explore agent's own permission block, composed through the identical merge function, is independent evidence consistent with exactly that claim. What this record does state plainly is that the issue itself pairs an executed reproduction, with a logged matching rule, for the additive merge finding, and an unexecuted, source level reading for the explicit deny finding, and that distinction is preserved here rather than collapsed into a single claim of equal evidentiary weight. This is also not a claim that every OpenCode custom agent is unrestricted, that every additive permission composition is unsafe on its own, or that a genuinely closed custom agent is impossible in the platform as it stands today; the explore agent is itself evidence that a closed agent is possible, built the same way any operator's own custom agent could be built, once the composition is given an explicit instruction to close the space rather than left to infer one from a list of what to allow.

Where this sits in the pattern

This record's own mechanism is a specific instance of a weakness this desk has already named more generally: a delegated actor inherits authority from whatever created or configured it, and nothing about writing a narrower instruction for that actor guarantees the inheritance was actually narrowed rather than merely added to. This desk's own existing coverage of unattenuated delegated authority already documents that failure across shared credentials, forked sessions and registered backends; this occurrence adds a further instance at the level of a single agent's own permission configuration, composed against a platform default it was never independently verified to narrow. Nothing about this record depends on OpenCode's own frontmatter syntax, Bash, or the specific stat command the reporter used to be true. Any platform that builds an agent's effective permission by combining an operator's own narrower configuration with a wider default faces the identical question this issue names: does writing the narrower configuration, on its own, remove what the wider default already granted, or does it require the platform's own composition to be built, and demonstrably proven, to treat that configuration as a ceiling rather than as one more addition.

Sources

This analysis interprets third-party reporting, research and announcements. Moona is not the original reporter of the underlying events.

[1]
fix(core): custom agent frontmatter permission adds to defaults instead of replacing them (Issue #47819)
anomalyco/opencode (GitHub Issues) · 7 September 2026 · Primary source
[2]
agent.ts, agent permission composition (packages/opencode/src/agent/agent.ts at commit 57ef382843)
anomalyco/opencode (GitHub, repository) · 7 September 2026 · Primary source

Protocol evidence

This record does not assess these architectures. The connection runs through the Risk Registry requirement each one bears on, and these published authority architectures are what the evidence says about that requirement.

Protocol evidence related through AEW-006 Delegated authority inherited without attenuation

  • Supports requirement

    Agent Flight Recorder

    Laurent Bindschaedler, Quentin Botha, Christoph Siebenbrunner (independent research, arXiv preprint)

    Requirement Delegation provenance (the requesting agent's identity, the parent event's hash, and the delegated scope) is recorded per event, but attenuation of that scope is not itself enforced

    This weakness names authority spreading past its granted boundary because a delegated grant is not checked for narrowing, expiry, or revocability against its parent. Agent Flight Recorder's own delegation provenance field records a requesting agent's identity, a parent event's hash, and a delegated scope per event, which would let an investigator reconstruct after the fact whether a given delegation ever attenuated relative to its parent. That is evidence supporting the need for an attenuation check, not an attenuation check itself: nothing in the material available to this record describes the construction rejecting, narrowing, or expiring a delegated scope at the point delegation happens, only recording what was claimed about it.

    View protocol evidence

  • Supports requirement

    An Architecture for Auditing Agent Delegation and Interactions (audit-architecture)

    Mirja Kuehlewind (Ericsson) and Henk Birkholz (Fraunhofer SIT), individual submission to the IETF

    Requirement The draft keeps a Delegation Record's existence separate from the delegatee's current effective authority

    This weakness's own corrective principle states that a delegated grant must not exceed its parent's scope, must not outlive its parent's expiry, and must be revocable together with it. The draft's own separation of a Delegation Record, which states that a delegation occurred, from an Authorization Transition Record, which states the delegated scope's current standing, is structural support for exactly that principle: evidence that authority was delegated is kept apart from evidence of the delegatee's currently effective authority, rather than one record class being asked to carry both facts. Recorded as design evidence for the attenuation principle this weakness names, not as a claim that any implementation of it exists outside the draft's own text.

    View protocol evidence

  • Supports requirement

    ARC, Agentic Runtime Control

    Britive

    Requirement Elevated privilege is documented as minted directly in a target system through its own native API and revoked automatically when a task ends, with credential brokering as a separate path for systems that require one

    Britive's own documented model brokers or mints credentials ephemerally and scoped to a task, rather than leaving a standing credential ambiently reachable by whatever caller happens to connect. argocd-mcp's pre fix ARGOCD_API_TOKEN is the failure that principle answers, made concrete at an MCP server rather than at the CI or SSH targets Britive's own material names: a standing, environment configured credential, reachable in full by any network caller whose request the server's own credential check would accept regardless of what, if anything, the request itself supplied. The shipped fix, a separate MCP_AUTH_TOKEN, narrows who can reach the server at all rather than narrowing or brokering the ARGOCD_API_TOKEN itself, which remains one long lived, ungraded credential shared across every holder of the new inbound token.

    View protocol evidence

  • Supports requirement

    Cross App Access (XAA), Okta Agent SSO and MCP Enterprise-Managed Authorization

    Okta

    Requirement Enterprise Managed Authorization governs the cross app connection, not the individual action an agent later attempts

    Cross App Access places the decision of which requesting identity may open a connection to a resource application with the enterprise identity provider and an administrator's own configured policy, independent of whether that resource application, or a server fronting it, is separately reachable inside the same environment. That connection level, principal specific decision is the same corrective github/gh-aw's own merged fix applies to a dynamically registered GitHub MCP backend: a backend's registration for one principal's delegated use is deliberately not read as a connection grant for a different principal, which must clear its own independent check.

    View protocol evidence

  • Supports requirement

    Grantex and the Delegated Agent Authorization Protocol (DAAP)

    Sanjeev Kumar, Grantex

    Requirement Child scopes MUST be a subset of the parent's scopes, and a child may hold exactly the parent's scopes

    Grantex enforces that a child grant's scope is a subset of its parent's and its expiry the earlier of the two, which is the attenuation these inheritance and shared credential failures lack. Unit 42's account of a real enterprise intrusion, corrected 3 September 2026 to clarify the event was an intrusion rather than ransomware, is a longer instance of the same missing attenuation: credentials a reconnaissance and repository search step discovered reached a secrets manager, then CI/CD and cloud identity, with no subset or expiry check narrower than what each step happened to find described at any hop.

    This record is the cited evidence for this relationship.

    View protocol evidence

  • Supports requirement

    Verifiable Attenuated Delegation for AI Agent Chains (draft-asor-wimse-agent-delegation-chain)

    Rafael Asor, Attenu

    Requirement A child's authority must be a verifiable subset of its immediate parent's: scopes under the wildcard containment rule, every parent constraint present and equal or narrower in the child, and expiry and delegation depth no greater than the parent's

    The draft requires a child's scopes, ceilings, constraints and expiry to be a verifiable subset of its immediate parent's, cryptographically checkable offline through a parent hash, which is the attenuation these inheritance and shared credential failures lack. OpenCode issue 47819 documents the same missing subsumption check at the level of a single agent's own permission configuration: the merge composing a custom agent's frontmatter block against the platform's own defaults is a union of the two rather than a verified subset of the wider one.

    This record is the cited evidence for this relationship.

    View protocol evidence

  • Supports requirement

    Verifiable Attenuated Delegation for AI Agent Chains (draft-asor-wimse-agent-delegation-chain)

    Rafael Asor, Attenu

    Requirement Revision 01 adds a min constraint type whose safe attenuation direction is upward, a floor that can only rise as authority narrows

    Revision 01's own min constraint, and its explicit statement that a maximum narrows downward while a minimum narrows upward, makes precise a point this weakness otherwise leaves implicit: narrowing is not one direction for every dimension of authority, and a delegation mechanism that only checks subset and shorter expiry can miss a floor that widened rather than a ceiling that loosened.

    View protocol evidence

  • Reveals bypass

    Agent Identity and Agent Identity Auth Manager

    Google

    Requirement Agent identities are not shared by multiple workloads by default, cannot be impersonated, and do not allow long lived keys

    Google's own comparison states that an agent identity, unlike a service account, is not shared by multiple workloads by default, cannot be impersonated and does not allow long lived keys. argocd-mcp's own ARGOCD_API_TOKEN is exactly the shape this property contrasts against: one long lived, environment configured credential, shared by construction across every caller able to reach the server, with nothing this entry's own reading of the affected source found narrowing which caller could exercise it. This does not fault Google's own architecture, which the property itself only describes rather than mandates elsewhere; it evidences why the comparison the property draws is the attenuation this weakness's own known examples keep missing.

    View protocol evidence

  • Reveals bypass

    AI Agent Identity Certificate (AIC) extension for X.509 v3

    Jijie Wei, individual submission to the IETF

    Requirement Authority can go stale after issuance

    AIC's authorized mode locks the permission set into the certificate at issuance, so authority can go stale: a change to the principal's grants after issuance does not reach an already issued certificate, a delegation gap the inheritance failures illustrate.

    View protocol evidence

  • Reveals bypass

    Verifiable Attenuated Delegation for AI Agent Chains (draft-asor-wimse-agent-delegation-chain)

    Rafael Asor, Attenu

    Requirement Nothing in the token profile establishes that the root token holder was actually entitled to grant the authority the root token represents

    A verified chain proves lineage forward from a trusted root key, not that the root holder was ever entitled to the authority it represents, so a mistaken or illegitimate grant at the root produces a chain every hop of which still narrows correctly, an inheritance failure the subsumption check alone does not reach.

    View protocol evidence

Related Intelligence

All Intelligence Records →