-
Notifications
You must be signed in to change notification settings - Fork 800
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create RequestBody struct, implement it using requests, add requestbody into Attribute for auditing #5124
Conversation
This reverts commit fbe72b3.
…o Attribute to use this field for auditing manual accesses
… auto generated code
func isManual(ctx context.Context) bool { | ||
callContext := yarpc.CallFromContext(ctx) | ||
caller := callContext.Caller() | ||
return caller == "cadence-cli" || caller == "cadence-web" || caller == "cadence-ui" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment above that sometime in the future we should also validate the caller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
common/types/shared.go
Outdated
@@ -5572,6 +5688,50 @@ type SignalWithStartWorkflowExecutionRequest struct { | |||
JitterStartSeconds *int32 `json:"jitterStartSeconds,omitempty"` | |||
} | |||
|
|||
func (v *SignalWithStartWorkflowExecutionRequest) BodyToString() string { | |||
cloneRequest := SignalWithStartWorkflowExecutionRequest{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment here why you are manually assigning attributes. You are trying to prevent logging workflow params, i.e. user inputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
RequestID: v.RequestID, | ||
CronSchedule: v.CronSchedule, | ||
} | ||
// deep copy the value within pointers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
common/authorization/authorizer.go
Outdated
@@ -58,6 +58,7 @@ type ( | |||
WorkflowType *types.WorkflowType | |||
TaskList *types.TaskList | |||
Permission Permission | |||
RequestBody ManualRequestBody |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe let's call ManualRequestBody as FilteredRequestBody and add a comment next to it saying "request object except for data inputs"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
RequestID: v.RequestID, | ||
CronSchedule: v.CronSchedule, | ||
} | ||
// deep copy the value within pointers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, explain why you are doing this manually in a sentence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Identity: v.Identity, | ||
RequestID: v.RequestID, | ||
} | ||
// deep copy the value within a pointer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -706,6 +818,11 @@ func (a *AccessControlledWorkflowHandler) StartWorkflowExecution( | |||
Permission: authorization.PermissionWrite, | |||
WorkflowType: request.WorkflowType, | |||
} | |||
|
|||
if isManual(ctx) { | |||
attr.RequestBody = request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all the requests that can contain PII, add a comment here that the authorizer plugin should use the new function you introduced while logging requests to avoid revealing private information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
common/types/admin.go
Outdated
@@ -26,6 +26,10 @@ type AddSearchAttributeRequest struct { | |||
SecurityToken string `json:"securityToken,omitempty"` | |||
} | |||
|
|||
func (v *AddSearchAttributeRequest) BodyToString() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming here is a bit misleading. It's not really stringifying the struct, it's outputting a string for logging. You probably rename this to something like "SerializeForLogging". Same for the util function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
common/types/shared.go
Outdated
@@ -5572,6 +5688,53 @@ type SignalWithStartWorkflowExecutionRequest struct { | |||
JitterStartSeconds *int32 `json:"jitterStartSeconds,omitempty"` | |||
} | |||
|
|||
func (v *SignalWithStartWorkflowExecutionRequest) SerializeForLogging() string { | |||
// making a deep copy of the struct for manually assigning attributes | |||
cloneRequest := SignalWithStartWorkflowExecutionRequest{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a good pattern. These logic is hard to maintain.
Consider using json encoding to serialize the structs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
common/types/shared.go
Outdated
|
||
// SerializeRequest Serialize an arbitrary request for logging | ||
func SerializeRequest(request interface{}) string { | ||
res, _ := json.Marshal(request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not good to ignore the error here.
common/types/shared.go
Outdated
@@ -5925,6 +6109,10 @@ type RestartWorkflowExecutionRequest struct { | |||
Identity string `json:"identity,omitempty"` | |||
} | |||
|
|||
func (v *RestartWorkflowExecutionRequest) SerializeForLogging() (string, error) { | |||
return SerializeRequest(*v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can pass the pointer as the parameter, which will save a deep copy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -251,6 +306,11 @@ func (a *AccessControlledWorkflowAdminHandler) PurgeDLQMessages(ctx context.Cont | |||
APIName: "PurgeDLQMessages", | |||
Permission: authorization.PermissionAdmin, | |||
} | |||
|
|||
if isManual(ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems that it's worth moving isManual
check into isAuthorized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we change to store a pointer instead of a struct in Attributes, as we discussed, we don't need to check if it is manual any more. Because a pointer won't occupy too much space.
What changed?
create FilteredRequestBody struct,
implement it using requests,
add FilteredRequestBody into Attribute
add a log tag for request body
add a email tag for actor emails
Why?
create FilteredRequestBody struct -> as an interface
implement it using requests -> we can store different requests as FilteredRequestBody, and can use a SerializeForLogging method
to transfer a struct into string. So that it is easier to log
add FilteredRequestBody into Attribute -> auditing manual accesses by logging the request body
How did you test it?
unit test
Potential risks
Leaking PII? -> But have already manually filtered fields to be logged.
Release notes
Documentation Changes