Skip to content

Add user custom attributes to thread context #5491

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

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

markdboyd
Copy link

Description

  • Category: Bug fix

  • Why these changes are required?

In opensearch-project/alerting#1829 (comment), I was informed that the the user serialization into the threadcontext does not handle custom attributes, which breaks DLS for alert monitors.

  • What is the old behavior before changes and new behavior after changes?

Without these changes, the serialized user in the thread context does not include custom attribute names. With these changes, the serialized user in the thread context does include custom attribute names.

Related Issues

Related to opensearch-project/alerting#1829

Check List

  • New functionality includes testing.
  • New functionality has been documented.
  • API changes companion pull request created.
  • Commits are signed per the DCO using --signoff.
  • Public documentation issue/PR created.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Testing

I have not done any testing because I was unsure how to implement it or run it

Check List

  • New functionality includes testing
  • New functionality has been documented
  • New Roles/Permissions have a corresponding security dashboards plugin PR
  • API changes companion pull request created
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

@markdboyd I think your IDE may have some conflicts with the spotless rules in this repo. Make sure to run ./gradlew spotlessApply to apply the spotless rules prior to push.

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

@markdboyd FYI for serialization, I was thinking something like this: cwperks#59

i.e. let's base64 encode it to serialize.

I'm thinking that its safe to base64 encode as its done elsewhere (example) and won't clash with the pipe-delimited format.

@markdboyd
Copy link
Author

@cwperks OK, I applied your feedback on base64 encoding and ran ./gradlew spotlessApply. Let me know if I need to do anything else.

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

Thank you @markdboyd1 Can you also make sure to sign the commits? (See DCO check failure) Each repo has a DCO check that requires contributors to sign commits as a Developer Certificate of Origin: https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin

I think we should also add an entry in the CHANGELOG for this PR.

@markdboyd markdboyd force-pushed the add-user-attributes-thread-context branch 4 times, most recently from a614db2 to 6d44822 Compare July 21, 2025 15:17
@markdboyd
Copy link
Author

@cwperks Sorry for the amount of commits here. I had to try a couple times to get the rebasing + commit signing to work correctly. But it should be ready now, including a CHANGELOG entry

Also, if you have any suggestions on how to setup git to do automatic signoff of future commits, I would welcome that

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

Also, if you have any suggestions on how to setup git to do automatic signoff of future commits, I would welcome that

I've gotten in the habit of doing git commit -m "message here" --signoff, but I think other contributors may create an alias like this: https://serverfault.com/a/433639

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

FYI tests are failing bc common-utils changes will need to be merged first.

They are failing on User.parse here: https://github.com/opensearch-project/security/blob/main/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/transport/CreateResourceTransportAction.java#L58

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

Other test error is bc ImmutableMap is not Serializable:

» org.opensearch.OpenSearchException: Instance {} of class class com.google.common.collect.RegularImmutableMap is not serializable
» at org.opensearch.security.support.Base64Helper.serializeObject(Base64Helper.java:84) ~[?:?]
» at org.opensearch.security.privileges.PrivilegesEvaluator.setUserInfoInThreadContext(PrivilegesEvaluator.java:298) ~[?:?]
» at org.opensearch.security.privileges.PrivilegesEvaluator.evaluate(PrivilegesEvaluator.java:397) ~[?:?]

@markdboyd
Copy link
Author

markdboyd commented Jul 21, 2025

@cwperks

OK. I'll fix the CHANGELOG.

Any suggestions re: Serializable and ImmutableMap? Base64Helper.serializeObject wouldn't work on user.getCustomAttributesMap() without Serializable. I took the idea from this code.

Also the common-utils PR is up and ready for review as well if that needs to go first: opensearch-project/common-utils#827

@markdboyd markdboyd force-pushed the add-user-attributes-thread-context branch from c07b657 to d4887ff Compare July 21, 2025 16:00
}

joiner.add(Base64Helper.serializeObject((Serializable) user.getCustomAttributesMap()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can lead to performance issues depending on size of custom attributes - should this be made selective using a role configuration or authz configuration?

Copy link
Author

Choose a reason for hiding this comment

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

Sure. Can you provide any guidance as to how that would work? I'm a novice Java developer with minimal overall knowledge of the OpenSearch codebase

Copy link
Member

Choose a reason for hiding this comment

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

@shikharj05 would a feature flag be useful here? IMO all attributes should be serialized bc user role definitions can change at any time.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@cwperks do you think it's possible to look at role definition, identify the dynamic parameter substitution required and just serilalize this specific parameter?

Copy link
Member

@cwperks cwperks Jul 21, 2025

Choose a reason for hiding this comment

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

I think the feature flag approach would be simpler. We could also add another setting in the future for additional controls for an allowlist of which attributes to specifically include when serializing instead of serializing all.

@markdboyd markdboyd force-pushed the add-user-attributes-thread-context branch from 125ea6b to 2ec314c Compare July 21, 2025 16:38
@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

@markdboyd for an example of a feature flag see: https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java#L1365-L1373

Essentially, we'd add a setting that an admin can place in opensearch.yml to enable/disable serialization of user attributes.

i.e.

plugins.security.user_attribute_serialization.enabled: true

@cwperks
Copy link
Member

cwperks commented Jul 21, 2025

To resolve the serialization issue with ImmutableMap, we need to add that as a Safe class here: https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/support/SafeSerializationUtils.java#L41-L54

@markdboyd markdboyd force-pushed the add-user-attributes-thread-context branch from 4bd2d5c to c90eae9 Compare July 21, 2025 19:10
Copy link

codecov bot commented Jul 22, 2025

Codecov Report

Attention: Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.

Project coverage is 72.75%. Comparing base (3121d88) to head (c90eae9).
Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
...earch/security/privileges/PrivilegesEvaluator.java 50.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #5491      +/-   ##
==========================================
+ Coverage   72.72%   72.75%   +0.02%     
==========================================
  Files         397      397              
  Lines       24589    24597       +8     
  Branches     3740     3742       +2     
==========================================
+ Hits        17882    17895      +13     
+ Misses       4881     4872       -9     
- Partials     1826     1830       +4     
Files with missing lines Coverage Δ
.../opensearch/security/OpenSearchSecurityPlugin.java 85.01% <100.00%> (+0.03%) ⬆️
...g/opensearch/security/support/ConfigConstants.java 95.23% <ø> (ø)
...earch/security/support/SafeSerializationUtils.java 86.66% <ø> (ø)
...earch/security/privileges/PrivilegesEvaluator.java 74.57% <50.00%> (-0.29%) ⬇️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@DarshitChanpura DarshitChanpura left a comment

Choose a reason for hiding this comment

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

@markdboyd Thank you for adding this fix! I've left some comments and couple of clarification questions.

}

if (this.isUserAttributeSerializationEnabled()) {
joiner.add(Base64Helper.serializeObject((Serializable) user.getCustomAttributesMap()));
Copy link
Member

Choose a reason for hiding this comment

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

Base64 encoding might still raise performance concerns if the user has thousands of attributes. Not a blocker for this PR, but we should test that scenario and add a fix in a follow-up PR.

@cwperks
Copy link
Member

cwperks commented Jul 24, 2025

Note: integ tests for the sample plugin will fail until opensearch-project/common-utils#827 is merged.

markdboyd added 21 commits July 24, 2025 15:20
attempt reading injected attributes in RolesInjector

add custom attributes to user information in thread context

add more logging to injectUserAndRoles

add debugging statements

update serialization to include only custom attribute name

revert changes to RolesInjector

revert changes to UserInjector

revert changes to SecurityFilter

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>

update setUserInfoInThreadContext to base64 encode the serialized map of user custom attributes

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>

add null tenant to user context when none is available

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>

Immutable user object (opensearch-project#5212)

Signed-off-by: Nils Bandener <nils.bandener@eliatra.com>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>

apply spotless formatting

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…en requested tenant is empty

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…Utils

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…control whether user attributes are serialized

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…k if user attribute serialization is enabled before adding serialized user attributes to the thread context

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…t consistent

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…text

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
…te file

Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
@markdboyd markdboyd force-pushed the add-user-attributes-thread-context branch from 8971760 to 4f0ee5b Compare July 24, 2025 19:20
Copy link
Member

@DarshitChanpura DarshitChanpura left a comment

Choose a reason for hiding this comment

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

Thanks @markdboyd ! LGTM. lets keep this feature behind feature flag for now.

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