mpa

package
v1.34.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

README

Multi Party Authorization

This module enables multi-party authorization for any sansshell command. Approval data is stored in-memory in sansshell-server.

User flow

MPA must be explicitly requested. When requested, the MPA flow will be used regardless of whether a policy would allow a command without MPA.

  1. A user issues commands.

    $ sanssh -mpa -targets=1.2.3.4 -justification emergency exec run /bin/echo hi
    Waiting for multi-party approval on all targets, ask an approver to run:
      sanssh --targets 1.2.3.4 mpa approve 244407fc-6b9b338a-db0760b8
    
  2. The approver views the commands and approves it.

    $ sanssh -targets=1.2.3.4 mpa list
    244407fc-6b9b338a-db0760b8 /Exec.Exec/Run from sanssh for emergency
    $ sanssh -targets=1.2.3.4 mpa get 244407fc-6b9b338a-db0760b8
    {
    "action": {
       "user": "sanssh",
       "justification": "emergency",
       "method": "/Exec.Exec/Run",
       "message": {
          "@type": "type.googleapis.com/Exec.ExecRequest",
          "command": "/bin/echo",
          "args": [
          "hi"
          ]
       }
    }
    }
    $ sanssh -targets=1.2.3.4 mpa approve 244407fc-6b9b338a-db0760b8
    
  3. If the user's command is still running, it will complete. If the user had stopped their command, they can rerun it and the approval will still be valid as long as the command's input remains the same and the sansshell-server still has the approval in memory. Approvals are lost if the server restarts, if the server evicts the approval due to age or staleness, or if a user calls sanssh mpa clear oon the request id.

Enabling MPA

SansShell is built on a principle of "Don't pay for what you don't use". MPA is a more invasive than the typical sansshell module, so it requires updating more places than most modules. The reference sanssh, sansshell-server, and proxy-server binaries implement these changes.

  1. In sanssh, in addition to importing the module to get the mpa subcommand, you should conditionally add interceptors when a -mpa flag is provided to the cli. This will let other sanssh commands use MPA with the -mpa flag and get the user experience mentioned above. There are four interceptors.

    1. Unary interceptor for direct calls
    2. Stream interceptor for direct calls
    3. Unary interceptor for proxied calls
    4. Stream interceptor for proxied calls.

    The interceptors for direct calls get added when dialing out.

    proxy.DialContext(ctx, proxy, targets,
       grpc.WithStreamInterceptor(mpahooks.StreamClientIntercepter),
       grpc.WithUnaryInterceptor(mpahooks.MPAUnaryClientInterceptor))
    

    The interceptors for proxied calls are added as fields in the *proxy.Conn struct.

    conn.UnaryInterceptors = []proxy.UnaryInterceptor{mpahooks.ProxyClientUnaryInterceptor(state)}
    conn.StreamInterceptors = []proxy.StreamInterceptor{mpahooks.ProxyClientStreamInterceptor(state)}
    
  2. In sansshell-server, import the MPA service and add an authz hook to consult the local datastore for MPA info.

    mpa "github.com/Snowflake-Labs/sansshell/services/mpa/server"
    server.WithAuthzHook(mpa.ServerMPAAuthzHook)
    
  3. If using the proxy-server, add an authz hook to consult the server for MPA info.

    proxy.WithAuthzHook(mpa.ProxyMPAAuthzHook)
    

    You'll also need to update the server's rego policies to reject requests that unexpectedly set proxied-sansshell-identity metadata if it allows callers other than the proxy to make direct calls. If you fail to do so, a direct caller can manipulate the metadata to approve their own request. For example, the policy below will reject calls if proxied identity information is in the metadata and the caller is something other than a peer with an identity of "proxy".

    package sansshell.authz
    default authz = false
    authz {
       allow
       not deny
    }
    deny {
       input.metadata["proxied-sansshell-identity"]
       not input.peer.principal.id = "proxy"
    }
    
  4. Any approvers must be able to call /Mpa.Mpa/Approve and any requestor must be able to call /Mpa.Mpa/Store. It's highly recommended to additionally let potential approvers call /Mpa.Mpa/Get and potential requestors call /Mpa.Mpa/WaitForApproval for better user experiences. /Mpa.Mpa/Clear can be used for cancelling MPA requests.

Approvers will show up in RPCAuthInput. Match on these in the OPA policies.

allow if {
    input.approvers[_].principal.id == 'superuser'
}

Design details

MPA requests and approvals are stored in memory in sansshell-server. The id for a request is generated as a hash of the request information, allowing us to reuse the same id for multiple identical requests across multiple commands or across multiple machines.

To support proxying, there are multiple ways of populating the user identity used in /Mpa.Mpa/Store and /Mpa.Mpa/Approve.

  1. From the proxied-sansshell-identity key in the gRPC metadata, used if the identity is set and the server has been configured to accept a proxied identity. The value of this is a JSON representation of rpcauth.Principal.
  2. From the peer identity of the call, used in all other cases.

Justification information can be provided via a sansshell-justification key in the gRPC metadata, available as a constant at rpcauth.ReqJustKey.

The values in RPCAuthInput are populated by authz hooks that look up a MPA request based on the sansshell-mpa-request-id key in the gRPC metadata. Requests will fail if this refers to an invalid or missing request.

Client-side streaming RPCs that involve more than one streamed message are not supported because it's not possible to evaluate the client's messages prior to the request.

Server-only flow

The server-only flow is the simplest scenario.

sequenceDiagram
    actor approver
    actor client
    client->>+server: /Mpa.Mpa/Store
    server->>server: PolicyCheck / log
    server->>-client: ID for request
    client->>approver: Give request ID
    approver->>+server: /Mpa.Mpa/Approve
    server->>-server: PolicyCheck / log
    client->>server: Make normal call with sansshell-mpa-request-id
    server->>server: PolicyCheck / log

Typical usage will involve /Mpa.Mpa/WaitForApproval so that sanssh can make the call as soon as it has approval.

sequenceDiagram
    actor approver
    actor client
    client->>+server: /Mpa.Mpa/Store
    server->>server: PolicyCheck / log
    server->>-client: ID for request
    client->>+server: /Mpa.Mpa/WaitForApproval
    server->>server: PolicyCheck / log
    client->>approver: Give request ID
    approver->>+server: /Mpa.Mpa/Approve
    server->>-server: PolicyCheck / log
    server->>-client: /Mpa.Mpa/WaitForApproval completes
    client->>server: Make normal call with sansshell-mpa-request-id
    server->>server: PolicyCheck / log
Server + Proxy flow

The proxy flow is a bit more complicated than the server flow because the proxy relies on the server for maintaining state.

sequenceDiagram
    actor approver
    actor client
    client->>+proxy: /Mpa.Mpa/Store
    proxy->>proxy: PolicyCheck / log
    proxy->>+server: /Mpa.Mpa/Store
    server->>server: PolicyCheck / log
    server->>-proxy: ID for request
    proxy->>-client: ID for request
    client->>+proxy: /Mpa.Mpa/WaitForApproval
    proxy->>proxy: PolicyCheck / log
    proxy->>+server: /Mpa.Mpa/WaitForApproval
    server->>server: PolicyCheck / log
    client->>approver: Give request ID
    approver->>+proxy: /Mpa.Mpa/Approve
    proxy->>proxy: PolicyCheck / log
    proxy->>-server: /Mpa.Mpa/Approve
    server->>server: PolicyCheck / log
    server->>-proxy: /Mpa.Mpa/WaitForApproval completes
    proxy->>-client: /Mpa.Mpa/WaitForApproval completes
    client->>+proxy: Make normal call with sansshell-mpa-request-id
    proxy->>+server: /Mpa.Mpa/Get
    server->>server: PolicyCheck / log
    server->>-proxy: Approver info
    proxy->>proxy: PolicyCheck / log
    proxy->>-server: Make normal call

Caveats

  • Due to the complexity of OPA policies, we don't support automatically recognizing that a request requires MPA.
    • If you want to give feedback that an action would succeed with MPA, check out DenialHints
  • We also don't support recognizing in advance whether MPA would let an action succeed.
  • You can easily write policies that allow people to approve actions even if their approval isn't useful
  • All state is stored in-memory in sansshell-server. Any restarts of the server will clear approvals.
  • Be wary of guarding too many actions behind MPA. If it gets used too regularly, humans will quickly get used to blindly approving commands without thinking through whether each command is necessary.

Documentation

Overview

Package mpa defines the RPC interface for the sansshell MPA actions.

Index

Constants

View Source
const (
	Mpa_Store_FullMethodName           = "/Mpa.Mpa/Store"
	Mpa_Approve_FullMethodName         = "/Mpa.Mpa/Approve"
	Mpa_WaitForApproval_FullMethodName = "/Mpa.Mpa/WaitForApproval"
	Mpa_List_FullMethodName            = "/Mpa.Mpa/List"
	Mpa_Get_FullMethodName             = "/Mpa.Mpa/Get"
	Mpa_Clear_FullMethodName           = "/Mpa.Mpa/Clear"
)

Variables

View Source
var Mpa_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "Mpa.Mpa",
	HandlerType: (*MpaServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Store",
			Handler:    _Mpa_Store_Handler,
		},
		{
			MethodName: "Approve",
			Handler:    _Mpa_Approve_Handler,
		},
		{
			MethodName: "WaitForApproval",
			Handler:    _Mpa_WaitForApproval_Handler,
		},
		{
			MethodName: "List",
			Handler:    _Mpa_List_Handler,
		},
		{
			MethodName: "Get",
			Handler:    _Mpa_Get_Handler,
		},
		{
			MethodName: "Clear",
			Handler:    _Mpa_Clear_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "mpa.proto",
}

Mpa_ServiceDesc is the grpc.ServiceDesc for Mpa service. It's only intended for direct use with grpc.RegisterService, and not to be introspected or modified (even as a copy)

Functions

func RegisterMpaServer

func RegisterMpaServer(s grpc.ServiceRegistrar, srv MpaServer)

Types

type Action

type Action struct {

	// The user that created the request.
	User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
	// User-supplied information on why the request is being made.
	Justification string `protobuf:"bytes,2,opt,name=justification,proto3" json:"justification,omitempty"`
	// The GRPC method name, as '/Package.Service/Method'
	Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
	// The request protocol buffer.
	Message *anypb.Any `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
	// contains filtered or unexported fields
}

func (*Action) Descriptor deprecated

func (*Action) Descriptor() ([]byte, []int)

Deprecated: Use Action.ProtoReflect.Descriptor instead.

func (*Action) GetJustification

func (x *Action) GetJustification() string

func (*Action) GetMessage

func (x *Action) GetMessage() *anypb.Any

func (*Action) GetMethod

func (x *Action) GetMethod() string

func (*Action) GetUser

func (x *Action) GetUser() string

func (*Action) ProtoMessage

func (*Action) ProtoMessage()

func (*Action) ProtoReflect

func (x *Action) ProtoReflect() protoreflect.Message

func (*Action) Reset

func (x *Action) Reset()

func (*Action) String

func (x *Action) String() string

type ApproveManyResponse

type ApproveManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *ApproveResponse
	Error error
}

ApproveManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type ApproveRequest

type ApproveRequest struct {

	// Approve takes an action instead of an ID to improve auditability
	// and allow richer authorization logic.
	Action *Action `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
	// contains filtered or unexported fields
}

func (*ApproveRequest) Descriptor deprecated

func (*ApproveRequest) Descriptor() ([]byte, []int)

Deprecated: Use ApproveRequest.ProtoReflect.Descriptor instead.

func (*ApproveRequest) GetAction

func (x *ApproveRequest) GetAction() *Action

func (*ApproveRequest) ProtoMessage

func (*ApproveRequest) ProtoMessage()

func (*ApproveRequest) ProtoReflect

func (x *ApproveRequest) ProtoReflect() protoreflect.Message

func (*ApproveRequest) Reset

func (x *ApproveRequest) Reset()

func (*ApproveRequest) String

func (x *ApproveRequest) String() string

type ApproveResponse

type ApproveResponse struct {
	// contains filtered or unexported fields
}

func (*ApproveResponse) Descriptor deprecated

func (*ApproveResponse) Descriptor() ([]byte, []int)

Deprecated: Use ApproveResponse.ProtoReflect.Descriptor instead.

func (*ApproveResponse) ProtoMessage

func (*ApproveResponse) ProtoMessage()

func (*ApproveResponse) ProtoReflect

func (x *ApproveResponse) ProtoReflect() protoreflect.Message

func (*ApproveResponse) Reset

func (x *ApproveResponse) Reset()

func (*ApproveResponse) String

func (x *ApproveResponse) String() string

type ClearManyResponse

type ClearManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *ClearResponse
	Error error
}

ClearManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type ClearRequest

type ClearRequest struct {
	Action *Action `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
	// contains filtered or unexported fields
}

func (*ClearRequest) Descriptor deprecated

func (*ClearRequest) Descriptor() ([]byte, []int)

Deprecated: Use ClearRequest.ProtoReflect.Descriptor instead.

func (*ClearRequest) GetAction

func (x *ClearRequest) GetAction() *Action

func (*ClearRequest) ProtoMessage

func (*ClearRequest) ProtoMessage()

func (*ClearRequest) ProtoReflect

func (x *ClearRequest) ProtoReflect() protoreflect.Message

func (*ClearRequest) Reset

func (x *ClearRequest) Reset()

func (*ClearRequest) String

func (x *ClearRequest) String() string

type ClearResponse

type ClearResponse struct {
	// contains filtered or unexported fields
}

func (*ClearResponse) Descriptor deprecated

func (*ClearResponse) Descriptor() ([]byte, []int)

Deprecated: Use ClearResponse.ProtoReflect.Descriptor instead.

func (*ClearResponse) ProtoMessage

func (*ClearResponse) ProtoMessage()

func (*ClearResponse) ProtoReflect

func (x *ClearResponse) ProtoReflect() protoreflect.Message

func (*ClearResponse) Reset

func (x *ClearResponse) Reset()

func (*ClearResponse) String

func (x *ClearResponse) String() string

type GetManyResponse

type GetManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *GetResponse
	Error error
}

GetManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type GetRequest

type GetRequest struct {
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// contains filtered or unexported fields
}

func (*GetRequest) Descriptor deprecated

func (*GetRequest) Descriptor() ([]byte, []int)

Deprecated: Use GetRequest.ProtoReflect.Descriptor instead.

func (*GetRequest) GetId

func (x *GetRequest) GetId() string

func (*GetRequest) ProtoMessage

func (*GetRequest) ProtoMessage()

func (*GetRequest) ProtoReflect

func (x *GetRequest) ProtoReflect() protoreflect.Message

func (*GetRequest) Reset

func (x *GetRequest) Reset()

func (*GetRequest) String

func (x *GetRequest) String() string

type GetResponse

type GetResponse struct {
	Action *Action `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
	// All approvers of the request.
	Approver []*Principal `protobuf:"bytes,2,rep,name=approver,proto3" json:"approver,omitempty"`
	// contains filtered or unexported fields
}

func (*GetResponse) Descriptor deprecated

func (*GetResponse) Descriptor() ([]byte, []int)

Deprecated: Use GetResponse.ProtoReflect.Descriptor instead.

func (*GetResponse) GetAction

func (x *GetResponse) GetAction() *Action

func (*GetResponse) GetApprover

func (x *GetResponse) GetApprover() []*Principal

func (*GetResponse) ProtoMessage

func (*GetResponse) ProtoMessage()

func (*GetResponse) ProtoReflect

func (x *GetResponse) ProtoReflect() protoreflect.Message

func (*GetResponse) Reset

func (x *GetResponse) Reset()

func (*GetResponse) String

func (x *GetResponse) String() string

type ListManyResponse

type ListManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *ListResponse
	Error error
}

ListManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type ListRequest

type ListRequest struct {
	// contains filtered or unexported fields
}

func (*ListRequest) Descriptor deprecated

func (*ListRequest) Descriptor() ([]byte, []int)

Deprecated: Use ListRequest.ProtoReflect.Descriptor instead.

func (*ListRequest) ProtoMessage

func (*ListRequest) ProtoMessage()

func (*ListRequest) ProtoReflect

func (x *ListRequest) ProtoReflect() protoreflect.Message

func (*ListRequest) Reset

func (x *ListRequest) Reset()

func (*ListRequest) String

func (x *ListRequest) String() string

type ListResponse

type ListResponse struct {
	Item []*ListResponse_Item `protobuf:"bytes,1,rep,name=item,proto3" json:"item,omitempty"`
	// contains filtered or unexported fields
}

func (*ListResponse) Descriptor deprecated

func (*ListResponse) Descriptor() ([]byte, []int)

Deprecated: Use ListResponse.ProtoReflect.Descriptor instead.

func (*ListResponse) GetItem

func (x *ListResponse) GetItem() []*ListResponse_Item

func (*ListResponse) ProtoMessage

func (*ListResponse) ProtoMessage()

func (*ListResponse) ProtoReflect

func (x *ListResponse) ProtoReflect() protoreflect.Message

func (*ListResponse) Reset

func (x *ListResponse) Reset()

func (*ListResponse) String

func (x *ListResponse) String() string

type ListResponse_Item

type ListResponse_Item struct {
	Action   *Action      `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
	Approver []*Principal `protobuf:"bytes,2,rep,name=approver,proto3" json:"approver,omitempty"`
	Id       string       `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
	// contains filtered or unexported fields
}

func (*ListResponse_Item) Descriptor deprecated

func (*ListResponse_Item) Descriptor() ([]byte, []int)

Deprecated: Use ListResponse_Item.ProtoReflect.Descriptor instead.

func (*ListResponse_Item) GetAction

func (x *ListResponse_Item) GetAction() *Action

func (*ListResponse_Item) GetApprover

func (x *ListResponse_Item) GetApprover() []*Principal

func (*ListResponse_Item) GetId

func (x *ListResponse_Item) GetId() string

func (*ListResponse_Item) ProtoMessage

func (*ListResponse_Item) ProtoMessage()

func (*ListResponse_Item) ProtoReflect

func (x *ListResponse_Item) ProtoReflect() protoreflect.Message

func (*ListResponse_Item) Reset

func (x *ListResponse_Item) Reset()

func (*ListResponse_Item) String

func (x *ListResponse_Item) String() string

type MpaClient

type MpaClient interface {
	// Store a request that we'd like to try running in the future. Requests
	// are stored in-memory and older requests may be cleared automatically.
	// This call is idempotent - requests from the same user with the same
	// contents will return the same id.
	//
	// The user for the request and any justification is implicitly passed in
	// via inspecting the peer of the RPC or via gRPC metadata.
	Store(ctx context.Context, in *StoreRequest, opts ...grpc.CallOption) (*StoreResponse, error)
	// Approve a previously stored request. A request can have multiple approvals
	// and can be approved by anybody but the original user that stored the request.
	//
	// The user for the request is implicitly passed in via inspecting the
	// peer of the RPC or via gRPC metadata.
	Approve(ctx context.Context, in *ApproveRequest, opts ...grpc.CallOption) (*ApproveResponse, error)
	// Block until at least one approval has been granted. This is used
	// as an optimization to avoid needing to poll for MPA approval.
	WaitForApproval(ctx context.Context, in *WaitForApprovalRequest, opts ...grpc.CallOption) (*WaitForApprovalResponse, error)
	// List available requests.
	List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
	// Get a request and all approvals associated with it.
	Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error)
	// Clear a stored request.
	//
	// This is typically unnecessary due to how requests are stored in memory
	// and forgotten after a process restart.
	Clear(ctx context.Context, in *ClearRequest, opts ...grpc.CallOption) (*ClearResponse, error)
}

MpaClient is the client API for Mpa service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.

func NewMpaClient

func NewMpaClient(cc grpc.ClientConnInterface) MpaClient

type MpaClientProxy

type MpaClientProxy interface {
	MpaClient
	StoreOneMany(ctx context.Context, in *StoreRequest, opts ...grpc.CallOption) (<-chan *StoreManyResponse, error)
	ApproveOneMany(ctx context.Context, in *ApproveRequest, opts ...grpc.CallOption) (<-chan *ApproveManyResponse, error)
	WaitForApprovalOneMany(ctx context.Context, in *WaitForApprovalRequest, opts ...grpc.CallOption) (<-chan *WaitForApprovalManyResponse, error)
	ListOneMany(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (<-chan *ListManyResponse, error)
	GetOneMany(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (<-chan *GetManyResponse, error)
	ClearOneMany(ctx context.Context, in *ClearRequest, opts ...grpc.CallOption) (<-chan *ClearManyResponse, error)
}

MpaClientProxy is the superset of MpaClient which additionally includes the OneMany proxy methods

func NewMpaClientProxy

func NewMpaClientProxy(cc *proxy.Conn) MpaClientProxy

NewMpaClientProxy creates a MpaClientProxy for use in proxied connections. NOTE: This takes a proxy.Conn instead of a generic ClientConnInterface as the methods here are only valid in proxy.Conn contexts.

type MpaServer

type MpaServer interface {
	// Store a request that we'd like to try running in the future. Requests
	// are stored in-memory and older requests may be cleared automatically.
	// This call is idempotent - requests from the same user with the same
	// contents will return the same id.
	//
	// The user for the request and any justification is implicitly passed in
	// via inspecting the peer of the RPC or via gRPC metadata.
	Store(context.Context, *StoreRequest) (*StoreResponse, error)
	// Approve a previously stored request. A request can have multiple approvals
	// and can be approved by anybody but the original user that stored the request.
	//
	// The user for the request is implicitly passed in via inspecting the
	// peer of the RPC or via gRPC metadata.
	Approve(context.Context, *ApproveRequest) (*ApproveResponse, error)
	// Block until at least one approval has been granted. This is used
	// as an optimization to avoid needing to poll for MPA approval.
	WaitForApproval(context.Context, *WaitForApprovalRequest) (*WaitForApprovalResponse, error)
	// List available requests.
	List(context.Context, *ListRequest) (*ListResponse, error)
	// Get a request and all approvals associated with it.
	Get(context.Context, *GetRequest) (*GetResponse, error)
	// Clear a stored request.
	//
	// This is typically unnecessary due to how requests are stored in memory
	// and forgotten after a process restart.
	Clear(context.Context, *ClearRequest) (*ClearResponse, error)
}

MpaServer is the server API for Mpa service. All implementations should embed UnimplementedMpaServer for forward compatibility

type Principal

type Principal struct {

	// The principal identifier (e.g. a username or service role)
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// Auxiliary groups associated with this principal.
	Groups []string `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty"`
	// contains filtered or unexported fields
}

func (*Principal) Descriptor deprecated

func (*Principal) Descriptor() ([]byte, []int)

Deprecated: Use Principal.ProtoReflect.Descriptor instead.

func (*Principal) GetGroups

func (x *Principal) GetGroups() []string

func (*Principal) GetId

func (x *Principal) GetId() string

func (*Principal) ProtoMessage

func (*Principal) ProtoMessage()

func (*Principal) ProtoReflect

func (x *Principal) ProtoReflect() protoreflect.Message

func (*Principal) Reset

func (x *Principal) Reset()

func (*Principal) String

func (x *Principal) String() string

type StoreManyResponse

type StoreManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *StoreResponse
	Error error
}

StoreManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type StoreRequest

type StoreRequest struct {

	// The GRPC method name, as '/Package.Service/Method'
	Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
	// The request protocol buffer.
	Message *anypb.Any `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
	// contains filtered or unexported fields
}

func (*StoreRequest) Descriptor deprecated

func (*StoreRequest) Descriptor() ([]byte, []int)

Deprecated: Use StoreRequest.ProtoReflect.Descriptor instead.

func (*StoreRequest) GetMessage

func (x *StoreRequest) GetMessage() *anypb.Any

func (*StoreRequest) GetMethod

func (x *StoreRequest) GetMethod() string

func (*StoreRequest) ProtoMessage

func (*StoreRequest) ProtoMessage()

func (*StoreRequest) ProtoReflect

func (x *StoreRequest) ProtoReflect() protoreflect.Message

func (*StoreRequest) Reset

func (x *StoreRequest) Reset()

func (*StoreRequest) String

func (x *StoreRequest) String() string

type StoreResponse

type StoreResponse struct {
	Id     string  `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	Action *Action `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"`
	// All approvers of the request. Storing is idempotent, so
	// approvers may be non-empty if we're storing a previously
	// approved command.
	Approver []*Principal `protobuf:"bytes,3,rep,name=approver,proto3" json:"approver,omitempty"`
	// contains filtered or unexported fields
}

func (*StoreResponse) Descriptor deprecated

func (*StoreResponse) Descriptor() ([]byte, []int)

Deprecated: Use StoreResponse.ProtoReflect.Descriptor instead.

func (*StoreResponse) GetAction

func (x *StoreResponse) GetAction() *Action

func (*StoreResponse) GetApprover

func (x *StoreResponse) GetApprover() []*Principal

func (*StoreResponse) GetId

func (x *StoreResponse) GetId() string

func (*StoreResponse) ProtoMessage

func (*StoreResponse) ProtoMessage()

func (*StoreResponse) ProtoReflect

func (x *StoreResponse) ProtoReflect() protoreflect.Message

func (*StoreResponse) Reset

func (x *StoreResponse) Reset()

func (*StoreResponse) String

func (x *StoreResponse) String() string

type UnimplementedMpaServer

type UnimplementedMpaServer struct {
}

UnimplementedMpaServer should be embedded to have forward compatible implementations.

func (UnimplementedMpaServer) Approve

func (UnimplementedMpaServer) Clear

func (UnimplementedMpaServer) Get

func (UnimplementedMpaServer) List

func (UnimplementedMpaServer) Store

func (UnimplementedMpaServer) WaitForApproval

type UnsafeMpaServer

type UnsafeMpaServer interface {
	// contains filtered or unexported methods
}

UnsafeMpaServer may be embedded to opt out of forward compatibility for this service. Use of this interface is not recommended, as added methods to MpaServer will result in compilation errors.

type WaitForApprovalManyResponse

type WaitForApprovalManyResponse struct {
	Target string
	// As targets can be duplicated this is the index into the slice passed to proxy.Conn.
	Index int
	Resp  *WaitForApprovalResponse
	Error error
}

WaitForApprovalManyResponse encapsulates a proxy data packet. It includes the target, index, response and possible error returned.

type WaitForApprovalRequest

type WaitForApprovalRequest struct {
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// contains filtered or unexported fields
}

func (*WaitForApprovalRequest) Descriptor deprecated

func (*WaitForApprovalRequest) Descriptor() ([]byte, []int)

Deprecated: Use WaitForApprovalRequest.ProtoReflect.Descriptor instead.

func (*WaitForApprovalRequest) GetId

func (x *WaitForApprovalRequest) GetId() string

func (*WaitForApprovalRequest) ProtoMessage

func (*WaitForApprovalRequest) ProtoMessage()

func (*WaitForApprovalRequest) ProtoReflect

func (x *WaitForApprovalRequest) ProtoReflect() protoreflect.Message

func (*WaitForApprovalRequest) Reset

func (x *WaitForApprovalRequest) Reset()

func (*WaitForApprovalRequest) String

func (x *WaitForApprovalRequest) String() string

type WaitForApprovalResponse

type WaitForApprovalResponse struct {
	// contains filtered or unexported fields
}

func (*WaitForApprovalResponse) Descriptor deprecated

func (*WaitForApprovalResponse) Descriptor() ([]byte, []int)

Deprecated: Use WaitForApprovalResponse.ProtoReflect.Descriptor instead.

func (*WaitForApprovalResponse) ProtoMessage

func (*WaitForApprovalResponse) ProtoMessage()

func (*WaitForApprovalResponse) ProtoReflect

func (x *WaitForApprovalResponse) ProtoReflect() protoreflect.Message

func (*WaitForApprovalResponse) Reset

func (x *WaitForApprovalResponse) Reset()

func (*WaitForApprovalResponse) String

func (x *WaitForApprovalResponse) String() string

Directories

Path Synopsis
Package client provides the client interface for 'mpa'
Package client provides the client interface for 'mpa'
Package mpahooks provides grpc interceptors and other helpers for implementing MPA.
Package mpahooks provides grpc interceptors and other helpers for implementing MPA.
Package server implements the sansshell 'Mpa' service.
Package server implements the sansshell 'Mpa' service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL