Skip to content

Feature/idrs switch - #131

Merged
theokaufman merged 17 commits into
developmentfrom
feature/idrs_switch
Oct 5, 2026
Merged

theokaufman merged 17 commits into
developmentfrom
feature/idrs_switch

Conversation

@theokaufman

Copy link
Copy Markdown
Collaborator

WIP

Adds in:

  • IDRS client to wrap API calls
  • New logic in execution flow to run fuzzy matching in certain circumstances
  • Executor IDRS orchestration method

Still to come in this or subsequent PRs:

  • Send logic to return matches to the app
  • stu-assess-ledger and unsent artifacts

@amazon-inspector-ohio

Copy link
Copy Markdown

⏳ I'm reviewing this pull request for security vulnerabilities and code quality issues. I'll provide an update when I'm done

@snyk-io-us

snyk-io-us Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@amazon-inspector-ohio

Copy link
Copy Markdown

✅ I finished the code review, and didn't find any security or code quality issues.

@theokaufman

Copy link
Copy Markdown
Collaborator Author

@edandylytics tagged you as reviewer for visibility mainly, but lmk if you have any thoughts!

@edandylytics edandylytics left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I haven't tried running locally yet, but thinking tomorrow I'll combine this branch and the one I've got in #128 and see how it shakes out.

Comment thread executor/executor/executor.py Outdated
self.error_url = job["appUrls"]["error"]
self.matches_url = job["appUrls"]["unmatchedIds"]
self.summary_url = job["appUrls"]["summary"]
self.idrs_url = job["appUrls"]["identityService"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note that the app will only send this URL for 'fuzzy' and 'id_based_fuzzy_background' modes -- i.e. when there's an IDRS connection configured and it's ready to be used.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Also fixed this up thank you for noting

Comment thread executor/executor/executor.py Outdated
Comment on lines +133 to +136
if self.id_matching_mode in ['fuzzy', 'id_based_fuzzy_background']:
if self.em_runtime and self.em_runtime <= config.MAX_EM_RUNTIME_SECONDS:
self.match_candidates()
self.get_id_matches(artifact.CANDIDATES.path)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why move the fuzzy matching steps to before the id-based processing has finished? Interleaving the processing modes makes me nervous.

I'm not saying it doesn't work, but I'd want to make very sure:

  • a new fuzzy matching step failing doesn't break existing id-based matching
  • the app gets a coherent set of updates from the Executor (e.g. only one earthmover_deps event)
  • state management between the two processing modes is maintainable long term, since we'll need id-based and fuzzy matching for the foreseeable future (until IDRS becomes a hard requirement to use Runway).
    • For example, it looks like match_candidates moves the output directory. Will that interfere with where Lightbeam expects the files from the id-based mode to be?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think we should chat about this a bit more tomorrow to make sure I'm understanding. I think some of this might come down to the naming in the executor at the moment.

As written in this PR, the execution flow is:

  • id_based -> Run our normal process (encapsulated in orchestrate_earthmover)
  • fuzzy -> Run our new process (right now spread out over a few methods but the piece that implements earthmover is match_candidates)

Right now, the processes will be separate in the code as written -- The edge case is id_based_fuzzy_background, which we might just want to make another condition in the finally block.

My thought here was that we want to make the "switch" explicit in the execution flow -- run one process OR the other, and afterwards proceed with the rest of the run as normal. I agree with all your concerns, I certainly want to make sure these processes are independent but can coexist within the execution flow. Let me know if I'm misunderstanding anything here!

Comment thread executor/executor/executor.py Outdated
self.idrs_url = job["appUrls"]["identityService"]
self.output_files_url = job["appUrls"]["outputFiles"]

self.id_matching_mode = job.get("idMatchingMode", True)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

id_based as the default?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed up thanks for the note

@theokaufman

Copy link
Copy Markdown
Collaborator Author

I haven't tried running locally yet, but thinking tomorrow I'll combine this branch and the one I've got in #128 and see how it shakes out.

@edandylytics Sounds great please ping me and let me know! I anticipate a decent amount of stuff will need to be wired up, but my feeling is the structure is there to hit the IDRS and handle matches

Comment thread executor/executor/idrs_client.py Outdated

@jayckaiser jayckaiser left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I've left some questions, but no major concerns. Andy's callout about chunking the posting to IDRS will be an important improvement to make!

Comment thread executor/executor/executor.py Outdated
Comment thread executor/executor/executor.py
Comment thread executor/executor/executor.py Outdated
Comment thread executor/executor/idrs_client.py Outdated
Comment thread executor/executor/idrs_client.py Outdated
Comment thread executor/executor/idrs_client.py Outdated
Comment thread executor/executor/idrs_client.py Outdated
@theokaufman
theokaufman marked this pull request as ready for review September 29, 2026 20:04
@theokaufman

Copy link
Copy Markdown
Collaborator Author

@jayckaiser Ready for another look when you get a chance!

# The URL for the IDRS
self.identity_url = identity_url

def validate_candidates(self, candidates: list[dict]) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The IDRS will reject requests with duplicate correlation IDs, and the candidate package doesn't do any deduping. Somewhere, we'll need to weed out duplicates (though I'm not sure this is the place since it'd be mutating the candidates rather than validating them per se...)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Might be good to grab some time tomorrow morning to talk about this validation/mutation distinction (is this a bigger chunk of work than this PR, I wonder?)

@edandylytics edandylytics Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sounds good. FWIW, the validation/mutation distinction was sort of offhand.

But one more thing this function (or something) should do: the candidates package adds a record_count key that'll need to be stripped. The IDRS rejects unexpected keys in order to avoid situations where a caller sends data thinking that it is included in the query and it's not actually factored in.

@jayckaiser jayckaiser left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@theokaufman I've highlighted a couple more fixes that I missed during our one-on-one this week. Let me know if you have any questions!

Comment thread executor/executor/executor.py
Comment thread executor/executor/idrs_client.py

resp = self.conn.post(
url=idrs_conn_info['url'],
headers={"Authorization": f"Bearer {idrs_conn_info['token']}"},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do we need to worry about auth-expiry? Will we ever need to refresh this token mid-run?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think so. We are getting the token in the payload of get_candidates, so it will always be fresh. Any given run that hits the IDRS will use a new token, so I don't think we will need to refresh

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The app ensures there's at least 10 min left before the token expires before handing it to the Executor. But if you do get a 401, you can always request a token again from the app. If the 401 was due to token expiration, you'll get a new one.

@theokaufman

Copy link
Copy Markdown
Collaborator Author

@edandylytics heads up that this is good to go!

@theokaufman
theokaufman merged commit d5ca7f8 into development Oct 5, 2026
4 checks passed
@theokaufman
theokaufman deleted the feature/idrs_switch branch October 5, 2026 20:25
@edandylytics edandylytics mentioned this pull request Oct 6, 2026
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.

3 participants