Describe the bug
On every interactive start, the CLI applies the managed-settings fail-closed posture that disables bypass-permissions mode — on an account where the policy resolves as absent and where nothing failed. Once applied it is never lifted for the life of the session, so --yolo, --allow-all-* and /allow-all stay blocked.
The startup log contradicts itself within 1 ms:
[managedSettings] device MDM: no policy present on this device
[managedSettings] server policy fetch skipped: no authenticated GitHub host available
[managedSettings] effective policy resolved: source=none, bypassDisabled=false,
serverFetchFailed=false, policyHelperFailed=false, policyHelperFailClosed=false
[managedSettings] applied: no bypass restriction in force (managed policy absent)
[managedSettings] applied: bypass-permissions mode DISABLED by enterprise policy
(fail-closed: policy could not be determined)
— /allow-all and permission escalation are now blocked
The resolver reports source=none, bypassDisabled=false and no failure flag of any kind, and the first applied: line agrees ("no bypass restriction in force"). A second applied: immediately overrides it with the undetermined-policy posture.
The trigger appears to be the pre-auth window: server policy fetch skipped: no authenticated GitHub host available is logged just before, while the CLI still reports Login status unknown. The fetch is not failing — it is skipped because auth has not resolved yet — but it seems to be treated as "policy could not be determined".
There is no managed policy on this account. The managed-settings cache confirms the server answered that there is none:
{"schemaVersion":1,"retrievedAtMs":1788776811105,"account":"<hash>","response":null}
and the same session logs serverResolution=Live.
It is never relaxed. In a full session log the disable is applied 3 times and nothing lifts it — no "relaxed", no "re-enabled". Unlike the MCP interim window, this restriction has no restore path once auth resolves.
Notable asymmetry: non-interactive mode is not affected. copilot -p "..." --yolo runs tools without prompting. Only the interactive startup path ends up with the restriction stuck on.
Likely cause
This area changed in 1.0.81:
"An enterprise managed-settings policy is no longer rejected when permissions.disableBypassPermissionsMode carries an unrecognized value; it is now logged and enforced as disable."
An absent policy looks to be taking the same "unrecognized ⇒ disable" path.
Related
Affected version
1.0.83 (also present in the 1.0.84-0 / 1.0.84-1 prereleases)
Steps to reproduce the behavior
- Sign in on an account with no enterprise managed policy (
~/Library/Caches/copilot/managed-settings/*.json shows "response": null).
- Start the CLI interactively:
copilot --yolo.
- Observe that permission escalation is blocked.
- Open the session log in
~/.copilot/logs/process-*.log and see the two contradictory applied: lines quoted above.
- Grep the same log for any line lifting the restriction later in the session — there is none:
grep -c "bypass-permissions mode DISABLED" ~/.copilot/logs/process-*.log # 3
grep -iE "relax|re-enabled|restriction lifted" ~/.copilot/logs/process-*.log # no matches
Counter-check that the flag itself is fine — this one is not blocked and runs the tool without prompting:
copilot -p "Run the shell command 'echo YOLO_OK' and reply with only its output." --yolo
Expected behavior
When the effective policy resolves to source=none with bypassDisabled=false and no failure flags set, bypass-permissions mode must stay enabled, and --yolo must work in interactive mode as it does with -p.
A policy fetch that is skipped pending authentication is not a policy that could not be determined. The restriction should at most be provisional during that window, and must be lifted once auth resolves and the policy comes back absent.
At minimum, the two applied: lines should not be able to disagree about the same resolution — the second one currently wins with the opposite conclusion, 1 ms after the first.
Additional context
- Operating system: macOS
- CPU architecture: ARM (darwin-arm64)
- Node.js: v24.20.0
- Shell: zsh
- No
defaultMode / defaultPermissionMode set; ~/.copilot/settings.json contains only showReasoning and model.
- No
COPILOT_* permission env vars set (COPILOT_ALLOW_ALL, COPILOT_ASSISTED_APPROVAL both unset).
--assisted-approval is not in use, so the safety judge is not what is engaging here.
Full startup sequence from ~/.copilot/logs/process-*.log, in order, unedited:
[INFO] [managedSettings] device MDM: no policy present on this device
[INFO] [managedSettings] server policy fetch skipped: no authenticated GitHub host available
[INFO] [managedSettings] effective policy resolved: source=none, bypassDisabled=false, serverFetchFailed=false, policyHelperFailed=false, policyHelperFailClosed=false
[INFO] [managedSettings] applied: no bypass restriction in force (managed policy absent)
[INFO] [managedSettings] applied: bypass-permissions mode DISABLED by enterprise policy (fail-closed: policy could not be determined) — /allow-all and permission escalation are now blocked
[INFO] [managedSettings] self-fetch starting for account (device)
[INFO] [managedSettings] device MDM: no policy present on this device
[INFO] [managedSettings] server policy fetch skipped: no authenticated GitHub host available
[INFO] [managedSettings] effective policy resolved: source=none, bypassDisabled=false, serverFetchFailed=false, policyHelperFailed=false, policyHelperFailClosed=false
[INFO] [managedSettings] applied: no bypass restriction in force (managed policy absent)
[INFO] [managedSettings] self-fetch complete for (device): bypassDisabled=false, serverFetchFailed=false, serverResolution=Live, serverRetryableFailure=false, deviceLoadFailed=false
[INFO] Starting Copilot CLI: 1.0.83
[INFO] Login status unknown
Note that Starting Copilot CLI and Login status unknown come after the restriction has already been applied.
Later in the same session, once the account is authenticated, the policy is confirmed absent again and still nothing lifts the restriction:
[INFO] [managedSettings] self-fetch complete for https://github.com/<user>: bypassDisabled=false, serverFetchFailed=false, serverResolution=FreshCache, serverRetryableFailure=false, deviceLoadFailed=false
[INFO] [managedSettings] effective policy resolved: source=none, bypassDisabled=false, serverFetchFailed=false, policyHelperFailed=false, policyHelperFailClosed=false
Describe the bug
On every interactive start, the CLI applies the managed-settings fail-closed posture that disables bypass-permissions mode — on an account where the policy resolves as absent and where nothing failed. Once applied it is never lifted for the life of the session, so
--yolo,--allow-all-*and/allow-allstay blocked.The startup log contradicts itself within 1 ms:
The resolver reports
source=none,bypassDisabled=falseand no failure flag of any kind, and the firstapplied:line agrees ("no bypass restriction in force"). A secondapplied:immediately overrides it with the undetermined-policy posture.The trigger appears to be the pre-auth window:
server policy fetch skipped: no authenticated GitHub host availableis logged just before, while the CLI still reportsLogin status unknown. The fetch is not failing — it is skipped because auth has not resolved yet — but it seems to be treated as "policy could not be determined".There is no managed policy on this account. The managed-settings cache confirms the server answered that there is none:
{"schemaVersion":1,"retrievedAtMs":1788776811105,"account":"<hash>","response":null}and the same session logs
serverResolution=Live.It is never relaxed. In a full session log the disable is applied 3 times and nothing lifts it — no "relaxed", no "re-enabled". Unlike the MCP interim window, this restriction has no restore path once auth resolves.
Notable asymmetry: non-interactive mode is not affected.
copilot -p "..." --yoloruns tools without prompting. Only the interactive startup path ends up with the restriction stuck on.Likely cause
This area changed in 1.0.81:
An absent policy looks to be taking the same "unrecognized ⇒ disable" path.
Related
--yolopath and reproduces from a bare terminal invocation.Affected version
1.0.83 (also present in the 1.0.84-0 / 1.0.84-1 prereleases)
Steps to reproduce the behavior
~/Library/Caches/copilot/managed-settings/*.jsonshows"response": null).copilot --yolo.~/.copilot/logs/process-*.logand see the two contradictoryapplied:lines quoted above.Counter-check that the flag itself is fine — this one is not blocked and runs the tool without prompting:
copilot -p "Run the shell command 'echo YOLO_OK' and reply with only its output." --yoloExpected behavior
When the effective policy resolves to
source=nonewithbypassDisabled=falseand no failure flags set, bypass-permissions mode must stay enabled, and--yolomust work in interactive mode as it does with-p.A policy fetch that is skipped pending authentication is not a policy that could not be determined. The restriction should at most be provisional during that window, and must be lifted once auth resolves and the policy comes back absent.
At minimum, the two
applied:lines should not be able to disagree about the same resolution — the second one currently wins with the opposite conclusion, 1 ms after the first.Additional context
defaultMode/defaultPermissionModeset;~/.copilot/settings.jsoncontains onlyshowReasoningandmodel.COPILOT_*permission env vars set (COPILOT_ALLOW_ALL,COPILOT_ASSISTED_APPROVALboth unset).--assisted-approvalis not in use, so the safety judge is not what is engaging here.Full startup sequence from
~/.copilot/logs/process-*.log, in order, unedited:Note that
Starting Copilot CLIandLogin status unknowncome after the restriction has already been applied.Later in the same session, once the account is authenticated, the policy is confirmed absent again and still nothing lifts the restriction: