Repository navigation
fix(orchestrator): Scope the execution cache to the secret's owner, so one user's execution is never reused for another - #424
Open
yuechao-qin wants to merge 1 commit into
Conversation
…ion cache key A secret argument is hashed as the reference the pipeline wrote, and Secret's primary key is (user_id, secret_name), so the same reference means a different value for every user. The matching cache entry was adopted before the ownership check ran, attaching one user's execution to another user's run and reusing results computed with the wrong value. The owner is now part of the key whenever an argument references a secret; keys for executions without secrets are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The cache key describes the work but not the authority it runs with, so a non-owner's identical submission matches the owner's entry and is served from it before the ownership check is reached. "Has anyone run this?" is the right question for ordinary work — but once a secret is involved, it has to become "has this user run this?".
The key is built from the component spec, the input hashes, and the arguments — and a secret argument appears there as the reference the pipeline wrote, never as the value it resolves to:
{"tok": {"secret": {"name": "tok"}}}Secret's primary key is(user_id, secret_name), so that reference means a different value for every user, while hashing to the same key for all of them. The lookup then happens before the run's owner is loaded and well before ownership is checked:Fix
Add the run's owner to the hashed struct, but only when an argument references a secret:
The key becomes per owner for secret-consuming tasks, and byte-identical to today for everything else. It carries the owner's ID and never the secret's value: the key is stored on every execution node, indexed, and exported as a trace attribute.
Before / after
User A owns a secret named
tokand has already run the task. Computed keys, for a task whose only argument is that secret:md5=5aa99115…md5=7468f0a0…md5=5aa99115…— the samemd5=9cfd7ea9…md5=8c67cb8d…md5=8c67cb8d…— unchangedWhat each user gets when they submit that task:
tokSYSTEM_ERROR— "User B does not have secret tok" — with no container launchedtokwith a different valueBehaviour change
Alternatives considered
Tests
TestCacheKeySeparatesSecretOwnersintests/test_orchestrator_sql.py, 4 tests:SYSTEM_ERRORwith "does not have secret", and does not point at the owner's container executionSuite: 578 passed. Removing
secret_ownerfrom the key turns the first and third red and leaves the other two green.