Investigate a Denied Request
This walkthrough traces one denied tool call back to the policy that denied it. The scenario uses the demo bundle: an agent in sandbox apf-demo tries to call the MCP tool github_repo_write, and the call fails.
Start from the Symptom
The agent reports that its tool call was refused. OpenShell’s supervisor blocked the request because APF’s middleware returned a deny. A request blocked at Layer 1 by the sandbox’s network policy never reaches APF and leaves no APF record, so first confirm that APF decided. Middleware records identify the sandbox by its OpenShell ID, not its name, so look up the ID first, then search the middleware audit file for denials from the sandbox:
If nothing matches, the request was blocked before APF. Check OpenShell’s sandbox logs and the projected network policy instead.
Read the Decision Record
The matching record looks like this. Values are illustrative.
The correlation_id is OpenShell’s request ID, so you can find the same request in OpenShell’s supervisor log.
Classify the Reason
The reason_code and error.message say which part of the pipeline denied the request.
Here the reason is no grant for github_repo_write. No capability rule permitted the action APF::Action::"github_repo_write".
Identify the Policy in Force
The record names the policy by policy_revision and by the digest of the policy set the gateway was using. Confirm when that policy became active:
Then find the bundle the policy service verified at that revision:
The record’s bundle_id and bundle_digest identify the signed bundle. Retrieve that revision from your artifact store.
Find the Deciding Rule
List the capability rules in the bundle and the actions they permit:
github-grants permits only github_repo_read, and its description says so: “repo_write has no permit (denied by default).” The denial is the policy working as authored.
The reason reads no grant rather than github-grants: conditions not met because the more specific reason is used only when a capability rule’s name contains the tool name, and github-grants does not contain github_repo_write.
Decide on a Fix
- The denial is intended. No change. Point the requester at the policy owner.
- The tool should be allowed. The tool owner adds a permit to
github-grants, for example with argument constraints, and the bundle is signed with a higher revision and published. Refer to Update Policies. - The rule is wrong for everyone. Fix it the same way, and check other records with the same
reason_codeanderror.messageto see who else it affected.
Next Steps
- To understand every field you used, refer to Understand Decisions and Findings.
- To write clearer deny reasons, give every statement an
@id. Refer to Capability Grants.