diff --git a/go/client_test.go b/go/client_test.go index d0139eb11..2332a7701 100644 --- a/go/client_test.go +++ b/go/client_test.go @@ -3834,6 +3834,26 @@ func TestSessionRequests_ManagedSettings(t *testing.T) { } }) + t.Run("accepts future bypass-permissions modes", func(t *testing.T) { + req := createSessionRequest{ManagedSettings: &ManagedSettings{ + Permissions: &ManagedSettingsPermissions{ + DisableBypassPermissionsMode: DisableBypassPermissionsMode("future-fail-closed-mode"), + }, + }} + data, err := json.Marshal(req) + if err != nil { + t.Fatalf("Failed to marshal: %v", err) + } + var m map[string]any + if err := json.Unmarshal(data, &m); err != nil { + t.Fatalf("Failed to unmarshal: %v", err) + } + perms := m["managedSettings"].(map[string]any)["permissions"].(map[string]any) + if perms["disableBypassPermissionsMode"] != "future-fail-closed-mode" { + t.Errorf("Expected future mode preserved, got %v", perms["disableBypassPermissionsMode"]) + } + }) + t.Run("omits managedSettings when nil", func(t *testing.T) { req := createSessionRequest{} data, _ := json.Marshal(req) diff --git a/go/internal/e2e/rpc_tasks_and_handlers_e2e_test.go b/go/internal/e2e/rpc_tasks_and_handlers_e2e_test.go index 0267f8d04..60fc2bd83 100644 --- a/go/internal/e2e/rpc_tasks_and_handlers_e2e_test.go +++ b/go/internal/e2e/rpc_tasks_and_handlers_e2e_test.go @@ -127,6 +127,8 @@ func TestRPCTasksAndHandlersE2E(t *testing.T) { }) t.Run("should report implemented error for invalid task agent model", func(t *testing.T) { + ctx.ConfigureForTest(t) + session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{ OnPermissionRequest: copilot.PermissionHandler.ApproveAll, }) diff --git a/go/types.go b/go/types.go index 60781d1da..f2218b27e 100644 --- a/go/types.go +++ b/go/types.go @@ -1569,11 +1569,16 @@ type ManagedSettings struct { } // DisableBypassPermissionsMode is the managed bypass-permissions policy. -type DisableBypassPermissionsMode = rpc.DisableBypassPermissionsMode +// +// The runtime may introduce additional fail-closed modes. Values are serialized +// as strings so callers can use newer modes without waiting for an SDK release. +type DisableBypassPermissionsMode string const ( // DisableBypassPermissionsModeDisable turns off bypass-permissions mode. - DisableBypassPermissionsModeDisable = rpc.DisableBypassPermissionsModeDisable + DisableBypassPermissionsModeDisable DisableBypassPermissionsMode = "disable" + // DisableBypassPermissionsModeAllowAutoOnly permits only automatic bypass. + DisableBypassPermissionsModeAllowAutoOnly DisableBypassPermissionsMode = "allow-auto-only" ) // ManagedSettingsPermissions is the permissions-only managed policy injected @@ -1581,9 +1586,8 @@ const ( // accepts for fetched managed policy (e.g. "Read(**)", "Shell(git push *)"); // malformed rules are rejected by the runtime at session creation. type ManagedSettingsPermissions struct { - // DisableBypassPermissionsMode, when set to "disable", turns off - // bypass-permissions ("yolo") mode for the session. Deny-wins: no other - // layer can re-enable it. + // DisableBypassPermissionsMode controls bypass-permissions ("yolo") mode for + // the session. Deny-wins: no other layer can grant broader bypass permissions. DisableBypassPermissionsMode DisableBypassPermissionsMode `json:"disableBypassPermissionsMode,omitempty"` // Deny lists operations that must always be denied. Unioned across layers. Deny []string `json:"deny,omitzero"` diff --git a/java/sdk/src/main/java/com/github/copilot/rpc/DisableBypassPermissionsModes.java b/java/sdk/src/main/java/com/github/copilot/rpc/DisableBypassPermissionsModes.java new file mode 100644 index 000000000..cf98f0526 --- /dev/null +++ b/java/sdk/src/main/java/com/github/copilot/rpc/DisableBypassPermissionsModes.java @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ +package com.github.copilot.rpc; + +/** + * Known values for the managed bypass-permissions policy. + * + *
+ * The wire contract is an open string so callers can pass newer fail-closed
+ * modes directly to
+ * {@link ManagedSettingsPermissions#setDisableBypassPermissionsMode(String)}.
+ */
+public final class DisableBypassPermissionsModes {
+ /** Turns off bypass-permissions mode. */
+ public static final String DISABLE = "disable";
+
+ /** Permits bypass only for automatic operations. */
+ public static final String ALLOW_AUTO_ONLY = "allow-auto-only";
+
+ private DisableBypassPermissionsModes() {
+ }
+}
diff --git a/java/sdk/src/main/java/com/github/copilot/rpc/ManagedSettingsPermissions.java b/java/sdk/src/main/java/com/github/copilot/rpc/ManagedSettingsPermissions.java
index 0923cea54..dd714621b 100644
--- a/java/sdk/src/main/java/com/github/copilot/rpc/ManagedSettingsPermissions.java
+++ b/java/sdk/src/main/java/com/github/copilot/rpc/ManagedSettingsPermissions.java
@@ -15,7 +15,7 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class ManagedSettingsPermissions {
@JsonProperty("disableBypassPermissionsMode")
- private DisableBypassPermissionsMode disableBypassPermissionsMode;
+ private String disableBypassPermissionsMode;
@JsonProperty("deny")
private List