You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow specifying specific commands that don't need permission to run #3085
In .claude/settings, users can set explicitly allows commands for Claude to run so that it doesn't need permission. e.g.
{
"permissions": {
"allow": [
"Bash(mkdir:*)",
"Bash(rg:*)",
"Bash(npm run build:*)",
"Bash(grep:*)",
"Bash(npm run format:*)"// ...
]
}
}
It's great that Claude Code lets me tell it which tools it doesn't need to ask for permission to use. It would be great if Codex CLI has a similar whitelist of user-specific permissions (not necessarily with the above syntax) so that it would stop repeatedly pestering me to ask if it can run my tests.
This enhancement is probably my #1 request - there are certain commands that I always want to allow, such as running the scripts to build and test my project (similar to the xcodebuild example from @SwiftedMind a few weeks ago).
The wildcards are an important aspect to this - tools such as 'axe' (https://github.com/cameroncooke/AXe) would commonly be run over and over again, and provide different parameters each time. Needing to approve each individual combination of parameter is a non-starter, but running on yolo mode is not what I want to do.
Reacted by stephen thoma, laurens-pilot, Felix Green, Peter Dedene, Adam Smith and aa403
I got really tired of having to always approve this, so I wrote a custom script that allows you to whitelist certain commands. I've been using it for about a month and it's a game changer with Codex CLI. Keep in mind this is my personal script, so you might have to tweak it to get it working right for you, but here's how to set it up:
Prerequisites:
Be on a mac
Use iTerm2
Have Dart installed
Write a zsh alias for when codex starts (put this in ~/.zshrc):
alias code='echo "Starting Codex...." && codex && echo "Ending Codex...."'
this gives us a string to watch for when codex starts and ends.
Put the following script in a file named codex_coprocess.dart (to be used in next step).
You can obviously edit the approvedCommands list as needed.
// ignore_for_file: prefer_interpolation_to_compose_stringsimport'dart:convert';
import'dart:io';
voidmain() {
showNotification(title:'Starting', text:'Starting Codex Coprocess');
///////////////// VARIABLES /////////////////const bufferMaxLines =20;
final approvedCommands = [
'cd',
'curl',
'dart',
'echo',
'export',
'flutter',
'gh pr diff',
'gh pr review',
'gh pr status',
'gh pr view',
'git checkout',
'git fetch',
'grep',
'melos',
'tail',
'tee',
'xcodebuild',
'xcrun',
];
final actions = [
(
RegExp(
r'Would you like to run the following command\?\n?.*',
multiLine:true,
dotAll:true,
),
(finalString match) {
final commandLine =extractCommandLine(match);
if (commandLine ==null) return;
if (areAllCommandsApproved(commandLine, approvedCommands)) {
stdout.write('2');
} else {
showNotification(
title:"Pending Request",
text:'Tool Needs Approval',
playSound:true,
);
}
},
),
];
///////////////////// END VARIABLES /////////////////////final buffer =StringBuffer();
final ansiRegex =RegExp(
r'(?:\x9B|\x1B\[)[0-?]*[ -/]*[@-~]|\x1B\][^\x07\x1B]*(?:\x07|\x1B\\)|\x1B[PXT^_].*?\x1B\\|\x1B[@-Z\\^_]|\x1B[ -/]*[@-~]',
dotAll:true,
);
final controlCharacterRegex =RegExp(
r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]',
);
stdin.transform(utf8.decoder).listen((final input) {
if (input.contains('Ending Codex....')) {
showNotification(title:'Done', text:'Ended Codex Coprocess');
exit(0);
}
final cleanInput = input
.replaceAll(ansiRegex, '')
.replaceAll(controlCharacterRegex, '');
buffer.write(cleanInput);
final numLines = buffer.toString().split('\n').length -1;
if (numLines > bufferMaxLines) {
final bufferWindow = buffer
.toString()
.split('\n')
.sublist(numLines - bufferMaxLines)
.join('\n');
buffer
..clear()
..write(bufferWindow);
}
for (final (regexp, action) in actions) {
final match = regexp.stringMatch(buffer.toString());
if (match !=null) {
action(match);
buffer.clear();
break;
}
}
});
}
/////////////////////////////// Command Approval Helpers ////////////////////////////////// Extracts the command line from a Codex approval prompt matchString?extractCommandLine(String match) {
final commandRegex =RegExp(r'\$\s+(.+)$', multiLine:true);
final commandMatch = commandRegex.firstMatch(match);
return commandMatch?.group(1)?.trim();
}
/// Splits a command line into individual commands by &&, ;, and |List<String> splitCommands(String commandLine) {
// Split on &&, ;, or | and trim each segmentreturn commandLine
.split(RegExp(r'&&|;|\|'))
.map((segment) => segment.trim())
.where((segment) => segment.isNotEmpty)
.toList();
}
/// Extracts the base command from a segment, removing environment variablesStringextractBaseCommand(String segment) {
// Remove environment variable assignments (KEY=VALUE) from the startfinal envVarRegex =RegExp(r'^(\w+=\S+\s+)+');
final cleaned = segment.replaceFirst(envVarRegex, '');
return cleaned.trim();
}
/// Checks if a command is approved using prefix matchingboolisCommandApproved(String command, List<String> approvedCommands) {
return approvedCommands.any((approved) => command.startsWith(approved));
}
/// Checks if all commands in a chain are approvedboolareAllCommandsApproved(String commandLine, List<String> approvedCommands) {
final commands =splitCommands(commandLine);
for (final segment in commands) {
final baseCommand =extractBaseCommand(segment);
if (!isCommandApproved(baseCommand, approvedCommands)) {
returnfalse;
}
}
returntrue;
}
voidshowNotification({
requiredfinalString title,
requiredfinalString text,
finalbool playSound =false,
}) {
Process.runSync('osascript', [
'-e',
'display notification "$text" with title "$title"',
]);
if (playSound) {
Process.runSync('afplay', ['/System/Library/Sounds/Funk.aiff']);
}
}
/////////////////////////// Debugging Utilities ///////////////////////////voidlog(finalString log, {finalbool shouldClear =false}) {
final file =File('/Users/adam/Desktop/log.txt');
final currentContents = file.existsSync() &&!shouldClear
? file.readAsStringSync()
:'';
file.writeAsStringSync(currentContents + log);
}
Create an iTerm2 Coprocess that starts up the custom script when it sees the text "Starting Codex...."
And the full text for the second screenshot, second part is this (you'll need to update this for your system).
Obviously you will need to update the paths to be relative to your machine.
It should now be working and when an approvedCommand is requested by codex, it should automatically be approved and continue. This has been a game changer for me.
prefix_rule works for commands with separate argument tokens (e.g. ["eslint"] allows eslint <any args>), but fails when Codex wraps commands as ["/bin/zsh", "-lc", "<entire command>"].
The third token contains the full heredoc, so there's no way to match just the prefix.
@fschwahn, we're looking at the next round of extensions to the existing Rules feature, and we're interested in ideas and feedback. I'd appreciate it if you'd create a new enhancement request and clarify what changes or additions you'd like to see. This thread is quite long (and old) and covers a lot of things that are already supported.
Activity
michaelboeding commentedon Sep 16, 2025
Is this on the roadmap still? Would be very useful
NightMachinery commentedon Sep 25, 2025
I also need this. Codex keeps asking me to approve each curl call.
zwalden commentedon Oct 1, 2025
Curious about this too.
fcakyon commentedon Oct 5, 2025
Is this still not available in Codex? 😩
SwiftedMind commentedon Oct 9, 2025
This would help me a lot because I can't run
xcodebuildinside the sandboxxshapira commentedon Oct 19, 2025
We all need this one.
mattcorey commentedon Oct 22, 2025
This enhancement is probably my #1 request - there are certain commands that I always want to allow, such as running the scripts to build and test my project (similar to the
xcodebuildexample from @SwiftedMind a few weeks ago).The wildcards are an important aspect to this - tools such as 'axe' (https://github.com/cameroncooke/AXe) would commonly be run over and over again, and provide different parameters each time. Needing to approve each individual combination of parameter is a non-starter, but running on yolo mode is not what I want to do.
l3wi commentedon Oct 28, 2025
+1 to have this feature. Its so tedious to use codex otherwise
berndeplo commentedon Oct 29, 2025
+1
ssimeth commentedon Nov 13, 2025
+1
flamerged commentedon Nov 13, 2025
Why the fuck is there an option to allow a command and then not be asked for permission again, but it simply does not work??
tarmolehtpuu commentedon Nov 20, 2025
Yeah also got surprised by that, but I think it whitelists even the args - so it will only work if the cmd has exactly the same args.
Came here looking for a way to autoallow gofmt but I am ok reviewing other edits and such. Please consider this feature :)
praxder commentedon Nov 25, 2025
I got really tired of having to always approve this, so I wrote a custom script that allows you to whitelist certain commands. I've been using it for about a month and it's a game changer with Codex CLI. Keep in mind this is my personal script, so you might have to tweak it to get it working right for you, but here's how to set it up:
Prerequisites:
~/.zshrc):this gives us a string to watch for when codex starts and ends.
codex_coprocess.dart(to be used in next step).You can obviously edit the
approvedCommandslist as needed.And the full text for the second screenshot, second part is this (you'll need to update this for your system).
/Users/adam/Developer/flutter_sdk/bin/dart "/Users/adam/Developer/Scripts/codex_coprocess/lib/codex_coprocess.dart"Obviously you will need to update the paths to be relative to your machine.
It should now be working and when an
approvedCommandis requested by codex, it should automatically be approved and continue. This has been a game changer for me.rimesime-alt commentedon Dec 7, 2025
+1
amit777 commentedon Dec 21, 2025
+1
hivokas commentedon Dec 21, 2025
Also had this concern, was able to fix it by adding
to
~/.codex/rules/default.rules.Now Codex can run eslint with any arguments without asking me permission.
johan456789 commentedon Dec 27, 2025
this works quite well. documentation:
https://developers.openai.com/codex/local-config/#rules-preview
Culpable commentedon Dec 30, 2025
prefix_ruleworks for commands with separate argument tokens (e.g.["eslint"]allowseslint <any args>), but fails when Codex wraps commands as["/bin/zsh", "-lc", "<entire command>"].The third token contains the full heredoc, so there's no way to match just the prefix.
Example that works:
Example that fails:
Request: Please add substring/glob support for within-token matching, e.g.:
etraut-openai commentedon Jan 14, 2026
This feature is supported through the "rules" mechanism, which is documented here.
fschwahn commentedon Jan 14, 2026
@etraut-openai
This does not seem to be possible with the rules mechanism at the moment.
etraut-openai commentedon Jan 14, 2026
@fschwahn, we're looking at the next round of extensions to the existing Rules feature, and we're interested in ideas and feedback. I'd appreciate it if you'd create a new enhancement request and clarify what changes or additions you'd like to see. This thread is quite long (and old) and covers a lot of things that are already supported.
fschwahn commentedon Jan 14, 2026
@Culpable you want to open your comment as a new issue? I think it's very clearly written.
aa403 commentedon Feb 8, 2026
this should be reopened -- @etraut-openai the current method doesn't handle wildcards at all as far as i can see. it's super frustrating.
etraut-openai commentedon Feb 8, 2026
@aa403, if you'd like to suggest a new capability, please open a new feature request.