Skip to content
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

Merged
merged 21 commits into from
Mar 6, 2023

Conversation

bowenxia
Copy link
Contributor

@bowenxia bowenxia commented Mar 1, 2023

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

@coveralls
Copy link

coveralls commented Mar 1, 2023

Pull Request Test Coverage Report for Build 0186b857-7512-4cad-ad94-15da898f9b53

  • 105 of 496 (21.17%) changed or added relevant lines in 6 files are covered.
  • 54 unchanged lines in 14 files lost coverage.
  • Overall coverage decreased (-0.1%) to 57.084%

Changes Missing Coverage Covered Lines Changed/Added Lines %
common/log/tag/tags.go 0 6 0.0%
common/types/replicator.go 0 18 0.0%
common/types/admin.go 0 27 0.0%
service/frontend/accessControlledHandler.go 101 135 74.81%
service/frontend/accessControlledAdminHandler.go 4 100 4.0%
common/types/shared.go 0 210 0.0%
Files with Coverage Reduction New Missed Lines %
service/history/queue/timer_queue_processor_base.go 1 77.26%
client/history/client.go 2 38.1%
client/history/metricClient.go 2 45.3%
common/task/weightedRoundRobinTaskScheduler.go 2 88.6%
service/history/handler.go 2 47.15%
common/cache/lru.go 3 90.73%
common/task/fifoTaskScheduler.go 3 84.54%
service/history/queue/timer_gate.go 3 95.83%
service/history/task/fetcher.go 3 91.75%
service/frontend/workflowHandler.go 4 59.86%
Totals Coverage Status
Change from base Build 0186b663-3828-4fa7-95a9-b5b2060c7cc3: -0.1%
Covered Lines: 85198
Relevant Lines: 149251

💛 - Coveralls

func isManual(ctx context.Context) bool {
callContext := yarpc.CallFromContext(ctx)
caller := callContext.Caller()
return caller == "cadence-cli" || caller == "cadence-web" || caller == "cadence-ui"
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -5572,6 +5688,50 @@ type SignalWithStartWorkflowExecutionRequest struct {
JitterStartSeconds *int32 `json:"jitterStartSeconds,omitempty"`
}

func (v *SignalWithStartWorkflowExecutionRequest) BodyToString() string {
cloneRequest := SignalWithStartWorkflowExecutionRequest{
Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -58,6 +58,7 @@ type (
WorkflowType *types.WorkflowType
TaskList *types.TaskList
Permission Permission
RequestBody ManualRequestBody
Copy link
Contributor

@demirkayaender demirkayaender Mar 2, 2023

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"

Copy link
Contributor Author

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
Copy link
Contributor

@demirkayaender demirkayaender Mar 2, 2023

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

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

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
Copy link
Contributor

@demirkayaender demirkayaender Mar 2, 2023

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -26,6 +26,10 @@ type AddSearchAttributeRequest struct {
SecurityToken string `json:"securityToken,omitempty"`
}

func (v *AddSearchAttributeRequest) BodyToString() string {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -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{
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// SerializeRequest Serialize an arbitrary request for logging
func SerializeRequest(request interface{}) string {
res, _ := json.Marshal(request)
Copy link
Contributor

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.

@@ -5925,6 +6109,10 @@ type RestartWorkflowExecutionRequest struct {
Identity string `json:"identity,omitempty"`
}

func (v *RestartWorkflowExecutionRequest) SerializeForLogging() (string, error) {
return SerializeRequest(*v)
Copy link
Contributor

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

Copy link
Contributor Author

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) {
Copy link
Contributor

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

Copy link
Contributor Author

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.

@bowenxia bowenxia merged commit c462ec0 into uber:master Mar 6, 2023
@bowenxia bowenxia deleted the CDNC-2946-Add-Audit-Info branch March 6, 2023 20:26
bowenxia added a commit to bowenxia/cadence that referenced this pull request Mar 10, 2023
…equestbody into Attribute for auditing (uber#5124)"

This reverts commit c462ec0.
bowenxia added a commit that referenced this pull request Mar 10, 2023
…equestbody into Attribute for auditing (#5124)" (#5145)

This reverts commit c462ec0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants