diff --git a/openshell/v1/internal/converter/profile.go b/openshell/v1/internal/converter/profile.go index e7583c9..8eaf845 100644 --- a/openshell/v1/internal/converter/profile.go +++ b/openshell/v1/internal/converter/profile.go @@ -82,29 +82,24 @@ func CredentialTokenGrantTypeToProto(t types.CredentialTokenGrantType) pb.Provid // --- NetworkEndpoint --- -// NetworkEndpointFromProto converts a proto NetworkEndpoint to an SDK NetworkEndpoint. -// Only Host, Port, and Protocol are mapped; additional proto fields are ignored. +// NetworkEndpointFromProto converts a proto NetworkEndpoint to an SDK +// NetworkEndpoint. Profile endpoints carry the same fields as policy +// endpoints, so every field is mapped. func NetworkEndpointFromProto(ep *sbv1.NetworkEndpoint) *types.NetworkEndpoint { if ep == nil { return nil } - return &types.NetworkEndpoint{ - Host: ep.GetHost(), - Port: ep.GetPort(), - Protocol: ep.GetProtocol(), - } + result := policyNetworkEndpointFromProto(ep) + return &result } -// NetworkEndpointToProto converts an SDK NetworkEndpoint to a proto NetworkEndpoint. +// NetworkEndpointToProto converts an SDK NetworkEndpoint to a proto +// NetworkEndpoint, mapping every field. func NetworkEndpointToProto(ep *types.NetworkEndpoint) *sbv1.NetworkEndpoint { if ep == nil { return nil } - return &sbv1.NetworkEndpoint{ - Host: ep.Host, - Port: ep.Port, - Protocol: ep.Protocol, - } + return policyNetworkEndpointToProto(ep) } // --- NetworkBinary --- diff --git a/openshell/v1/internal/converter/profile_test.go b/openshell/v1/internal/converter/profile_test.go index 1cdf3b9..7c4b884 100644 --- a/openshell/v1/internal/converter/profile_test.go +++ b/openshell/v1/internal/converter/profile_test.go @@ -11,6 +11,7 @@ import ( sbv1 "github.com/ai-openshell/sdk-go/proto/sandboxv1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" ) @@ -751,3 +752,54 @@ func TestProviderProfileRoundTrip(t *testing.T) { assert.Equal(t, original.Discovery.Credentials, back.Discovery.Credentials) } + +// Profile endpoints share the policy endpoint message; access, enforcement, +// credential settings, and every other field must survive both directions +// (ai-openshell/sdk-go#12). +func TestNetworkEndpointRoundTripKeepsAllFields(t *testing.T) { + in := &sbv1.NetworkEndpoint{ + Host: "api.anthropic.com", + Port: 443, + Ports: []uint32{443, 8443}, + Protocol: "rest", + Tls: sbv1.NetworkTlsMode_NETWORK_TLS_MODE_SKIP, + Enforcement: sbv1.NetworkEnforcementMode_NETWORK_ENFORCEMENT_MODE_ENFORCE, + Access: sbv1.NetworkAccessPreset_NETWORK_ACCESS_PRESET_FULL, + AllowedIps: []string{"10.0.0.0/8"}, + Path: "/v1", + AllowUninspectedCredentials: true, + ProviderCredentialed: true, + CredentialBinding: &sbv1.NetworkCredentialBinding{Provider: "anthropic"}, + } + + ep := NetworkEndpointFromProto(in) + require.NotNil(t, ep) + assert.Equal(t, v1.NetworkAccessPresetFull, ep.Access) + assert.True(t, ep.AllowUninspectedCredentials) + require.NotNil(t, ep.CredentialBinding) + assert.Equal(t, "anthropic", ep.CredentialBinding.Provider) + + out := NetworkEndpointToProto(ep) + assert.True(t, proto.Equal(in, out), "round trip changed the endpoint:\nin: %v\nout: %v", in, out) +} + +func TestProviderProfileRoundTripKeepsEndpointAccess(t *testing.T) { + in := &pb.ProviderProfile{ + Id: "claude-code", + Endpoints: []*sbv1.NetworkEndpoint{{ + Host: "api.anthropic.com", + Port: 443, + Protocol: "rest", + Access: sbv1.NetworkAccessPreset_NETWORK_ACCESS_PRESET_READ_WRITE, + Enforcement: sbv1.NetworkEnforcementMode_NETWORK_ENFORCEMENT_MODE_ENFORCE, + }}, + } + + profile := ProviderProfileFromProto(in) + require.Len(t, profile.Endpoints, 1) + assert.Equal(t, v1.NetworkAccessPresetReadWrite, profile.Endpoints[0].Access) + + out := ProviderProfileToProto(profile) + require.Len(t, out.GetEndpoints(), 1) + assert.True(t, proto.Equal(in.GetEndpoints()[0], out.GetEndpoints()[0])) +} diff --git a/openshell/v1/types/network_policy.go b/openshell/v1/types/network_policy.go index 0e41348..d26cf98 100644 --- a/openshell/v1/types/network_policy.go +++ b/openshell/v1/types/network_policy.go @@ -53,9 +53,9 @@ const ( NetworkAccessPresetFull NetworkAccessPreset = 3 ) -// PolicyNetworkEndpoint describes a full network endpoint with its access controls -// as used in sandbox network policy rules. This is distinct from [NetworkEndpoint] -// which is the simplified profile-level endpoint (Host, Port, Protocol only). +// PolicyNetworkEndpoint describes a network endpoint with its access controls, +// as used in sandbox network policy rules and, as [NetworkEndpoint], in +// provider profiles. type PolicyNetworkEndpoint struct { Host string Port uint32 diff --git a/openshell/v1/types/profile.go b/openshell/v1/types/profile.go index 1589eb2..b2886c8 100644 --- a/openshell/v1/types/profile.go +++ b/openshell/v1/types/profile.go @@ -139,12 +139,11 @@ type TokenGrantAudienceOverride struct { Scopes []string } -// NetworkEndpoint describes a network endpoint provided by a profile. -type NetworkEndpoint struct { - Host string - Port uint32 - Protocol string -} +// NetworkEndpoint describes a network endpoint provided by a profile. Profiles +// and sandbox policies share one endpoint message, so it is the same type as +// [PolicyNetworkEndpoint], with access, enforcement, rules, and credential +// settings. +type NetworkEndpoint = PolicyNetworkEndpoint // NetworkBinary describes a binary artifact provided by a profile. type NetworkBinary struct { diff --git a/openshell/v1/types_reexport.go b/openshell/v1/types_reexport.go index c982391..2c7725b 100644 --- a/openshell/v1/types_reexport.go +++ b/openshell/v1/types_reexport.go @@ -15,6 +15,12 @@ type NetworkPolicyRule = types.NetworkPolicyRule // PolicyNetworkEndpoint describes a full network endpoint in a sandbox network policy rule. type PolicyNetworkEndpoint = types.PolicyNetworkEndpoint +// NetworkCredentialBinding binds an endpoint to static credentials from an attached provider. +type NetworkCredentialBinding = types.NetworkCredentialBinding + +// McpOptions configures MCP inspection for a policy endpoint. +type McpOptions = types.McpOptions + // NetworkTLSMode controls TLS handling for a policy endpoint. type NetworkTLSMode = types.NetworkTLSMode