Restrict AI agents to Apono Agent Privilege Guard for AWS
Make the Apono Agentic Gateway the only way AI agents can access AWS
Configure Claude Code, Claude Desktop, and Codex so that the Apono Agentic Gateway is the only way an AI agent can access AWS.
After Apono Agent Privilege Guard is set up for AWS, the AI agent has two ways to reach AWS: the Agentic Gateway, and the AWS credentials already on the developer's machine under ~/.aws. This page shows how to close the second path.
Each AI client gets three kinds of settings:
Deny rules stop the agent from running the AWS CLI and from reading
~/.aws.Instructions tell the agent that the block is intentional and that AWS access goes through the Apono MCP tools
list_targetsandask_access_assistant.An OS-level deny makes
~/.awsunreadable to every process the agent starts. This is the only layer that is a real security boundary.
How the layers differ
Instructions
Tells the agent that AWS goes through Apono. The agent stops trying and points the user to Apono.
The model. Guidance only.
Client rules
The client refuses to run a matching command or read a matching path. Gives a clear refusal and an audit trail.
The client. Can be bypassed.
OS-level deny
The operating system blocks every process the agent starts from reading ~/.aws, including scripts.
The operating system. The security boundary.
Prerequisites
Apono account setup completed
Agent Privilege Guard for AWS is set up
Confirm that an Apono admin has followed Apono Agent Privilege Guard for AWS: the AWS Organization integration is connected, an agentic access flow exists with Restrict to agentic access enabled, and MCP features and the AWS MCP are enabled.
Agentic Gateway connected
The AI client already reaches Apono
Each AI client you restrict must already be connected through the Local Agentic Gateway, and asking it to list available integrations must return AWS. Apply the deny rules only after this works. Otherwise the developer loses AWS access with no alternative.
Admin route to each AI client
How the settings reach every machine
Claude Code: the claude.ai admin console, or a
managed-settings.jsonfile deployed by MDM.Claude Desktop: managed preferences deployed by MDM.
Codex: a root-owned
requirements.tomldeployed by MDM, or ChatGPT managed configs with a Business or Enterprise sign-in.
Configure your AI client
Claude Code's managed settings cover the CLI, the VS Code and JetBrains extensions, and Claude Desktop's Code and Cowork surfaces.
Managed settings outrank every other setting level. No user, project, or command-line setting can override a managed deny rule. A managed settings file applies to every Claude Code session on the machine, whichever account the developer signs in with.
Deliver the configuration
Deploy it as server-managed settings in the claude.ai admin console, or as a file on each machine:
macOS
/Library/Application Support/ClaudeCode/managed-settings.json
Linux / WSL
/etc/claude-code/managed-settings.json
Windows
C:\Program Files\ClaudeCode\managed-settings.json
Configuration
permissions.deny
Blocks the aws command by name and at its two common install paths, blocks aws-vault, and blocks reads under ~/.aws for every user on the machine. Path rules also cover shell file commands such as cat, head, tail, and sed.
claudeMd
Instructions added to every session: the block is intentional, and AWS goes through the Apono MCP tools. Works only in managed settings.
allowManagedPermissionRulesOnly
Makes managed settings the only source of permission rules.
disableBypassPermissionsMode
Removes bypass-permissions mode.
Add the OS-level deny
The deny rules do not stop a script that opens ~/.aws/credentials on its own, such as a Python one-liner. Without the sandbox, only the auto-mode classifier stands in the way, and a classifier is not a guarantee.
Follow these steps:
Keep auto mode on. Do not set
permissions.disableAutoMode.In the same managed settings, enable the sandbox and list
~/.awsundersandbox.credentials. The sandbox blocks reads at the OS level for every command the agent runs and every child process. See Sandboxing.
The sandbox runs on macOS, Linux, and WSL2. It does not run on native Windows.
Claude Code's managed settings already cover Claude Desktop's Code and Cowork surfaces. This configuration adds Desktop's own deny for the AWS command and ~/.aws, and turns off desktop extensions.
Deliver it as managed preferences. When a managed source is present, it wins and local values are ignored.
macOS
/Library/Managed Preferences/<user>/com.anthropic.claudefordesktop.plist
Windows
HKLM\SOFTWARE\Policies\Claude (machine) / HKCU\SOFTWARE\Policies\Claude (user)
Linux
/etc/claude-desktop/managed-settings.json
Values, JSON encoded as a string in the plist or registry:
macOS plist equivalent:
Each disabledBuiltinTools entry is a tool name such as Bash, or a scoped rule such as Bash(aws *). A bare name blocks every call. A scoped rule blocks matching calls in every permission mode.
Caveats
Cowork's own shell honors bare tool names only.
Bash(aws *)has no effect there. A bare"Bash"entry works.Start file patterns with
**/. An absolute host path does not match inside the Cowork sandbox.A local MCP server that runs
awsis anmcp__*tool, notBash, so these rules do not apply to it. UsemanagedMcpServers[].toolPolicyto block or gate its tools.Device Claude Code policy overrides Desktop policy unless the Claude Code managed settings set
parentSettingsBehavior: "merge".Scoped rules depend on the Desktop build. Pin builds with
disableAutoUpdates.
Codex has the strongest credential-path control of the three clients and a weak command control.
Admin-enforced settings live in requirements.toml. Users cannot weaken them with local config. Codex reads them, from lowest to highest priority, from /etc/codex/requirements.toml (macOS and Linux) or %ProgramData%\OpenAI\Codex\requirements.toml (Windows), then the cloud config assigned at chatgpt.com/codex/settings/managed-configs, then the macOS MDM key com.openai.codex:requirements_toml_base64.
/etc/codex/config.toml ranks below user config. managed_config.toml sets defaults the user can change during a run. Only requirements.toml is a lock.
Follow these steps:
Install the following file root-owned at
/etc/codex/requirements.toml, or deliver it through the MDM key or cloud managed configs.
permissions.filesystem.deny_read
The OS-level deny. Codex keeps the agent in a sandbox so it can enforce it. Users cannot weaken it.
experimental_network.denied_domains
Blocks AWS endpoints, so the AWS CLI is useless even if it runs.
rules.prefix_rules
Refuses aws and terraform with a reason the agent can read. Applies only outside the sandbox, so treat it as a clear message, not a block.
hooks.PreToolUse
Runs the script below before every shell command. This is the unconditional command block, and its deny reason is the instruction that points the agent to Apono.
Install the hook script root-owned at
/etc/codex/hooks/block_aws.py. Codex enforces the hook configuration but does not distribute the script, so ship it in the same MDM payload.
(Optional) Install
/etc/codex/managed_config.tomlto removeAWS_*variables from the agent's shell. This is a default the user can change during a run, not a lock.
A malformed hook deny lets the command run. A deny must use the nested hookSpecificOutput shape shown in the script. A bare {"permissionDecision":"deny"} fails validation, and Codex continues the tool call. Exit code 2 with the reason on stderr is the fallback deny.
Verify the configuration
Perform the following tests inside each AI client after restarting it. Ask the agent for the literal output or error of each command.
1
aws sts get-caller-identity
direct command
caller identity
2
sh -c 'head -c 40 ~/.aws/credentials | wc -c'
wrapper evasion
40
3
python3 -c "print(len(open('/Users/<user>/.aws/credentials').read()))"
subprocess read
byte size of the file
4
env | grep AWS_
environment variables
variable names and values
Probe 3 is the important one. A deny rule can stop it only when the command line names the path. Only the OS-level deny stops the read itself.
Then confirm the Apono path still works: ask the agent to list available integrations. The AWS target should appear.
Confirm the deny is enforced, not just obeyed
An agent often declines to touch credential files on its own. That does not prove the deny works. To test the deny itself, deny a harmless file the agent has no reason to refuse.
Follow these steps:
Create two files:
Add the decoy path to the credential-path deny of the client under test. For Codex, add it to
deny_read:
Restart the AI client, then ask the agent to
catboth files and paste the literal output or error for each.
control readable, decoy fails with an OS error
The deny is enforced.
both readable
The deny is not enforced. Earlier refusals were the agent obeying, not the client blocking.
agent refuses both
Inconclusive. Rerun and insist on literal output.
Known limitations
A refusal is not a block. An agent that declines to run a command proves the instructions work, not that the client would stop it. Only an OS-level error proves enforcement.
Command rules can be bypassed. Renamed binaries, quoted names such as
a"w"s,bash -c,docker exec,npx, and SDKs such asboto3all get past a command rule. The credential-path deny is the control that holds.Other MCP servers are not covered. An MCP server that reads
~/.awsis not a shell command. Restrict MCP servers separately.Environment variables are only partly covered. Codex removes
AWS_*as a default the user can change. Claude Code needs the sandbox to do the same.Device files need MDM. A developer with local admin rights can edit them. Redeploy on a schedule.
Console settings need the org account. Tenant-side policy does not apply when the developer signs in with a personal account.
The agent's API is outside all of this. A script that calls the model API directly is under no client policy.
Troubleshooting
Last updated
Was this helpful?
