Repository navigation
Kerberos credential delegation: allowDelegation() and --allow-delegate (#141) - #182
Merged
Conversation
#141) Let remote commands use the caller's Kerberos credentials to reach a further host (the second hop), like winrs -allowdelegate: - WinRMClient.Builder.allowDelegation() and the CLI's --allow-delegate make KerberosAuthScheme request credential delegation, so the host receives a forwarded TGT. - GSS silently drops the request when the TGT is not forwardable: the scheme now fails with a message pointing to forwardable = true in krb5.conf, instead of the command failing later with access denied. - Rejected without Kerberos, at build() and at CLI parse time. - Kerberos errors raised inside Subject.doAs no longer lose their message (PrivilegedActionException has none of its own), e.g. "Server not found in Kerberos database". Verified live against a domain host: the second hop works with delegation and is denied without, even though the host is not trusted for delegation in AD. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
bertysentry
deleted the
141-kerberos-credential-delegation-allowdelegation-and-cli---allow-delegate-winrs--allowdelegate
branch
September 27, 2026 21:41
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.
Closes #141.
What
Kerberos credential delegation, like
winrs -allowdelegate: the remote command can use the caller's credentials to reach a further host (a UNC path, AD, another server) instead of failing with access denied on the second hop.KerberosAuthSchemesetsrequestCredDeleg(true)iff delegation was requested (it used to hardcodefalse).getCredDelegState()after the first token and fails with a message that says to setforwardable = truein[libdefaults](orkinit -f). The CLI exits with 77.build()fails when Kerberos is not among the schemes (the check sits inLightWinRMService.resolveAuthScheme, where every entry point goes through, next to the Kerberos-over-HTTP rejection). The CLI gives a usage error for--allow-delegatewithout--kerberos. In a(KERBEROS, NTLM)fallback, a connection that falls back to NTLM is not delegated (documented).LightWinRMService.createInstance(endpoint, timeout, ticketCache, authentications, allowDelegation, ...); theretriesoverload forwards to it withfalse.WinRMClientnow callsLightWinRMServicedirectly instead of going throughWinRMExecutorFactory, a pure pass-through kept for the legacy API. This avoids adding a matching factory overload.allowDelegationsits next toauthentications, the setting it qualifies, not at the end: appending a 10th parameter made the telescoping overloads share a 9-parameter prefix, which trips the CPD gate.Also fixed: Kerberos errors lost their message
Subject.doAswraps checked exceptions in aPrivilegedActionExceptionthat has no message of its own. So every GSS failure frominitSecContextreached users as the bare textorg.metricshub.winrm.exceptions.WinRMException. That includes the common Server not found in Kerberos database (connecting by IP), and it happened onmaintoo.authenticate()now rethrows the wrapped exception. Before/after, connecting by IP:Live validation (tc-win2016, SENTRY domain, HTTPS,
SENTRY\dev-admin)dir \\camus...\SYSVOLAccess is denied.(exit 1);kliston the host shows only the HTTP service ticket--allow-delegate, forwardable krb5.conf: samedircifs/…andldap/…tickets it obtained with it--allow-delegate,ls \\camus...\SYSVOL(remote file API)[adsisearcher]AD lookup from the host--allow-delegatewithoutforwardable = truein krb5.conf--allow-delegate+--kerberos-kdc+ a krb5.conf that only saysforwardable = true--allow-delegatewithout--kerberosWinRMLiveTest#kerberosDelegationReachesTheSecondHop(new, gated on-Dwinrm.live.delegation.unc)One finding differs from the issue text: tc-win2016 is not trusted for delegation in AD (its HTTP service ticket has no
ok_as_delegateflag), and delegation still works. The JDK forwards the TGT wheneverrequestCredDeleg(true)is set. Windows clients such aswinrsonly delegate to hosts trusted for delegation. So OK-AS-DELEGATE is not a prerequisite for this client, and the docs say so, with the matching warning to only delegate to hosts you trust. Decision: this permissive behavior is intentional, so delegation works out of the box for library users. Following the Windows policy (requestDelegPolicy, delegate only to trusted hosts) would require unconstrained-delegation trust in AD, which many shops forbid.Tests
KerberosAuthSchemeTest(new): the context requests delegation iff asked, and the check fails when an initialized context does not delegate. It needs no KDC and no krb5.conf: it uses a realm-qualified name, because a host-based one needs a default realm to resolve.WinRMClientBuilderTest.delegationRequiresKerberos,CliArgumentsTest(parse and usage error),WinRmCliTest(help line).mvn clean verify siteon JDK 17 (the CI command) is green.Docs
🤖 Generated with Claude Code