Skip to content

Pin user.home in DocumentAccessPolicyTest so it passes when running as root - #1530

Open
rq-jwhitlock wants to merge 2 commits into
conductor-oss:mainfrom
rq-jwhitlock:jwhitlock/fix-documentaccesspolicytest-as-root
Open

Pin user.home in DocumentAccessPolicyTest so it passes when running as root#1530
rq-jwhitlock wants to merge 2 commits into
conductor-oss:mainfrom
rq-jwhitlock:jwhitlock/fix-documentaccesspolicytest-as-root

Conversation

@rq-jwhitlock

Copy link
Copy Markdown

Make DocumentAccessPolicyTest independent of the running user

Problem

Three DocumentAccessPolicyTest cases fail whenever the build runs as root, which is the norm for container-based CI:

DocumentAccessPolicyTest > shouldAllowFileUriUnderPayloadDir() FAILED
DocumentAccessPolicyTest > shouldAllowPathUnderDefaultPayloadDir() FAILED
DocumentAccessPolicyTest > AllowedDirectoriesTests > shouldFallbackToDefaultPayloadDirWhenParentDirNotSet() FAILED

  org.conductoross.conductor.ai.document.DocumentAccessDeniedException:
  Access denied: path matches blocked prefix '/root/'

All three build their expected directory from user.home:

String payloadDir = System.getProperty("user.home") + "/worker-payload/";

"/root/" is a built-in entry in DEFAULT_BLOCKED_PATH_PREFIXES, and validateAccess runs checkBlockedPaths before checkAllowedDirectories. So when user.home is /root, the default payload directory is itself blocked, and these "safe path" cases fail for a reason unrelated to what they assert.

Reproducing

On an unmodified checkout, in any JDK 21 container image (which run as root with user.home=/root):

docker run --rm -v $PWD:/w -v ~/.gradle:/root/.gradle -w /w eclipse-temurin:21-jdk \
  sh -c './gradlew --offline :conductor-ai:test --tests "*DocumentAccessPolicyTest*"'

Note that -Duser.home=/root alone does not reproduce it — the value has to be the JVM's actual resolved home.

Fix

Pins user.home to a neutral value for the duration of each test and restores the original afterwards, so these tests describe the policy rather than the identity of the user running them. No production code changes.

Verified on main @ 1bad2c88d: green both locally as a normal user (49 tests, 0 failures) and as root inside eclipse-temurin:21-jdk. On unmodified main the same command in the same image fails 3 of 49 — shouldAllowFileUriUnderPayloadDir, shouldAllowPathUnderDefaultPayloadDir, and shouldFallbackToDefaultPayloadDirWhenParentDirNotSet — so the fix is load-bearing and the bug is pre-existing rather than introduced here.

A related runtime concern, deliberately not addressed here

The same ordering affects production, not just tests. Because checkBlockedPaths runs before the allow-list, an application running as root — common in containers — cannot read from its own default ~/worker-payload/ directory, since that resolves under /root/.

This PR does not change that, because the fix is a design decision rather than an obvious correction. Options include exempting the effective allowed directories from the blocklist, checking the allow-list first, or treating /root/ as blocked only when it is not the resolved payload root. Happy to follow up with a separate PR if you have a preference on which of those you'd want.

Three 'safe path' cases build their expected directory from user.home, but
'/root/' is a built-in blocked prefix and checkBlockedPaths runs before the
allow-list. When user.home is /root — which it is whenever the build runs as
root, as it does in a container-based CI — the fallback ~/worker-payload/
directory is itself blocked, and those cases fail for a reason unrelated to what
they assert:

  DocumentAccessDeniedException: Access denied: path matches blocked prefix '/root/'

Pins user.home to a neutral value for each test and restores it afterwards, so
these tests describe the policy rather than the identity of the user running
them.

Reproduce on an unmodified checkout with:

  docker run --rm -v $PWD:/w -v ~/.gradle:/root/.gradle -w /w <jdk21-image> \
    sh -c './gradlew --offline :conductor-ai:test --tests "*DocumentAccessPolicyTest*"'

Note this is only the test-side fix. Because checkBlockedPaths runs before the
allow-list, an application running as root also cannot read from its own default
~/worker-payload/ directory at runtime. That ordering question is left alone
here.
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.

1 participant