Documentation
¶
Overview ¶
Package privilegedhelper defines the authenticated wire protocol shared by rshell's privileged helper and the Datadog Private Action Runner.
Index ¶
- Constants
- Variables
- type AgentPolicy
- type Client
- type ConnectionInfo
- type Credential
- type CredentialKey
- type DirectorKeyProof
- type ExecuteRequest
- type ExecuteResponse
- type ExecutionMode
- type Executor
- type KeyType
- type PrivateActionTask
- func (*PrivateActionTask) Descriptor() ([]byte, []int)deprecated
- func (x *PrivateActionTask) GetActionName() string
- func (x *PrivateActionTask) GetBundleId() string
- func (x *PrivateActionTask) GetConnectionInfo() *ConnectionInfo
- func (x *PrivateActionTask) GetExpirationTime() *timestamppb.Timestamp
- func (x *PrivateActionTask) GetInputs() *structpb.Struct
- func (x *PrivateActionTask) GetOrgId() int64
- func (x *PrivateActionTask) GetSystemInputs() *SystemInputs
- func (x *PrivateActionTask) GetTaskId() string
- func (*PrivateActionTask) ProtoMessage()
- func (x *PrivateActionTask) ProtoReflect() protoreflect.Message
- func (x *PrivateActionTask) Reset()
- func (x *PrivateActionTask) String() string
- type RemoteAction
- func (*RemoteAction) Descriptor() ([]byte, []int)deprecated
- func (x *RemoteAction) GetAllowedCommands() []string
- func (x *RemoteAction) GetAllowedPaths() []string
- func (x *RemoteAction) GetSystemServices() map[string]*structpb.ListValue
- func (*RemoteAction) ProtoMessage()
- func (x *RemoteAction) ProtoReflect() protoreflect.Message
- func (x *RemoteAction) Reset()
- func (x *RemoteAction) String() string
- type Server
- type Signature
- type SignedEnvelope
- type SystemInputs
- func (*SystemInputs) Descriptor() ([]byte, []int)deprecated
- func (x *SystemInputs) GetInput() isSystemInputs_Input
- func (x *SystemInputs) GetRemoteAction() *RemoteAction
- func (*SystemInputs) ProtoMessage()
- func (x *SystemInputs) ProtoReflect() protoreflect.Message
- func (x *SystemInputs) Reset()
- func (x *SystemInputs) String() string
- type SystemInputs_RemoteAction
- type VerifiedCommand
Constants ¶
const ( ProtocolVersion = 1 MaxMessageBytes = 1 << 20 )
const (
EscalationAllowed = "EscalationAllowed"
)
Variables ¶
var File_privilegedhelper_private_action_proto protoreflect.FileDescriptor
Functions ¶
This section is empty.
Types ¶
type AgentPolicy ¶ added in v0.0.28
type AgentPolicy struct {
AllowedCommands []string `json:"allowedCommands"`
AllowedPaths []string `json:"allowedPaths"`
AllowedSystemServices map[string][]string `json:"allowedSystemServices"`
ElevatableCommands []string `json:"elevatableCommands"`
}
AgentPolicy is an unsigned, Agent-supplied authorization narrowing sent alongside the signed task envelope. It represents the Private Action Runner's local datadog.yaml restricted_shell.allowed_* operator settings, the same operator settings that already narrow the non-privileged rshell path. Because it is unsigned and supplied by a process the helper does not fully trust, it can only narrow (intersect with) the signed backend policy and any local root-owned policy.json — it can never grant a permission beyond what those already allow.
A nil ExecuteRequest.AgentPolicy means the Agent imposes no narrowing at this layer at all: the effective policy is exactly signed task ∩ optional policy.json, identical to the protocol's behavior before this field existed.
A non-nil AgentPolicy applies independently per field, mirroring the exact nil-vs-empty convention Credential (policy.json) and the Agent's own datadog.yaml operator settings already use elsewhere in this system: for each of AllowedCommands, AllowedPaths, AllowedSystemServices, and ElevatableCommands, a nil value means that axis is left unrestricted by this layer (defer entirely to signed ∩ policy.json for that axis), while a non-nil-but-empty value is an explicit kill switch that denies every grant on that axis regardless of what the signed task or policy.json allow. This lets an operator narrow only the axes they have configured — e.g. setting only AllowedCommands — without accidentally denying every system service or path just because those fields were left unset.
These fields intentionally omit `omitempty`: Go's encoding/json treats nil and empty slices/maps identically when omitempty is set, which would erase the nil-vs-empty distinction this type depends on once it crosses the wire.
type Client ¶
func (Client) Execute ¶
func (c Client) Execute(ctx context.Context, req ExecuteRequest) (*ExecuteResponse, error)
func (Client) ExecuteSignedTask ¶
func (c Client) ExecuteSignedTask(ctx context.Context, envelope SignedEnvelope) (*ExecuteResponse, error)
ExecuteSignedTask dispatches an original backend-signed task to the helper. It is the preferred client entry point because callers cannot accidentally select a protocol version or place authorization data outside the signature.
type ConnectionInfo ¶
type ConnectionInfo struct {
RunnerId string `protobuf:"bytes,4,opt,name=runner_id,json=runnerId,proto3" json:"runner_id,omitempty"`
// contains filtered or unexported fields
}
func (*ConnectionInfo) Descriptor
deprecated
func (*ConnectionInfo) Descriptor() ([]byte, []int)
Deprecated: Use ConnectionInfo.ProtoReflect.Descriptor instead.
func (*ConnectionInfo) GetRunnerId ¶
func (x *ConnectionInfo) GetRunnerId() string
func (*ConnectionInfo) ProtoMessage ¶
func (*ConnectionInfo) ProtoMessage()
func (*ConnectionInfo) ProtoReflect ¶
func (x *ConnectionInfo) ProtoReflect() protoreflect.Message
func (*ConnectionInfo) Reset ¶
func (x *ConnectionInfo) Reset()
func (*ConnectionInfo) String ¶
func (x *ConnectionInfo) String() string
type Credential ¶
type Credential struct {
Version int `json:"version"`
OrgID int64 `json:"orgId"`
RunnerID string `json:"runnerId"`
Keys []CredentialKey `json:"keys"`
AllowedCommands []string `json:"allowedCommands"`
AllowedPaths []string `json:"allowedPaths"`
AllowedSystemServices map[string][]string `json:"allowedSystemServices"`
ElevatableCommands []string `json:"elevatableCommands"`
DirectorRoot json.RawMessage `json:"directorRoot,omitempty"`
// contains filtered or unexported fields
}
func LoadCredential ¶
func LoadCredential(path string) (*Credential, error)
func NewRequestCredential ¶
func NewRequestCredential(keys []CredentialKey) (*Credential, error)
NewRequestCredential trusts one bare verification key supplied with the request and applies no local policy. The embedding application is responsible for independently gating this mode through administrator configuration.
func (*Credential) Verify ¶
func (c *Credential) Verify(req ExecuteRequest, now time.Time) (*VerifiedCommand, error)
type CredentialKey ¶
type DirectorKeyProof ¶
type DirectorKeyProof struct {
Roots [][]byte `json:"roots,omitempty"`
Targets []byte `json:"targets"`
TargetPath string `json:"targetPath"`
TargetFile []byte `json:"targetFile"`
}
DirectorKeyProof contains the TUF metadata needed to authenticate one AP_RUNNER_KEYS target from the Director root in the helper credential.
type ExecuteRequest ¶
type ExecuteRequest struct {
Version int `json:"version"`
Envelope SignedEnvelope `json:"envelope"`
VerificationKeys []CredentialKey `json:"verificationKeys,omitempty"`
AgentPolicy *AgentPolicy `json:"agentPolicy,omitempty"`
}
func NewExecuteRequest ¶
func NewExecuteRequest(envelope SignedEnvelope) ExecuteRequest
NewExecuteRequest wraps an original backend-signed task for transport to the privileged helper. Security-relevant task fields, including the command and its requested effective permissions, deliberately remain inside envelope.Data so that the helper can authenticate them before use.
type ExecuteResponse ¶
type ExecutionMode ¶
type ExecutionMode string
ExecutionMode is derived exclusively from the authenticated action name and carried to the one-shot worker as part of the verified command policy.
const ( ExecutionModeReadOnly ExecutionMode = "readonly" ExecutionModeRemediation ExecutionMode = "remediation" )
type Executor ¶
type Executor interface {
Execute(context.Context, *VerifiedCommand) (*ExecuteResponse, error)
}
type KeyType ¶
type KeyType string
const ( KeyTypeX509RSA KeyType = "X509_RSA" KeyTypeED25519 KeyType = "ED25519" // KeyTypeTUFDirector identifies a request-scoped Director proof transported // in CredentialKey.PEM for protocol-v1 compatibility. It is never decoded as // a bare verification key. KeyTypeTUFDirector KeyType = "TUF_DIRECTOR" )
type PrivateActionTask ¶
type PrivateActionTask struct {
ActionName string `protobuf:"bytes,1,opt,name=action_name,json=actionName,proto3" json:"action_name,omitempty"`
BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"`
OrgId int64 `protobuf:"varint,3,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
TaskId string `protobuf:"bytes,4,opt,name=task_id,json=taskId,proto3" json:"task_id,omitempty"`
Inputs *structpb.Struct `protobuf:"bytes,6,opt,name=inputs,proto3" json:"inputs,omitempty"`
ConnectionInfo *ConnectionInfo `protobuf:"bytes,10,opt,name=connection_info,json=connectionInfo,proto3" json:"connection_info,omitempty"`
ExpirationTime *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=expiration_time,json=expirationTime,proto3" json:"expiration_time,omitempty"`
SystemInputs *SystemInputs `protobuf:"bytes,13,opt,name=system_inputs,json=systemInputs,proto3" json:"system_inputs,omitempty"`
// contains filtered or unexported fields
}
PrivateActionTask is the security-relevant subset of the PAR task wire format. Field numbers intentionally match private_actions.proto in the datadog-agent repository. Unknown fields remain covered by the backend signature and are ignored when decoding.
func (*PrivateActionTask) Descriptor
deprecated
func (*PrivateActionTask) Descriptor() ([]byte, []int)
Deprecated: Use PrivateActionTask.ProtoReflect.Descriptor instead.
func (*PrivateActionTask) GetActionName ¶
func (x *PrivateActionTask) GetActionName() string
func (*PrivateActionTask) GetBundleId ¶
func (x *PrivateActionTask) GetBundleId() string
func (*PrivateActionTask) GetConnectionInfo ¶
func (x *PrivateActionTask) GetConnectionInfo() *ConnectionInfo
func (*PrivateActionTask) GetExpirationTime ¶
func (x *PrivateActionTask) GetExpirationTime() *timestamppb.Timestamp
func (*PrivateActionTask) GetInputs ¶
func (x *PrivateActionTask) GetInputs() *structpb.Struct
func (*PrivateActionTask) GetOrgId ¶
func (x *PrivateActionTask) GetOrgId() int64
func (*PrivateActionTask) GetSystemInputs ¶
func (x *PrivateActionTask) GetSystemInputs() *SystemInputs
func (*PrivateActionTask) GetTaskId ¶
func (x *PrivateActionTask) GetTaskId() string
func (*PrivateActionTask) ProtoMessage ¶
func (*PrivateActionTask) ProtoMessage()
func (*PrivateActionTask) ProtoReflect ¶
func (x *PrivateActionTask) ProtoReflect() protoreflect.Message
func (*PrivateActionTask) Reset ¶
func (x *PrivateActionTask) Reset()
func (*PrivateActionTask) String ¶
func (x *PrivateActionTask) String() string
type RemoteAction ¶
type RemoteAction struct {
AllowedCommands []string `protobuf:"bytes,1,rep,name=allowed_commands,json=allowedCommands,proto3" json:"allowed_commands,omitempty"`
AllowedPaths []string `protobuf:"bytes,2,rep,name=allowed_paths,json=allowedPaths,proto3" json:"allowed_paths,omitempty"`
SystemServices map[string]*structpb.ListValue `` /* 177-byte string literal not displayed */
// contains filtered or unexported fields
}
func (*RemoteAction) Descriptor
deprecated
func (*RemoteAction) Descriptor() ([]byte, []int)
Deprecated: Use RemoteAction.ProtoReflect.Descriptor instead.
func (*RemoteAction) GetAllowedCommands ¶
func (x *RemoteAction) GetAllowedCommands() []string
func (*RemoteAction) GetAllowedPaths ¶
func (x *RemoteAction) GetAllowedPaths() []string
func (*RemoteAction) GetSystemServices ¶ added in v0.0.27
func (x *RemoteAction) GetSystemServices() map[string]*structpb.ListValue
func (*RemoteAction) ProtoMessage ¶
func (*RemoteAction) ProtoMessage()
func (*RemoteAction) ProtoReflect ¶
func (x *RemoteAction) ProtoReflect() protoreflect.Message
func (*RemoteAction) Reset ¶
func (x *RemoteAction) Reset()
func (*RemoteAction) String ¶
func (x *RemoteAction) String() string
type Server ¶
type SignedEnvelope ¶
type SignedEnvelope struct {
Data []byte `json:"data"`
HashType string `json:"hashType"`
Signatures []Signature `json:"signatures"`
}
SignedEnvelope contains the original backend-signed protobuf bytes. Trust roots are deliberately absent from the signed object. Helpers configured with a local Director root authenticate the request-scoped task key using its Director proof. Helpers without one trust the accompanying bare verification key; without a local policy, they use the signed backend policy unchanged.
type SystemInputs ¶
type SystemInputs struct {
// Types that are valid to be assigned to Input:
//
// *SystemInputs_RemoteAction
Input isSystemInputs_Input `protobuf_oneof:"input"`
// contains filtered or unexported fields
}
func (*SystemInputs) Descriptor
deprecated
func (*SystemInputs) Descriptor() ([]byte, []int)
Deprecated: Use SystemInputs.ProtoReflect.Descriptor instead.
func (*SystemInputs) GetInput ¶
func (x *SystemInputs) GetInput() isSystemInputs_Input
func (*SystemInputs) GetRemoteAction ¶
func (x *SystemInputs) GetRemoteAction() *RemoteAction
func (*SystemInputs) ProtoMessage ¶
func (*SystemInputs) ProtoMessage()
func (*SystemInputs) ProtoReflect ¶
func (x *SystemInputs) ProtoReflect() protoreflect.Message
func (*SystemInputs) Reset ¶
func (x *SystemInputs) Reset()
func (*SystemInputs) String ¶
func (x *SystemInputs) String() string
type SystemInputs_RemoteAction ¶
type SystemInputs_RemoteAction struct {
RemoteAction *RemoteAction `protobuf:"bytes,1,opt,name=remote_action,json=remoteAction,proto3,oneof"`
}